Errors
Error responses in the Lightfield API.
The Lightfield API uses conventional HTTP status codes and returns a JSON body for errors. Use the response type and, when present, the machine-readable code to handle errors in your integration.
Error response format
Section titled “Error response format”All error responses are wrapped in an error object:
| Field | Type | Description |
|---|---|---|
type | string | Machine-readable error type (e.g. bad_request, not_found). Use this to branch on the kind of error. |
message | string | Human-readable description of what went wrong. |
Example (404):
HTTP/1.1 404 Not FoundContent-Type: application/json
{ "error": { "type": "not_found", "message": "No resource found in 'accounts' with the given ID." }}Some errors also include code and param. Their presence depends on the operation:
| Field | Type | Description |
|---|---|---|
code | string | Finer-grained code for programmatic handling (see Error codes below). Present on errors that define a specific code. |
param | string | Optional. Request location related to the error (e.g. fields.$name, relationships.$owner, Idempotency-Key). Present when the operation identifies a request parameter. |
Example (400):
HTTP/1.1 400 Bad RequestContent-Type: application/json
{ "error": { "type": "bad_request", "message": "Unrecognized field 'bogus' for 'accounts'.", "code": "unknown_field", "param": "fields.bogus" }}Example (422):
HTTP/1.1 422 Unprocessable ContentContent-Type: application/json
{ "error": { "type": "unprocessable_content", "message": "A single request may change at most 25 relationships; this one would change 26. Split the change across multiple requests.", "code": "relationship_write_limit_exceeded", "param": "relationships" }}HTTP status codes
Section titled “HTTP status codes”| Status | Type | When it happens |
|---|---|---|
| 400 | bad_request | Invalid request (wrong field, relationship, or parameter). Check code and param. |
| 401 | unauthorized | Missing or invalid API key. Ensure the request includes Authorization: Bearer $LIGHTFIELD_API_KEY. |
| 403 | forbidden | The caller lacks a required scope or access to the operation or records. Check scopes and the error details. |
| 404 | not_found | The resource is missing, unavailable in this workspace, or hidden from this caller. Check the endpoint’s visibility rules. |
| 409 | conflict | Conflict with current state (e.g. duplicate definition, resource locked, concurrent update). |
| 415 | unsupported_media_type | Request body is not JSON. Include Content-Type: application/json on POST, PUT, and PATCH requests. |
| 422 | unprocessable_content | Request body is valid JSON but business validation failed (e.g. invalid field value). Check param. |
| 429 | too_many_requests | Rate limit exceeded. See Rate limits. |
| 500 | internal_server_error | Server error. Follow the retry rules below; contact support if it persists. |
| 502 | bad_gateway | An attachment provider could not return the file. Retry with backoff a few times, then stop if it keeps failing. |
| 503 | service_unavailable | The service is temporarily unavailable or at capacity. See Rate limits and the retry rules below. |
Error codes
Section titled “Error codes”The code field identifies a specific failure. Check the endpoint reference for its HTTP status and recovery rules:
| Code | Meaning |
|---|---|
referenced_resource_missing | A field references another resource by ID that does not exist. Use param to see which field (e.g. fields.$company). |
relationship_entity_missing | One or more IDs in a relationship (e.g. relationships.$owner) do not exist. |
relationship_entity_inactive | One or more IDs in a relationship refer to an inactive (e.g. deleted) entity. |
relationship_write_limit_exceeded | The request references more than 25 related records or changes more than 25 links. Split it into smaller requests. Creating an opportunity also returns it when Automatically link account contacts is on and the account has more than 1,000 contacts: ask an admin to turn the setting off, or reduce the account’s contacts. |
record_validation_failed | A workspace validation rule refused the create or update, so nothing was saved. message names the broken rule, the missing Required fields, or the linked records the change would break. Fix the values and retry. Rules don’t apply to writes made as an owner or admin. |
mail_attachment_provider_unavailable | The email attachment provider failed during a file URL request (502). Retry with bounded backoff. |
chat_attachment_provider_unavailable | The chat attachment provider failed during a file URL request (502). Retry with bounded backoff. |
unknown_field | The request included a field that is not defined for this object type. Use param to see the field. |
unknown_relationship | The request included a relationship that is not defined for this object type. Use param to see the relationship. |
invalid_configuration | Invalid field or relationship configuration. |
idempotency_key_too_long | The Idempotency-Key header exceeds the maximum length (255 characters). |
invalid_type | A field value has the wrong type (e.g. a string where an object is expected). Use param to see the field. |
parameter_missing | A required request parameter is missing. Use param to see which one. |
version_header | The Lightfield-Version header is missing or invalid. |
ambiguous_stage_label | A stage label needs a pipeline to resolve it. See pipeline and stage errors. |
stage_unresolved_in_pipeline | The supplied stage does not identify one active stage in the selected pipeline. |
unknown_pipeline | The supplied pipeline does not resolve to an active pipeline for this object type. |
draft_not_found | The sequence has no open draft. See sequence errors. |
sequence_not_published | The sequence has never been published, so it cannot be activated, deactivated, or enroll contacts. |
permissions_not_granted | A step built in Lightfield requests tool permissions that have not been approved there yet. |
no_selectable_sender | A channel the sequence’s steps use has no sender that can send. |
Pipeline and stage errors
Section titled “Pipeline and stage errors”Pipeline and stage
resolution errors include details inside the
error object:
| Code | HTTP status | Details and recovery |
|---|---|---|
ambiguous_stage_label | 400 for a filter; 422 for a write | candidates lists stage choices with stageOptionId, stageLabel, pipelineId, and pipelineName. Choose an exact stage option ID or specify its pipeline. For non-Opportunity writes, a label requires a pipeline hint even when only one stage matches. |
stage_unresolved_in_pipeline | 422 | pipelineId identifies the selected pipeline; candidates lists possible stages and their owners. Correct the stage or the pipeline hint. An Opportunity label without a hint is resolved within the default opportunity pipeline. |
unknown_pipeline | 400 for a filter; 422 for a write | activePipelineIds lists available pipelines. Refresh definitions and use a pipeline ID for filtering, or an ID or name for a write hint. |
These lists are bounded; truncated: true means more entries exist. Refresh
definitions
for the full configuration. An empty candidate list can mean the stage label
does not exist. Change the input before retrying; do not silently choose the
first candidate.
If $pipeline is absent from definitions, a write using it returns 400
unknown_field. Refresh definitions for the target object type and omit fields
it does not expose; do not retry the same request.
Sequence errors
Section titled “Sequence errors”Sequence writes are all-or-nothing: a refused request changes nothing, and the response says what to fix. See Using sequences with the API for the draft and version model these errors refer to.
| Code | HTTP status | Details and recovery |
|---|---|---|
invalid_configuration | 400 | On create, update draft, publish, and start test, issues lists every problem found (see sequence draft issues). On enroll and start test, invalidContacts lists each contact that cannot be enrolled and why (see sequence enrollment refusals). Without either list, message explains the refusal and param, when present, names the field. |
referenced_resource_missing | 400 | A reviewer or sender ID does not belong to this workspace, or the sender is archived. param is reviewers or senders; message names the IDs. |
draft_not_found | 404 | Retrieve, update, publish, or discard was called while no draft is open. To open one on a published sequence, update the draft without expectedVersion. |
sequence_not_published | 400 | Activate, deactivate, or enroll was called before the first publish. Publish the draft first. |
permissions_not_granted | 400 | Publish or start test was refused because a step built by the agent in Lightfield requests tool permissions that nobody has approved yet. Approve them on the sequence in Lightfield, then retry. Steps created over the API never request permissions. |
no_selectable_sender | 400 | Activate, enroll, start test, or publish on an active sequence found a channel the steps use with no sender that can send: none is listed, or every listed one is archived, paused, or disconnected. A sequence that isn’t active publishes without senders. Add a sender to the draft and publish it, or reconnect a listed one in Lightfield, then retry. |
Sequence draft issues
Section titled “Sequence draft issues”A refused create, update draft, or publish returns issues, one entry per
problem. Publish checks the draft in stages (content, then reviewers, then
senders, then entitlement) and reports the first stage that fails, so fixing
one stage can reveal the next.
| Field | Description |
|---|---|
code | One of the codes below. |
path | Where in the request body the problem is, with steps addressed by index (definition.steps.1.prompt). |
stepId | The ID of the step concerned, when it has one; null otherwise. |
message | What is wrong, in plain language. |
| Issue code | Recovery |
|---|---|
invalid_value | Fix the field at path. For a template step, path points at its subject or body: see template variables for what a template can contain. |
invalid_step_order | Reorder the steps; message says which rule the order breaks. |
unsupported_step | The step at stepId is one the API cannot save or publish yet, such as a call step or one made in a newer version of Lightfield. Edit or remove it in Lightfield, or omit definition.steps from the save. |
reviewer_inactive | The reviewer is no longer an active member. Remove them, or save any reviewers change to clear them. |
sender_unavailable | The sender is not an unarchived sender of this workspace. Remove it from senders. |
not_entitled | The workspace cannot use what is at path. For LinkedIn steps and senders, the plan does not include LinkedIn: remove them, or upgrade the plan. For a template step (path ends in .mode), template steps are not turned on for the workspace: send the step with mode: "AGENT" and a prompt, or send its template back unchanged. |
Sequence enrollment refusals
Section titled “Sequence enrollment refusals”A refused enroll returns invalidContacts, one entry per contact that cannot
be enrolled, each with contactId and reason. Contacts already enrolled are
not refusals; they are reported as already_enrolled in a successful response.
| Reason | Meaning |
|---|---|
contact_not_found | The contact does not exist in this workspace or is not active. |
missing_email | The sequence has an email step and the contact has no email address. |
missing_linkedin_url | The sequence has a LinkedIn step and the contact has no LinkedIn URL. |
missing_phone_number | The sequence has a call step and the contact has no phone number. |
Conflicts and retries
Section titled “Conflicts and retries”A 409 on a draft write means the draft moved since it was read. Retrieve the
draft and retry with its current version; message says which case applies:
- The draft was published or discarded since it was read.
- The draft changed since it was read, in Lightfield or through the API.
- A
definition.stepssave would delete edits made in Lightfield that are not valid yet. Finish them there, or save withoutdefinition.steps. - The sequence was published from another draft since this one was opened. Discard this draft and start a new one.
- A draft is already open and the request sent no
expectedVersion.
A 409 on start test means expectedVersion is not the open draft’s
version. If a draft is open, retrieve it and retry with its current
version. If the draft was published or discarded, retrieving it returns
404 draft_not_found; omit expectedVersion to test the published version.
A 429 too_many_requests on start test means a test limit was reached, and
no test started. message names the limit: the workspace already has 10 tests
running (retry once one is COMPLETED or FAILED), or it started more than 5
tests a minute (retry after the Retry-After header’s seconds).
A 409 on activate, deactivate, or enroll means the sequence or its
enrollments changed while the request ran. Re-read the sequence, then retry.
A 503 on a draft write means the draft is temporarily unavailable; nothing
changed. Retrieve the draft before retrying.
Retry safely
Section titled “Retry safely”Change invalid inputs before retrying a 400 or 422. For a 409, follow the operation’s conflict instructions: a stale sequence draft needs a fresh version, while a concurrent idempotent operation needs time to finish.
For a supported write that times out or returns a server error, retry with bounded backoff and the original idempotency key. Do not assume every write is safe to retry: starting a sequence test creates another test. Check the endpoint’s recovery instructions first. Honor Retry-After on a 429 or 503 when it’s present.
The SDKs expose typed exceptions. Inspect the API error payload for type and, when present, code and param; use your language’s quickstart for exception handling.