Reference · 63 error codes
Errors
Every error carries a stable code. Branch on the code, show the message, log the request id. Each code below has its own anchor: error.docUrl links straight to it.
Last updated from API version 2026-10-06 at (live spec, refreshed hourly). openapi.json
{
"error": {
"type": "unavailable",
"code": "API_V1_NOT_ENABLED",
"message": "API v1 is not enabled on this workspace yet.",
"requestId": "<requestId>",
"docUrl": "https://owlbound.ai/docs/api/errors#API_V1_NOT_ENABLED"
}
}| Field | Meaning |
|---|---|
type | The broad class: invalid_request, authentication, insufficient_credits, permission, not_found, conflict, unprocessable, idempotency, rate_limit, internal, unavailable. |
code | Stable UPPER_SNAKE code. New codes can appear: handle unknown codes by their type and status. |
message | Human readable. It can change: never parse it. |
requestId | Also in the X-Request-Id header. Quote it to support. |
docUrl | This page, at the code's anchor. |
param | The request field or header at fault, when there is one. |
details | Code-specific details, for example the new plan on PLAN_STALE or the cap on CAP_EXCEEDED. |
Action targets that are skipped or fail inside a run (for example ALREADY_SENT or NO_EMAIL) are not request errors: they are reported per target in GET /api/v1/actions/{id}/targets as reason, and each action operation lists its reasons in the reference.
HTTP 400
CURSOR_MISMATCH
400 · invalid_request
A pagination cursor was reused with different filters.
What to doKeep the same filters for every page of a listing, or start again without cursor.
INVALID_CELL_VALUE
400 · invalid_request
A table cell value does not match its column type.
What to doSend a value of the column's type (numbers for number, ISO 8601 strings for date, an existing option for select, ...).
INVALID_FILTER
400 · invalid_request
A rows filter is malformed or names an unknown column or operator.
What to doUse the filter language ({column, op, value}, {and: [...]}, {or: [...]}) with column keys that exist on the table.
UNSUPPORTED_FILTER
400 · invalid_request
A query parameter that is reserved or not supported by this operation was sent.
What to doRemove the parameter. Check the operation's parameters in the reference.
VALIDATION_ERROR
400 · invalid_request
A parameter, header or body field is missing or invalid.
What to doRead error.param (the field at fault) and error.message, fix the request and send it again. Operations marked idempotency required also return this when the Idempotency-Key header is missing.
HTTP 401
API_KEY_EXPIRED
401 · authentication
The API key reached its expiry date.
What to doCreate a new key in the Developer tab and replace the old one.
API_KEY_INVALID
401 · authentication
The API key is malformed or unknown.
What to doCopy the full key again from where you stored it at creation. Keys are shown once; create a new one if it is lost.
API_KEY_REVOKED
401 · authentication
The API key was revoked (or rotated and its grace period ended).
What to doUse the current key. Actions already queued with a revoked key stop at their next batch.
MISSING_API_KEY
401 · authentication
The request carries no API key.
What to doSend Authorization: Bearer owl_sk_... (or X-API-Key). Create a v1 key in the app, Settings > Developer.
SESSION_INVALID
401 · authentication
The dashboard session behind this request is no longer valid.
What to doSign in again. API clients should use an API key instead of a session.
HTTP 402
INSUFFICIENT_CREDITS
402 · insufficient_credits
The workspace wallet cannot cover what this request would hold or charge.
What to doAdd credits in the dashboard, then retry with a new Idempotency-Key (a 402 returned by the operation is replayed under the old key).
HTTP 403
IDENTITY_NOT_ALLOWED
403 · permission
The key is bound to one identity and the request names another.
What to doDrop identityId (the bound identity is used), or use a key bound to the identity you need.
IDENTITY_UNAVAILABLE
403 · permission
The sending identity cannot run this action (no connected account for the channel, disconnected, or not usable).
What to doReconnect the identity's account in the app, or pick another identity with identityId.
INSUFFICIENT_SCOPE
403 · permission
The key does not hold the scope this operation needs (read, write, enrich or act).
What to doCheck the operation's scope in the reference and use a key that has it. details.upgrade: true means a legacy v0 key: upgrade it to v1 in the Developer tab.
ORIGIN_NOT_ALLOWED
403 · permission
The request came from a browser origin that is not allowed.
What to doCall the API from your server. Never ship an API key to a browser.
WORKSPACE_ACCESS_DENIED
403 · permission
The caller is not allowed to act on this workspace or resource.
What to doUse a key created in the workspace that owns the resource, by a member with the right role.
WORKSPACE_SUSPENDED
403 · permission
The workspace is suspended, so the API refuses calls.
What to doContact the workspace owner or Owlbound support.
HTTP 404
NOT_FOUND
404 · not_found
The resource does not exist, or belongs to another workspace.
What to doCheck the id. Ids from another workspace, and plans made by another key, are reported as not found.
ROUTE_NOT_FOUND
404 · not_found
No operation exists at this method and path.
What to doCheck the method and path against the reference (paths start with /api/v1/).
HTTP 409
ALREADY_ENROLLED
409 · conflict
The contact is already enrolled in this sequence.
What to doNothing to do. Read the sequence's enrollments to see its state.
COLUMN_KEY_CONFLICT
409 · conflict
A column with this key already exists on the table.
What to doPick another key, or update the existing column.
IDEMPOTENCY_IN_PROGRESS
409 · conflict
A request with the same Idempotency-Key is still running.
What to doWait Retry-After seconds and send the same request again with the same key: you get its stored result.
IDEMPOTENCY_RESULT_UNAVAILABLE
409 · conflict
The earlier request with this Idempotency-Key finished, but its result was not stored (too large, or it carried a secret).
What to doRead the resource's current state with a GET (details.originalRequestId names the first request).
LIST_BUSY
409 · conflict
The saved audience is already being scraped.
What to doWait for it to finish (GET the action), then try again.
PLAN_ALREADY_APPLIED
409 · conflict
This plan already ran. A plan runs once.
What to doTo read the outcome, replay the original request with its Idempotency-Key, or GET the action. Dry run again to plan a new run.
PLAN_STALE
409 · conflict
The dry run's plan no longer matches what would run (targets, skips, approval, price), or it expired after 15 minutes.
What to doReview error.details.changed and the new plan in error.details.plan, then apply the new planId with a new Idempotency-Key.
TABLE_MIGRATING
409 · conflict
The table is being migrated and refuses writes for a moment.
What to doRetry after Retry-After seconds.
TABLE_STORE_UNSUPPORTED
409 · conflict
This operation is not available yet for the table storage your workspace uses.
What to doUse the app for this table, or contact support to know when it is available.
WEBHOOK_ENDPOINT_DISABLED
409 · conflict
The webhook endpoint is disabled, so it cannot redeliver events.
What to doFix the receiver, enable the endpoint (PATCH with status: "enabled"), then redeliver.
HTTP 412
VERSION_CONFLICT
412 · conflict
The row changed since you read it: the version you sent no longer matches, so nothing was written.
What to doRead the row again (details.currentVersion), reapply your change and send the new version. Without a version, the last write wins.
HTTP 422
ACTION_ASYNC_UNAVAILABLE
422 · unprocessable
This action class cannot run as an async run yet.
What to doRun it on one target (inline), or check the action's catalog entry (available).
ACTION_NOT_ALLOWED
422 · unprocessable
The caller may not run this action (role, identity ownership or workspace policy).
What to doAsk the identity's owner or a workspace owner, or run it from the app.
ACTION_NOT_SYNC
422 · unprocessable
mode: "sync" was asked for an action that cannot run inline.
What to doUse mode: "auto" or "async" and follow the action with GET /api/v1/actions/{id}.
CONNECTOR_NOT_ALLOWED
422 · unprocessable
The connector or credential cannot be used by this request.
What to doCheck the connector in Settings > Integrations and its allowed hosts.
CONVERSATION_ACCOUNT_MISMATCH
422 · unprocessable
The conversation or post belongs to another LinkedIn account than the sending identity's.
What to doRun the action as the identity that owns the conversation.
CRM_NOT_CONNECTED
422 · unprocessable
The workspace has no connection to this CRM.
What to doConnect the CRM in the app (Settings > Integrations), then dry run again.
HOST_NOT_ALLOWED
422 · unprocessable
The URL points to a host that is not allowed (private, loopback, link-local or metadata addresses, or outside a credential's allowed hosts).
What to doUse a public https URL. Redirects are never followed: answer the request directly.
ICP_TOO_BROAD
422 · unprocessable
A first scrape of a saved audience over 1,000 people is refused.
What to doNarrow the audience in the app, then dry run again.
IDEMPOTENCY_KEY_REUSED
422 · idempotency
The Idempotency-Key was already used with a different body or operation.
What to doUse a new key for every distinct request; reuse a key only to retry the exact same request.
IDENTITY_REQUIRED
422 · unprocessable
This action runs as a sending identity and none is known.
What to doPass identityId, or use a key bound to an identity.
LIMIT_EXCEEDED
422 · unprocessable
The request is over a size limit (targets, rows, items or length).
What to doNarrow it (fewer targets, a stricter filter) or split it into several requests.
LIST_EMPTY
422 · unprocessable
The list source returned nobody.
What to doBroaden the search and dry run again.
LIST_SOURCE_UNSUPPORTED
422 · unprocessable
The list source is not supported for this request.
What to doUse one of the source kinds listed for actions.lists.create.
NOT_ENRICHED
422 · unprocessable
Every target lacks the enrichment this action needs (for example scoring an unenriched contact).
What to doEnrich the contacts first, then run the action again.
NOTIFY_NOT_CONNECTED
422 · unprocessable
The notification destination (Slack or Google Chat) is not connected.
What to doConnect it in the app, then try again.
PLAY_COST_UNBOUNDED
422 · unprocessable
The play's cost has no upper bound (a list loop without Max items, or a cycle), so it cannot be held.
What to doSet Max items on the play's loops and remove cycles, then trigger it again.
PLAY_INACTIVE
422 · unprocessable
The play is paused.
What to doResume the play in the app.
PLAY_NO_TRIGGER
422 · unprocessable
The play has no trigger that the API can start.
What to doAdd an API or manual trigger to the play.
PLAY_NOT_DEPLOYED
422 · unprocessable
The play is not deployed.
What to doDeploy the play in the app first.
SALES_NAV_URL_TOO_LONG
422 · unprocessable
The Sales Navigator URL is longer than the search can take.
What to doSave the search in Sales Navigator and use the saved search or lead list URL, or remove filters.
SCHEDULE_UNAVAILABLE
422 · unprocessable
Refreshing (scheduled) lists are not available yet.
What to doOmit schedule and run the list again when you need fresh results.
SEQUENCE_INACTIVE
422 · unprocessable
The sequence is paused or not active.
What to doActivate the sequence in the app, then enroll.
SEQUENCE_NO_STEPS
422 · unprocessable
The sequence has no steps, so nobody can be enrolled.
What to doAdd steps to the sequence in the app.
HTTP 429
CAP_EXCEEDED
429 · rate_limit
A daily cap was reached: the key's (or user's, or agent's) daily credits or daily sends, or a column's daily cap.
What to doWait until details.resetsAt (UTC day), or raise the key's caps in the Developer tab. details has cap, limit and used.
LINKEDIN_SEARCH_LIMIT
429 · rate_limit
The identity's LinkedIn account reached its search limit.
What to doWait for the limit to reset (Retry-After), or use another identity.
PROVIDER_DAILY_LIMIT
429 · rate_limit
The workspace reached its daily limit of company lookups and searches on Owlbound's data provider.
What to doRetry after Retry-After (the next UTC day), or connect your own provider key in the app (free).
RATE_LIMITED
429 · rate_limit
Too many requests for this key or workspace in the current window.
What to doWait Retry-After seconds, then retry. Watch X-RateLimit-Remaining to pace calls; heavy operations count more than one request.
HTTP 500
INTERNAL_ERROR
500 · internal
Something failed on Owlbound's side.
What to doRetry with the same Idempotency-Key (a 5xx is never stored, so the retry runs safely). If it persists, contact support with error.requestId.
HTTP 503
ACTIONS_ASYNC_UNAVAILABLE
503 · unavailable
Async action runs are not available right now; nothing was created.
What to doRetry later, or run the action on a single target.
API_V1_NOT_ENABLED
503 · unavailable
API v1 is not enabled on this workspace or deployment yet.
What to doContact Owlbound to enable API v1. Legacy v0 routes keep working until their sunset.
LINKEDIN_SEARCH_DEGRADED
503 · unavailable
LinkedIn search is degraded right now, so results would be incomplete.
What to doRetry later.
STORE_UNAVAILABLE
503 · unavailable
The data store is briefly unavailable.
What to doRetry with backoff and the same Idempotency-Key.
UPSTREAM_UNAVAILABLE
503 · unavailable
A provider Owlbound depends on did not answer.
What to doRetry later with the same Idempotency-Key. Nothing was charged.
Target and run reasons
Common reason values on action targets (and on a list action's error.code). They are reported per target, not as a request error; each action lists its own in the reference.
PROVIDER_KEY_REMOVED
The list started on the workspace's own data provider key, and that key was removed before the list finished. Owlbound does not fall back to its own key, so nothing more is charged.
What to doReconnect the provider key in the app (Settings > Integrations) and run the list again, or run it without your own key to use Owlbound's (priced).
RUN_CAPPED
The target no longer fit under the request's maxCredits.
What to doRun the skipped targets again with a higher maxCredits.
ALREADY_SENT
This identity already sent this kind of touch to this person within 30 days.
What to doNothing to do: Owlbound never contacts a person twice.
ALREADY_CONTACTED
This person was already contacted by this identity (or a send to them is in flight) within 30 days.
What to doNothing to do. Wait for the window to pass if a second touch is intended.
IN_SEQUENCE
An active sequence is working on this contact, so an ad-hoc send was skipped.
What to doLet the sequence finish, or stop the contact's enrollment first.
CONTENT_CHANGED
The contact changed after the approval, so the frozen content no longer matches.
What to doDry run and submit the action again for a new approval.
OUTCOME_UNKNOWN
The provider did not confirm whether the send happened, and checking could not settle it.
What to doCheck the conversation in the app. Owlbound never retries it, so it is never sent twice.
KEY_DAILY_SENDS
The key's daily send cap was reached; the target waits for the next UTC day (and is skipped if it cannot go in time).
What to doWait, or raise the key's daily sends in Settings > Developer.
NO_CONTACT
The table row has no linked contact, and this action needs one.
What to doPush the rows to contacts first (POST /api/v1/tables/{id}/rows/push, target contacts).
NOT_APPROVED
The person who approved the action unticked this target.
What to doNothing to do, or submit the target again in a new action.