Browse the docs

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 envelope
{
  "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"
  }
}
FieldMeaning
typeThe broad class: invalid_request, authentication, insufficient_credits, permission, not_found, conflict, unprocessable, idempotency, rate_limit, internal, unavailable.
codeStable UPPER_SNAKE code. New codes can appear: handle unknown codes by their type and status.
messageHuman readable. It can change: never parse it.
requestIdAlso in the X-Request-Id header. Quote it to support.
docUrlThis page, at the code's anchor.
paramThe request field or header at fault, when there is one.
detailsCode-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.

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.

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.

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.

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.