Documentation Index
Fetch the complete documentation index at: https://docs.uselamina.ai/llms.txt
Use this file to discover all available pages before exploring further.
Error Envelope
Every /v1/ error response uses a structured envelope:
{
"error": "Human-readable error message",
"code": "AUTH_INVALID_KEY",
"retryable": false,
"requestId": "550e8400-e29b-41d4-a716-446655440000"
}
| Field | Type | Always present | Description |
|---|
error | string | Yes | Human-readable error message |
code | string | Yes | Machine-readable error code (see table below) |
retryable | boolean | Yes | Whether the request can be retried |
retryAfter | integer | Only on 429 | Seconds to wait before retrying |
details | array | Only on VALIDATION_ERROR | Per-field validation errors |
requestId | string | Yes | Trace ID from X-Request-Id header |
For agents: branch on code for error handling, use retryable to decide whether to retry, and include requestId in support requests.
Error Codes
| Code | HTTP | Retryable | When |
|---|
AUTH_MISSING_KEY | 401 | No | No API key in x-api-key or Authorization header |
AUTH_INVALID_KEY | 401 | No | Key hash not found or key is revoked |
AUTH_INVALID_CONTEXT | 401 | No | Key record is missing workspace or user context |
AUTH_FAILED | 500 | Yes | Database error during key validation |
FORBIDDEN | 403 | No | Workspace mismatch, app access denied, trigger inactive |
NOT_FOUND | 404 | No | App, execution, trigger, or template not found |
VALIDATION_ERROR | 400 | No | Invalid inputs, missing required fields, bad request body |
RATE_LIMITED | 429 | Yes | Request rate exceeded; check retryAfter |
WEBHOOK_INVALID_URL | 400 | No | Webhook URL malformed or unsupported protocol |
WEBHOOK_INVALID_SECRET | 401 | No | Webhook secret does not match |
RESOURCE_UNAVAILABLE | 503 | Yes | Service not configured or temporarily unavailable |
INTERNAL_ERROR | 500 | Yes | Unhandled server error |
HTTP Status Codes
| Status | Meaning |
|---|
200 | Successful read |
202 | Execution accepted and queued asynchronously |
400 | Invalid request body or inputs |
401 | Missing or invalid API key |
403 | Access denied for this workspace or app |
404 | App or execution not found |
429 | Rate limit exceeded |
500 | Unexpected server-side failure |
503 | Service temporarily unavailable |
Interpreting 202 Accepted
POST /v1/apps/{appId}/runs returns 202 when Lamina has accepted the job.
That does not mean outputs are ready yet. After a 202 response:
- store the returned run ID
- call
GET /v1/runs/{runId}/wait?timeout=60 (simplest)
- or poll
GET /v1/runs/{runId} every 3-5 seconds
- or wait for your webhook callback
Common Error Cases
Authentication errors
{
"error": "Missing API key",
"code": "AUTH_MISSING_KEY",
"retryable": false,
"requestId": "abc-123"
}
Action:
AUTH_MISSING_KEY: send x-api-key header or Authorization: Bearer ...
AUTH_INVALID_KEY: verify the key value, check it has not been revoked, confirm correct environment
AUTH_INVALID_CONTEXT: the key exists but is misconfigured — contact support
Validation errors include a details array with one structured entry per problem:
{
"error": "Invalid inputs",
"code": "VALIDATION_ERROR",
"retryable": false,
"requestId": "abc-123",
"details": [
{
"param": "Mention Key Ingredients",
"code": "missing_no_default",
"message": "\"Mention Key Ingredients\" is required: no default is configured for this parameter."
},
{
"param": "Location",
"code": "invalid_option",
"message": "\"Location\": invalid option \"Mars\". Must be one of: Studio, Urban, Park"
}
]
}
Each detail entry has:
| Field | Type | Meaning |
|---|
param | string | null | The offending parameter name |
code | string | A machine-readable detail code (see below) |
message | string | A human-readable explanation |
Detail codes:
| Code | When it fires |
|---|
missing_no_default | A parameter has no default and you didn’t supply a value for it |
unknown_parameter | The input key doesn’t match any parameter on this app |
invalid_option | You sent an option value that isn’t in the allowed list |
invalid_media | A url parameter failed media validation (bad URL, unreachable, wrong type) |
invalid_type | You sent the wrong JSON type (e.g. a number where a string was expected) |
About required and defaults: every parameter in the schema is returned with required: true, so agents always know to supply a value. If a parameter has a default, omitting it is still safe — the workflow will run with the default. If it has no default, omitting it triggers a missing_no_default error with 400.
How to recover:
- Parse
details[] and branch on code.
- For
missing_no_default: read the param field, look it up in your cached schema, and fill in a value.
- For
unknown_parameter: re-fetch GET /v1/apps/{appId} — your cached schema may be stale.
- For
invalid_option: read the message for the allowed option list and pick one.
- For
invalid_media or invalid_type: fix the value and retry.
Not found
{
"error": "App not found",
"code": "NOT_FOUND",
"retryable": false,
"requestId": "abc-123"
}
Action:
- verify the
appId or runId
- confirm the resource is accessible to the workspace associated with your key
Rate limit exceeded
{
"error": "Too many requests, please try again later",
"code": "RATE_LIMITED",
"retryable": true,
"retryAfter": 60,
"requestId": "abc-123"
}
Action:
- wait
retryAfter seconds before retrying
- read
RateLimit-Limit, RateLimit-Remaining, and RateLimit-Reset headers
- avoid tight polling loops; prefer webhooks or the wait endpoint for long-running executions
Current Rate Limit
All /v1/* endpoints are currently limited to 100 requests per minute per IP.
Retry Guidance
Use the retryable field to decide whether to retry. As a general rule:
Safe to retry (retryable: true):
RATE_LIMITED — wait retryAfter seconds first
INTERNAL_ERROR — transient server failure, use exponential backoff
AUTH_FAILED — transient database error
RESOURCE_UNAVAILABLE — service temporarily down
- Network timeouts while fetching status
- Idempotent reads (
GET /v1/apps, GET /v1/runs/{id})
Do not retry unchanged (retryable: false):
VALIDATION_ERROR — fix the inputs first
AUTH_MISSING_KEY / AUTH_INVALID_KEY — fix credentials
FORBIDDEN — access denied, won’t change on retry
NOT_FOUND — wrong ID
Support Checklist
If you need to debug an issue quickly, capture:
requestId from the error response
code from the error response
- request path and method
- app ID or execution ID
- timestamp