Skip to main content

API Errors

When an API request fails, all LightOn API returns a JSON error response with a consistent structure. Every error includes a machine-readable error code your application can use for programmatic handling, and a human-readable detail message for debugging.

Error Response Format

All /api/v3/ error responses share this envelope:
{
  "id": null,
  "code": 400,
  "error": "bad_request",
  "detail": "Unknown content type path: 'fake:path'",
  "doc_url": "https://developers.lighton.ai/errors#bad_request"
}
FieldTypeDescription
idstring | nullResource or job identifier, when one exists at error time. null for most errors.
codeintegerHTTP status code (mirrors the response status).
errorstringMachine-readable error code. Use this for programmatic error handling.
detailstringHuman-readable explanation. May change between versions — do not parse.
doc_urlstringLink to the relevant section of this page.
indexinteger (optional)0-based position of the failing action in a batch request. Only present on errors from dedicated /batch endpoints.

Validation errors (422)

Requests that fail field-level validation return 422 Unprocessable Entity with an additional fields key mapping each invalid field to its errors:
{
  "id": null,
  "code": 422,
  "error": "validation_error",
  "detail": "One or more fields failed validation.",
  "doc_url": "https://developers.lighton.ai/errors#validation_error",
  "fields": {
    "name": [
      {"error": "required", "detail": "Field required"}
    ],
    "attribute_type": [
      {"error": "invalid_choice", "detail": "Input should be 'text', 'number', 'date', 'boolean', 'select' or 'multi-select'"}
    ]
  }
}
Each entry in fields is an array of {error, detail} objects. A single field can have multiple errors. The error value is a field error code your application can map to form field states.

Batch error responses

Dedicated batch endpoints (e.g., POST /api/v3/content-types/batch, POST /api/v3/files/{id}/facets/batch) execute multiple actions in one request. When a batch request fails, the error response includes an index field — the 0-based position of the action that caused the failure:
{
  "id": null,
  "code": 400,
  "error": "content_type_unknown",
  "detail": "Unknown content type path: 'fake:path'.",
  "doc_url": "https://developers.lighton.ai/errors#content_type_unknown",
  "index": 2
}
All error types (400, 403, 404, 422) include index when triggered inside a batch. Single-action requests never include this field. Replay safety: actions before the failing index are committed but their results are not returned. All action verbs are idempotent — re-send the entire batch after fixing the failing action to complete it.

HTTP Status Codes

StatusMeaningTypical action
400Business rule violated — the request is structurally valid but the operation is not allowedRead error and detail to understand the constraint. Fix the request logic.
401Not authenticated — credentials are missing or expiredRefresh your API key or session token.
403Forbidden — authenticated but lacking the required permissionCheck your role and permissions for this resource.
404Not found — the resource doesn’t exist or isn’t accessible to youVerify the resource ID or path.
409Conflict — a resource with the same identifier already existsUse a different name, or fetch the existing resource.
422Validation error — one or more request fields are invalidRead fields to identify which fields to fix.
429Rate limited — too many requestsWait and retry after the indicated period.
500Server error — something unexpected went wrongRetry later. If persistent, contact support.
502Upstream error — a dependent service (AI model, external provider) failedRetry later. The error code indicates which service.
503Service unavailable — a required service is not deployed or reachableRetry later.
504Timeout — a dependent service did not respond in timeRetry with a simpler request (fewer pages, shorter query).

Error Codes

bad_request

Status: 400 The request is structurally valid JSON but violates a domain rule. The detail message explains the specific constraint.
{"error": "bad_request", "detail": "Unknown content type path: 'fake:path'"}
Common causes:
  • Invalid parameter combination
  • Unsupported value for a domain-specific field
  • Operation not applicable to the current resource state

unauthorized

Status: 401 Authentication credentials were not provided or are invalid.
{"error": "unauthorized", "detail": "Authentication credentials were not provided."}
Include a valid API key in the Authorization: Bearer <key> header, or authenticate via session cookie.

email_verification_required

Status: 403 Your email address has not been verified. Some operations require a verified email.
{"error": "email_verification_required", "detail": "Please verify your email address to access this feature."}
Check your inbox for a verification email, or request a new one from your account settings.

insufficient_permissions

Status: 403 You are authenticated but your role does not grant access to this operation.
{"error": "insufficient_permissions", "detail": "You do not have permission to perform this action."}
Contact your workspace or company administrator to request the required permission.

not_found

Status: 404 The requested resource does not exist, or you do not have access to it. For security, the API does not distinguish between “does not exist” and “not accessible.”
{"error": "not_found", "detail": "Document not found."}
Verify the resource ID or path. If the resource was recently created, ensure you have the appropriate workspace membership.

conflict

Status: 409 A resource with the same unique identifier (name, path, etc.) already exists.
{"error": "conflict", "detail": "A resource with this name already exists."}
Choose a different name, or retrieve the existing resource.

content_filtered

Status: 422 The model refused to generate a response, typically because a safety filter was triggered.
{
  "error": "content_filtered",
  "fields": {
    "query": [{"error": "content_filtered", "detail": "The model refused to generate an answer or a safety filter was triggered."}]
  }
}
Rephrase your query. This is not a rate limit — the model determined the content was not appropriate to answer.

context_length_exceeded

Status: 422 The combined query and retrieved context exceed the model’s maximum context window.
{
  "error": "context_length_exceeded",
  "fields": {
    "query": [{"error": "context_length_exceeded", "detail": "Query + retrieved context exceeds the model's context window."}]
  }
}
Reduce the number of documents in scope (use workspace_id, tag_id, or file_id filters), or shorten your query.

validation_error

Status: 422 The request body is valid JSON, but one or more fields failed validation. Check the fields key for per-field error details.
{
  "error": "validation_error",
  "fields": {
    "content_type_path": [{"error": "required", "detail": "Field required"}],
    "choices": [{"error": "invalid", "detail": "'choices' must be a non-empty list for select/multi-select attributes."}]
  }
}
See Field Error Codes for the vocabulary of field-level error values.

too_many_requests

Status: 429 You have exceeded the rate limit for this endpoint. Wait before retrying.
{"error": "too_many_requests", "detail": "Too many requests. Please try again later."}

internal_server_error

Status: 500 An unexpected error occurred on the server. This is not caused by your request.
{"error": "internal_server_error", "detail": "An unexpected error occurred. Please try again later."}
If the error persists, contact support with the timestamp and endpoint.

model_unavailable

Status: 502 / 503 The requested AI model is not reachable or not currently deployed.
{"error": "model_unavailable", "detail": "The requested model is currently unavailable."}
Retry after a short delay. If using a specific model name, verify it is supported via the models endpoint.

model_timeout

Status: 504 The AI model did not respond within the allowed time.
{"error": "model_timeout", "detail": "The model did not respond within the allowed time."}
Consider reducing the complexity of your request (shorter query, fewer documents in scope).

Domain Error Codes

Some endpoints return domain-specific error codes for fine-grained error handling. Each code links directly from the doc_url in the error response.

Extract

extraction_failed

Status: 500 The extraction pipeline failed unexpectedly. Retry the request. If the error persists, contact support.

extraction_timeout

Status: 504 Extraction did not complete within the allowed time. Try extracting fewer pages at a time.

extraction_upstream_error

Status: 502 An upstream service used during extraction returned an error. Retry after a short delay.

invalid_page

Status: 400 The page specification is malformed. Use integer page numbers or valid ranges.

page_out_of_range

Status: 400 The requested page number is outside the document’s actual page range. Check the document’s page count first.

Facets

attribute_name_conflict

Status: 400 Attribute name is already defined on another node in the same content type tree. Attribute names must be unique across the entire tree (root to leaves).

attribute_name_reserved

Status: 400 Attribute name collides with a system-reserved name (e.g. id, path, type). Choose a different name.

attribute_type_immutable

Status: 400 Cannot change an attribute’s type after creation. To change the type, delete the attribute with undefine_attribute and recreate it with the new type.

attribute_value_invalid

Status: 400 The value does not match the attribute’s type or allowed choices. For select attributes, the value must be one of the defined choices. For multi-select, it must be an array of valid choices.

content_type_depth_exceeded

Status: 400 Tree nesting exceeds the maximum allowed depth of 4 levels (e.g. legal:contract:nda:mutual is depth 4). Restructure your taxonomy to stay within this limit.

content_type_not_assigned

Status: 404 The content type is not assigned to this document. Classify the document first with the classify action.

content_type_not_found

Status: 404 Content type path does not exist for your company. Verify available paths with GET /api/v3/content-types. If you need to create it, use the adopt or define_content_type action.

content_type_sibling_conflict

Status: 400 The document already has a content type from the same tree root. A document can hold at most one classification per tree. Unclassify the existing one first, then classify with the new path.

content_type_unknown

Status: 400 Content type code is not recognized. Verify available content types with GET /api/v3/content-types/seed/templates.

Files

upload_session_expired

Status: 400 The upload session has expired. Create a new upload session and retry.

upload_session_not_found

Status: 404 The upload session ID does not exist. Verify the session ID or create a new one.

Parse

ambiguous_input

Status: 400 Both a file upload and a document URL were provided in the same request. Provide one or the other, not both.

file_rendering_failed

Status: 500 The file could not be rendered to images before OCR processing. The file may be corrupted or in an unsupported variant.

invalid_model

Status: 400 The requested vision-language model is not available. Check supported models via the models endpoint.

invalid_page_range

Status: 400 Page range is malformed or out of bounds. Ensure start page is less than end page and both are within the document’s page count.

max_pages_exceeded

Status: 400 | Also: /extract The document exceeds the maximum page count allowed for this operation. Process the document in smaller page ranges.

max_pages_per_request_exceeded

Status: 400 Too many pages requested in a single OCR call. Split into smaller page ranges.

missing_input

Status: 400 Neither a file upload nor a document URL was provided. Provide one of them.

no_file

Status: 400 The file upload field is empty or missing. Attach a file to the request.

ocr_concurrent_limit

Status: 429 Too many concurrent OCR requests are running. Wait and retry after a short delay.

unsupported_file_format

Status: 400 The file type is not supported for parsing. Check supported file types in the API documentation.

vlm_error

Status: 502 The vision-language model returned an error while processing the document. Retry after a short delay.

vlm_unavailable

Status: 503 The vision-language model is not reachable or not currently deployed. Retry after a short delay.

Workspaces

datasource_connection_failed

Status: 400 Could not connect to the external data source with the provided credentials. Verify your credentials and network access, then retry.

googledrive_folder_inaccessible

Status: 400 The Google Drive folder cannot be accessed with the provided service account. Verify that the service account has read access to the folder.

sharepoint_site_not_found

Status: 400 The SharePoint site does not exist or is not accessible with the provided credentials. Verify the site_id or site_name and tenant configuration.

unknown_provider

Status: 400 The datasource type is not recognized. Supported types: googledrive, sharepoint, servicenow, webscrapper.

workspace_already_synced

Status: 400 The workspace is already connected to a datasource. A workspace can only have one datasource.

workspace_has_datasource

Status: 409 The workspace already has an active datasource import running.

workspace_has_documents

Status: 400 Cannot convert to a synced workspace because it already contains manually uploaded documents. Remove existing documents first or create a new workspace.

Field Error Codes

When you receive a 422 response, each entry in the fields dict contains an error code from this vocabulary:
CodeDescriptionExample
requiredField is missing from the request body{"error": "required", "detail": "Field required"}
blankField is present but empty string{"error": "blank", "detail": "This field may not be blank."}
nullField is present but null{"error": "null", "detail": "This field may not be null."}
invalidWrong type or format{"error": "invalid", "detail": "Input should be a valid integer"}
invalid_choiceNot one of the allowed values{"error": "invalid_choice", "detail": "Input should be 'text', 'number' or 'date'"}
invalid_formatDoesn’t match the expected pattern{"error": "invalid_format", "detail": "Invalid email format"}
too_shortString or array below minimum length{"error": "too_short", "detail": "String should have at least 3 characters"}
too_longString or array exceeds maximum length{"error": "too_long", "detail": "String should have at most 255 characters"}
too_smallNumber below minimum value{"error": "too_small", "detail": "Input should be greater than or equal to 1"}
too_largeNumber exceeds maximum value{"error": "too_large", "detail": "Input should be less than or equal to 100"}
already_existsDuplicate value{"error": "already_exists", "detail": "A group with this name already exists."}
does_not_existReferenced resource not found{"error": "does_not_exist", "detail": "User with this ID does not exist."}

Handling field errors in your application

import requests

try:
    response = requests.post(
        "https://your-instance.lighton.ai/api/v3/content-types",
        headers={"Authorization": f"Bearer {api_key}"},
        json={"action": "define_attribute"},
    )

    if not response.ok:
        error = response.json()

        # Batch requests include the 0-based action index that failed
        if "index" in error:
            print(f"  Failed at batch action #{error['index']}")

        if error["error"] == "validation_error" and "fields" in error:
            # Per-field errors — collect for form display or logging
            for field, errors in error["fields"].items():
                for entry in errors:
                    print(f"  {field}: [{entry['error']}] {entry['detail']}")
        else:
            # Domain error (e.g. attribute_type_immutable, content_type_not_found)
            print(f"Error {error['code']}: [{error['error']}] {error['detail']}")
except requests.RequestException as exc:
    print(f"Network error: {exc}")