API & Developer Guide
Overview
The FuriosaCRM API lets you programmatically access and manage your CRM data. You can create contacts, manage audiences, trigger campaigns, and retrieve analytics — all through a RESTful JSON API. This is ideal for integrating FuriosaCRM with your own applications, building custom workflows, or automating repetitive tasks.
The API is available to users with the Client Admin or Admin role on the Pro plan and above. API access is controlled through API keys that you generate from the admin dashboard. Each key can be given a descriptive name and can be revoked independently, giving you full control over who and what can access your data programmatically.
All API endpoints use HTTPS and return JSON responses. The base URL for all API requests is https://app.furiosacrm.com/api/v1. Requests must include a valid API key in the Authorization header. The API follows RESTful conventions: GET for reading, POST for creating, PUT for updating, and DELETE for removing resources.
Generating API Keys
To generate an API key, navigate to Settings → API Keys in the admin sidebar. Click Create New Key to open the key creation form. Give the key a descriptive name (e.g., "Website Integration" or "Mobile App Backend") so you can easily identify its purpose later.
When you create a key, you can optionally restrict its permissions. Available permission scopes include: contacts:read, contacts:write, audiences:read, audiences:write, campaigns:read, campaigns:write, pages:read, and analytics:read. If no specific permissions are selected, the key has full access to all endpoints.
The full API key is shown only once, immediately after creation. Copy it and store it securely. After you close the creation dialog, the key is masked and cannot be retrieved in full. If you lose a key, revoke it and create a new one. API keys are encrypted with AES-256-CBC before being stored in the database.
Authentication
All API requests must include your API key in the Authorization header using the Bearer token scheme. The Content-Type header should be set to application/json for requests that include a body (POST, PUT).
Authorization: Bearer fcrm_pk_your_api_key_here
Content-Type: application/json
Accept: application/json
If the API key is missing, invalid, or revoked, the API returns a 401 Unauthorized response. If the key does not have sufficient permissions for the requested endpoint, you receive a 403 Forbidden response with a message indicating which permission is required.
Available Endpoints
The API is organized around the core resources in FuriosaCRM. Here is an overview of the main endpoint groups:
- Contacts (
/api/v1/contacts) — Create, read, update, and delete individual contacts. Search and filter contacts across audiences. - Audiences (
/api/v1/audiences) — List audiences, get audience details and stats, create new audiences, and manage audience groups. - Campaigns (
/api/v1/campaigns) — List campaigns, get campaign details and metrics, and trigger campaign sends. - Pages (
/api/v1/pages) — List pages, get page details including submission counts and settings. - Analytics (
/api/v1/analytics) — Retrieve page submission analytics, campaign performance metrics, and audience growth data.
All list endpoints support pagination via page and per_page query parameters (default: 25 per page, maximum: 100). Responses include total, page, per_page, and total_pages metadata for navigation.
Working with Contacts
The Contacts API is the most commonly used endpoint group. Here are the key operations:
List Contacts
GET /api/v1/contacts?audience_id=5&page=1&per_page=50
Returns a paginated list of contacts in the specified audience. You can filter by email, phone, name, or group_id using query parameters.
Create a Contact
POST /api/v1/contacts
{
"audience_id": 5,
"email": "jane@example.com",
"phone": "+447911123456",
"first_name": "Jane",
"last_name": "Smith",
"groups": [1, 3]
}
Creates a new contact in the specified audience. The email or phone field is required (at least one). The groups array is optional and lets you assign the contact to one or more audience groups at creation time. If a contact with the same email already exists in the audience, the API returns a 409 Conflict response.
Update a Contact
PUT /api/v1/contacts/{contact_id}
{
"first_name": "Jane",
"last_name": "Doe",
"phone": "+447911999888"
}
Updates the specified contact's fields. Only include the fields you want to change. Fields not included in the request body are left unchanged.
Delete a Contact
DELETE /api/v1/contacts/{contact_id}
Permanently removes the contact from the audience. This action cannot be undone. The contact's data is deleted from the database and the audience's email/phone counts are decremented accordingly.
Webhooks
Webhooks let FuriosaCRM notify your application when events happen in real time, rather than requiring you to poll the API. When a configured event occurs, FuriosaCRM sends an HTTP POST request to your specified URL with a JSON payload describing the event.
To set up webhooks, go to Settings → Webhooks and click Add Webhook. Provide your endpoint URL, select which events to subscribe to, and optionally set a secret key for payload verification. Available event types include:
contact.created— A new contact is added to any audience (via form, import, or API).contact.updated— An existing contact's data is modified.contact.deleted— A contact is removed from an audience.campaign.sent— A campaign completes sending.campaign.bounced— An email campaign receives bounce notifications.page.submission— A new form submission is received on a page.
Each webhook payload includes the event type, a timestamp, and the relevant resource data. The payload is signed with your webhook secret using HMAC-SHA256, sent in the X-Furiosa-Signature header. Verify this signature in your application to ensure the request genuinely came from FuriosaCRM.
If your endpoint returns a non-2xx status code or times out (after 10 seconds), FuriosaCRM retries the delivery with exponential backoff: after 1 minute, 5 minutes, 30 minutes, and 2 hours. After 4 failed retries, the delivery is marked as failed and logged in the webhook delivery log, which you can review from the Settings page.
https://mysite.com/webhooks/furiosa
https://api.internal.com/sync
Rate Limits
The API is rate-limited to 60 requests per minute per API key. This limit applies across all endpoints. When you exceed the limit, the API returns a 429 Too Many Requests response with the following headers:
X-RateLimit-Limit: 60— The maximum requests per minute.X-RateLimit-Remaining: 0— Remaining requests in the current window.Retry-After: 23— Seconds until the rate limit resets.
For bulk operations (importing large numbers of contacts), use the batch endpoint POST /api/v1/contacts/batch which accepts up to 100 contacts per request and counts as a single API call. This is much more efficient than individual create requests.
If you need higher rate limits for a legitimate use case, contact our support team. Enterprise plans include customizable rate limits based on your integration requirements.
Code Examples
Here are example API requests in common programming languages to help you get started.
cURL
curl -X POST https://app.furiosacrm.com/api/v1/contacts \
-H "Authorization: Bearer fcrm_pk_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"audience_id": 5,
"email": "jane@example.com",
"first_name": "Jane"
}'
PHP
$ch = curl_init('https://app.furiosacrm.com/api/v1/contacts');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer fcrm_pk_your_key_here',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'audience_id' => 5,
'email' => 'jane@example.com',
'first_name' => 'Jane',
]),
]);
$response = curl_exec($ch);
$data = json_decode($response, true);
curl_close($ch);
Python
import requests
response = requests.post(
'https://app.furiosacrm.com/api/v1/contacts',
headers={
'Authorization': 'Bearer fcrm_pk_your_key_here',
'Content-Type': 'application/json',
},
json={
'audience_id': 5,
'email': 'jane@example.com',
'first_name': 'Jane',
}
)
data = response.json()
print(data)
JavaScript (Node.js)
const response = await fetch(
'https://app.furiosacrm.com/api/v1/contacts',
{
method: 'POST',
headers: {
'Authorization': 'Bearer fcrm_pk_your_key_here',
'Content-Type': 'application/json',
},
body: JSON.stringify({
audience_id: 5,
email: 'jane@example.com',
first_name: 'Jane',
}),
}
);
const data = await response.json();
console.log(data);
Error Handling
The API uses standard HTTP status codes and returns error details in a consistent JSON format:
{
"error": true,
"status": 422,
"message": "Validation failed",
"errors": {
"email": "The email field is required."
}
}
Common error codes and their meanings:
400 Bad Request— The request body is malformed or missing required fields.401 Unauthorized— No API key provided, or the key is invalid/revoked.403 Forbidden— The API key does not have permission for this endpoint.404 Not Found— The requested resource does not exist.409 Conflict— A duplicate resource exists (e.g., contact with same email).422 Unprocessable Entity— Validation failed. Check theerrorsobject for details.429 Too Many Requests— Rate limit exceeded. Wait and retry.500 Internal Server Error— An unexpected error on our side. Contact support if this persists.
When building integrations, always check the HTTP status code before parsing the response body. Implement retry logic with exponential backoff for 429 and 5xx errors. For 4xx errors (except 429), retrying the same request will produce the same error — fix the request before retrying.
message and errors fields provide specific information that helps diagnose issues quickly. Include the full response body in any support tickets.