Skip to main content
Every error the Salesfinity API returns is JSON. There is no HTML error page, no plain-text fallback, and no endpoint that answers a failure differently — a client can parse a failure the same way on every route and every status code. The one exception is a request that never reaches the API, for example when the network edge in front of it cannot connect. That answer comes from the edge and may not be JSON. Treat a 5xx whose body does not parse as JSON as retryable, the same as any other 5xx.

The error envelope

Branch on error or statusCode, never on message. Message text is written for humans and may be reworded; error and statusCode are contractual.

Request IDs

Every response, successful or not, carries an X-Request-Id header, and every error body repeats it as request_id. To follow a request through your own logs and ours, send your own X-Request-Id: 1 to 128 characters of letters, digits, ., _, : and -. Salesfinity uses it as the request’s ID. If you send none, or one that does not fit that format, Salesfinity generates a UUID.

The order checks run in

A request is checked in this order, and the first check that fails decides the response. When a request could fail in more than one way, this tells you which error you will see.
  1. The body is read. A body that is not valid JSON gets 400; one over the size limit gets 413.
  2. The route is matched. A method and path that match no route get 404 Cannot <METHOD> <path>.
  3. The API key is checked. A missing or unknown key gets 403.
  4. The rate limit is counted. Over the limit gets 429. Every request that got this far counts, whatever happens next.
  5. The Idempotency-Key is claimed, on Sequencer writes that send one. A reused or busy key gets 409.
  6. Parameters and body are validated. Anything that does not match the schema gets 400 with one message entry per problem. GET /v1/call-log, GET /v1/scored-calls, GET /v1/contact-lists/csv and GET /v1/contact-lists/csv/{id} are the exception for unknown query parameters: they drop one rather than refuse it.
  7. The operation runs. It can still answer 400, 402, 403, 404, 409, 422 or a 5xx, as its reference page says.

Status codes

400 Bad Request

The request is malformed. Most often a parameter or body field failed validation, and message is an array with one entry per invalid field. A field the operation does not define is a validation failure too, except in the query of the four list endpoints named in step 6 above, which ignore what they do not recognize.
message is a single string when the request fails before validation or in the operation itself: a body that is not valid JSON, an ID in the path that is not a valid ID, or a rule such as a user_id that is not on the team. Not every route checks the ID first; the ones that do not are listed under 500.
Recover by reading message and correcting what it names. Check the request against the schema shown on the operation’s reference page. Retrying an identical request will fail identically.

402 Payment Required

The team has run out of enrichment credits. Only the requests that start an enrichment return this; reading a result or the balance never does.
These are the team’s enrichment credits, which the API and the MCP server spend. They are separate from the SmartEnrich credits members spend in the dialer, and they cannot be bought in the dashboard. Recover by asking Salesfinity to add team enrichment credits, then retrying. Call Get enrichment credit balance before a bulk run to avoid hitting this mid-batch.

403 Forbidden

The x-api-key header is missing, malformed, revoked, or belongs to a different team.
Salesfinity returns 403 for authentication failures, not 401. A client written around the usual “re-authenticate on 401” convention will never trigger its auth-recovery path against this API. Handle 403 explicitly.
Recover by checking that the x-api-key header is present and spelled correctly, that the key has not been revoked in Settings → Connections & API, and that it belongs to the team whose data you are requesting. A 403 with any message other than Forbidden resource is not about the key. It means the team member you are acting as, the user_id, may not do this. For example, a Sequencer write acting as an inactive member gets The acting user is not an active member of this team, and editing someone else’s note gets Only the author can edit this note. Act as a member who is allowed to. A Sequencer write acting as a member who has no active plan or seat is refused before anything else is checked, and its error is NO_ACTIVE_PLAN instead of Forbidden:
Assign that member a seat, or act as one who has one.

404 Not Found

Either the route does not exist, or the resource does exist but belongs to another team.
A message of the form Cannot <METHOD> <path> means the route itself is wrong — check the method and path against the reference. Any other message means the route was correct but the record was not found for this team. Recover by verifying the path, the HTTP method, and any ID in the URL. Because API keys are team-scoped, the API returns 404 rather than 403 for records owned by another team; it does not confirm that they exist.

409 Conflict

The request conflicts with an earlier request or with the current state of the record. The most common cause is an Idempotency-Key that was already used. See Retrying writes safely.
Recover by working out which case you hit:
  • The key was already used for a different request, with another body or another path. Send a new key. Reusing a key for a different request is a bug in the client.
  • The first request with this key is still running. The message is A request with this Idempotency-Key is still in progress. Wait a moment, then retry with the same key. Once the first request has finished, the retry returns its response.
  • The record’s state rules the action out, for example completing a manual_email task whose send is already in flight, or reordering steps while people are mid-cadence. The operation’s reference page says when this applies. An identical retry fails the same way until the state changes.

413 Payload Too Large

The body is over the size limit: 10 MB on /v1/contact-lists and /v2/sequencer, 1 MB on every other route. The request was not processed.
Recover by splitting the request. For enrolling many people, an enrollment run takes up to 5,000 contacts in one request.

422 Unprocessable Entity

The Sequencer understood the request, but its rules refuse it. Examples: enabling a sequence that has no steps or no mailbox able to send, or adding contacts to a sequence that is archived, has no steps, or has enrollment paused. Contacts refused one by one, for example because they are suppressed or a rule blocks them, are not a 422: the bulk operations report them in their response.
Recover by fixing what message names, then sending the request again. An identical retry fails identically until then.

429 Too Many Requests

The team has used up a rate limit for the current minute. Limits are per team, so every API key on the team draws on the same budget. See Rate limits for the limits and the routes each one covers.
Recover by waiting the number of seconds in the Retry-After response header, never more than 60, then retrying. The refused request did nothing, so retrying it is safe even for a write. To avoid the 429 in the first place, pace bulk jobs with the X-RateLimit-Remaining and X-RateLimit-Reset headers, which come on every response to an authenticated request. Because the budget is shared, a burst from one integration can throttle another integration on the same team.

500 Internal Server Error

Something failed on the Salesfinity side.
Recover by retrying with exponential backoff. If it persists, email [email protected] with the request_id, the request path and the timestamp.

502 Bad Gateway and 504 Gateway Timeout

The Sequencer and enrichment endpoints pass requests on to a Salesfinity service behind the API. 502 means that service could not be reached. 504 means the Sequencer did not answer within 55 seconds.
Recover by retrying with exponential backoff. After a 504 on a write, the write may still have finished, so confirm with a GET before retrying a create.

Other statuses

During planned maintenance, /v2/sequencer routes answer 405 with error Method Not Allowed and a message that says maintenance is in progress. Retry later. The first time a sequence with email steps is enabled, Salesfinity sets up email sending for the team. If that briefly fails, Enable a sequence answers 503 Service Unavailable; retry after a moment.

Which errors are retryable

Retrying writes safely

Outside the Sequencer, POST endpoints are not idempotent: sending the same request twice acts twice. Cap retries on writes, and confirm state with a GET before retrying a create so you do not duplicate a record. Every POST /v2/sequencer/* endpoint except the three /preview endpoints accepts an Idempotency-Key header, which makes a retry safe. Generate a unique value, such as a UUID, for each write, and send the same value when you retry that write. PATCH, PUT and DELETE requests do not take one.
  • A retry with the same key and the same request returns the original successful response without acting again.
  • The same key with a different body or path returns 409. The comparison covers the method, the path including its query string, and the JSON body.
  • The same key while the first request is still running returns 409. Retry after a moment.
  • A request that fails frees its key, so the retry runs normally. That includes a 5xx: after a 500, 502 or 504 on a create, the work may have finished behind the error, so confirm with a GET before retrying.
  • Keys are kept for 24 hours and are scoped to your team.
  • A 429 is not a failure of the write: the request was refused before the key was claimed, so the retry is the first attempt.
Replace DUE_AT with an ISO 8601 time within the next 365 days, for example 2026-11-02T15:00:00Z.

Handling errors in code

Reporting a problem

Email [email protected] or use the help center. Include:
  • The request_id from the error body, or the X-Request-Id response header. It lets Salesfinity find the exact request.
  • The request method and path, for example GET /v1/call-log.
  • The timestamp of the request, with its timezone.
  • The error and statusCode from the response body.
Never include your API key in a support message.

Next steps

Stay under the rate limits

Per-team budgets, the headers that report them, and pacing.

Test safely on live data

Read-only first, a test team, and writes that reach the dialer.