Errors
The error response body, what each HTTP status means, how to read validation errors, and every error code the API returns.
Last updated
The API uses standard HTTP status codes, and every error response has the same JSON body.
The error body
{
"success": false,
"error": "VALIDATION_ERROR",
"message": "Request validation failed. Check the errors for details.",
"details": {
"errors": [
{ "field": "lead.first_name", "message": "Field required", "type": "missing" }
]
},
"request_id": "3b0f6c1e-8a2d-4e7b-9c5a-2d1f0e9b8a7c"
}| Field | Meaning |
|---|---|
success | Always false on an error. |
error | A stable code for the kind of error. Branch on this. |
message | A human-readable explanation. Its wording can change, so don't parse it. |
details | Extra context for some errors, such as the failing fields of a validation error. Not always present. |
request_id | The request's ID, also sent as the X-Request-ID header. Quote it when you contact support. |
Status codes
| Status | Meaning | Retry? |
|---|---|---|
400 | The request is invalid. | No. Fix the request first. |
401 | The API key is missing, invalid, revoked or expired. | No. |
403 | The key lacks the required scope, or the organization is deactivated. | No. |
404 | The endpoint, or the resource in your organization, doesn't exist. | No. |
405 | The endpoint doesn't accept this HTTP method. | No. |
409 | A conflict: the resource already exists, or it changed since you read it. | For IDEMPOTENCY_IN_PROGRESS, after Retry-After. For SEQUENCE_MODIFIED, after reading the campaign again. |
413 | The request body is larger than 1 MB. | No. |
429 | You've hit a rate limit. | Yes, after Retry-After. See Rate limits. |
500 | Something failed on our side. | Yes, with backoff. Send an Idempotency-Key on create requests so a retry is safe. |
503 | A dependency timed out, or the key couldn't be checked. | Yes, with backoff. |
Validation errors
A request that doesn't match the endpoint's schema answers 400 VALIDATION_ERROR, and details.errors lists every problem. Each entry has:
field: the path to the field, with nested fields joined by dots, such aslead.first_name. It'srequestwhen the problem isn't tied to one field.message: what's wrong with the value.type: a short machine-readable reason, such asmissing.
Common causes are a missing required field, a value of the wrong type, a string longer than 2,000 characters, and a number out of range, such as a limit above the endpoint's maximum.
IDs that don't exist
- A path ID that isn't a valid UUID answers
404 NOT_FOUND. - An ID in a request body or query string that isn't a valid UUID, such as
campaign_idorstage_id, answers400 VALIDATION_ERROR. - A path ID for a resource that isn't in your organization answers that resource's not-found code, such as
404 CAMPAIGN_NOT_FOUND. - An ID in a request body that isn't in your organization answers
400, such as400 INVALID_STAGE. This way a response never confirms an ID that belongs to another organization.
Error codes
Every code the API can return. Each endpoint's reference page lists the codes that endpoint can return.
| Code | Status | Meaning |
|---|---|---|
| Request | ||
VALIDATION_ERROR | 400 | The request didn't match the endpoint's schema: a missing or malformed field, a bad query parameter, or a value out of range. |
BAD_REQUEST | 400 | The request was malformed in a way no more specific code covers. |
NO_UPDATES | 400 | The update request contained no fields to change. |
NO_SEQUENCE | 400 | The campaign has no sequence, so there's no step to update. |
SEQUENCE_VALIDATION_FAILED | 400 | The sequence breaks a structural rule, such as an unknown step type or a |
INVALID_WEBHOOK_URL | 400 | The webhook URL must use |
INVALID_DATE_FILTER | 400 |
|
INVALID_VARIATION | 400 |
|
INVALID_LEAD | 400 | The |
INVALID_STAGE | 400 | The |
INVALID_OWNER | 400 | The |
INVALID_ACCOUNT | 400 | A sender account ID in the request isn't a connected account in your organization. Answered when a connected assistant assigns sender accounts to a campaign. This is a |
INVALID_WINDOW | 400 | The daily-stats window is unparseable, has from after to, or spans more than 400 days. |
INVALID_GROUP_BY | 400 | group_by must be none, sender or variation. |
PAYLOAD_TOO_LARGE | 413 | The request body is larger than 1 MB. |
| Authentication | ||
UNAUTHORIZED | 401 | The |
API_KEY_EXPIRED | 401 | The API key is past its expiry date. Create a new key in the Victoria AI app. |
FORBIDDEN | 403 | This API key isn't allowed to make the request. |
INSUFFICIENT_SCOPE | 403 | The API key doesn't have the scope this endpoint requires, such as |
ORGANIZATION_DEACTIVATED | 403 | The organization that owns this API key has been deactivated. |
NO_DEFAULT_ORGANIZATION | 403 | You belong to more than one organization and none is set as the default for connected assistants. Pick one on the consent screen, in Settings → Connect your AI, or with the switch_organization tool. |
NO_ACTIVE_SUBSCRIPTION | 403 | The organization doesn't have an active subscription. |
TRIAL_LEAD_CAP_REACHED | 403 | The organization is on a free trial and has used up its lead quota, so the lead wasn't created. |
| Not found | ||
NOT_FOUND | 404 | No endpoint matches the path. A resource ID in the path that isn't a valid UUID also answers |
CAMPAIGN_NOT_FOUND | 404 | No campaign with this ID exists in your organization. |
LEAD_NOT_FOUND | 404 | No lead with this ID exists in your organization. |
LEAD_NOT_IN_CAMPAIGN | 404 | The lead isn't enrolled in the campaign given by |
DEAL_NOT_FOUND | 404 | No deal with this ID exists in your organization. |
PIPELINE_NOT_FOUND | 404 | No pipeline with this ID exists in your organization. |
WEBHOOK_NOT_FOUND | 404 | No webhook with this ID exists on the campaign. |
STEP_NOT_FOUND | 404 | No step with this ID exists in the campaign's sequence, including inside conditional branches. |
CONVERSATION_NOT_FOUND | 404 | No conversation with this ID exists in your organization. |
AI_FIELD_NOT_FOUND | 404 | No AI field with this ID exists on the campaign. |
METHOD_NOT_ALLOWED | 405 | The path exists but doesn't accept this HTTP method. |
| Conflict | ||
LEAD_ALREADY_EXISTS | 409 | A lead with the same email or LinkedIn URL already exists in your organization. From Create a lead, this means the request named no |
LEAD_ALREADY_IN_CAMPAIGN | 409 | The lead already exists in your organization and is already enrolled in the campaign given by |
LEAD_SUPPRESSED | 409 | The contact is on your organization's do-not-contact list, so the lead wasn't created, enrolled or updated. |
DUPLICATE_WEBHOOK | 409 | An active webhook for this URL already exists on the campaign. |
WEBHOOK_SLOT_TAKEN | 409 | A campaign has one response webhook, and a different URL already holds this campaign's. |
CAMPAIGN_NOT_READY | 409 | The campaign can't be activated: at least one readiness check is blocking, such as a step missing content, a variable with no personalization field, an unassigned or unauthenticated sender, or no enrolled leads. |
CAMPAIGN_ACTIVATION_WARNINGS | 409 | The campaign's readiness checks passed with warnings only. |
SEQUENCE_MODIFIED | 409 | The sequence changed after it was read. Retrieve the campaign again and retry. |
STEP_ID_AMBIGUOUS | 409 | More than one step in the sequence has this ID, so the update can't tell which one to change. |
VARIATION_B_MISSING | 409 | The campaign's sequence has no |
AB_TESTING_DISABLED | 409 | A/B testing is off for this campaign, so there's no test to promote a winner from. Turn it on with Turn A/B testing on or off first. |
ACCOUNT_NOT_CONNECTED | 409 | A sender account being assigned to the campaign has disconnected. Reconnect it in the Victoria AI app or with a reconnect link first. |
ACCOUNT_IN_USE | 409 | A sender account sends for one active campaign at a time, and one being assigned is already used by another active campaign. |
ACCOUNT_LIMIT_REACHED | 409 | Connecting a new sender account would exceed the organization's seats for that platform. |
AI_FIELD_EXISTS | 409 | An active AI field with this name already exists on the campaign. Names are compared without regard to case. |
IDEMPOTENCY_KEY_REUSED | 409 | This |
IDEMPOTENCY_IN_PROGRESS | 409 | The first request with this |
| Rate limits | ||
RATE_LIMITED | 429 | Too many requests for this API key: more than 100 a minute to one endpoint, or 600 a minute in total. Retry after the number of seconds in the |
DAILY_SPEND_LIMIT | 429 | Lead-database spend from this connection (an AI connector or API key) would pass the organization's rolling 24-hour limit (5,000 credits by default). |
| Server | ||
INTERNAL_ERROR | 500 | Something failed on our side. The response never includes internal details; quote its |
ORG_HAS_NO_MEMBERS | 500 | The organization has no members, so the campaign can't be created. Contact support. |
UPSTREAM_TIMEOUT | 503 | A service the API depends on timed out. The request is safe to retry. |
AUTH_UNAVAILABLE | 503 | The API key couldn't be checked because the authentication service was unavailable. The request is safe to retry. |
HTTP_ERROR | 500 | An HTTP error that no more specific code covers. |