Errors and retries

The error codes the API returns and what to do about each, the request ID to quote to support, which requests are safe to retry, and how idempotency keys stop a retry from starting a run twice.

The API uses standard HTTP status codes. Every error has a JSON body with a message saying what went wrong, and a code naming the problem:

{
  "error": "Execution not found",
  "error_code": "not_found"
}

Decide what to do from error_code. It names the problem and never changes, while the wording of error is for people and may be improved. The error codes below list every one.

Request IDs

Every response, error or not, carries an X-Request-Id header naming the request:

X-Request-Id: req_9808efd9bf000072c581da45b425d3c0

When something goes wrong and you contact Lodol's support, quote it: it finds the request in Lodol's records. Log it with any error you keep.

Status codes

StatusMeaningWhat to do
200Success
202Accepted: the run has startedFollow it with Get a run
400The request isn't valid, such as an input that doesn't match the workflowFix the request; the message names the problem. Don't retry as is.
401The API key is missing or invalidCheck the Authorization header and the key
402Lodol Local only: the installation needs a licenceAdd the licence in Settings
403The key lacks a scope, its creator's role doesn't allow the action, or the plan doesn't include itUse a key with the right scope, or change the creator's role
404The workflow or run doesn't exist, or was deletedCheck the ID
409A request with the same Idempotency-Key is still being processed, or a run to delete hasn't finishedDepends on the error_code: see Error codes
422The Idempotency-Key was already used for a different requestUse a new key for a new request
429Too many requests, too many runs in progress at once, or the month's runs are used upDepends on the error_code: see Error codes
500Something went wrong on Lodol's sideRetry with backoff

Error codes

These name a problem precisely, so your code can handle each its own way:

CodeStatusMeaningWhat to do
missing_api_key401No Authorization: Bearer … headerSend the key
invalid_api_key401The key is malformed, revoked or expiredCheck the key, or make a new one
missing_scope403The key was made without a scope this endpoint needsUse a key with the scope
permission_denied403The member who made the key isn't allowed to do thisChange their role, or use another member's key
api_key_owner_inactive403The member who made the key has left the workspace, or has no role in itMake a new key
item_view_only403The key's member can see this workflow but not run or change itAsk for edit access to it
workspace_ip_not_allowed403The workspace only accepts requests from certain networksSend the request from an allowed network
invalid_inputs400The run's inputs don't match what the workflow declares, or it takes noneFix the inputs; the message names the one at fault
workflow_not_runnable400The workflow is a draft, or isn't finishedPublish or fix it in Lodol
run_already_finished400Stop a run on a run that has already finishedNothing: the run is over. Get it to see how it ended
run_not_finished409Delete a run on a run that, or a run it started, hasn't finishedStop it, or wait for it to finish, then delete it
request_in_progress409A request with this Idempotency-Key is still being worked onRetry after the Retry-After header's seconds
idempotency_key_reused422This Idempotency-Key was already used for a different requestUse a new key for a new request
rate_limited429Too many requests in the last minuteRetry after the Retry-After header's seconds
concurrency_limit429As many runs are going as your plan allows at onceStart the run once one finishes. Retrying straight away won't help
monthly_run_limit429The month's runs are used upRuns come back at resets_at; add runs or turn on extra runs in Billing to go on now

Any other error has the code for its kind of problem: invalid_request (400), unauthorized (401), licence_required (402), forbidden (403), not_found (404), method_not_allowed (405), conflict (409), request_too_large (413), unprocessable_request (422), internal_error (500) or service_unavailable (503).

Common errors

Retry safely

Retry 409, 5xx, and 429 with the code rate_limited, waiting longer each time. When the response has a Retry-After header, wait that many seconds; otherwise back off exponentially. Don't retry other 4xx responses: the request itself needs fixing. Nor the other 429s: concurrency_limit clears only when a run finishes, and monthly_run_limit when the month's runs come back.

async function lodolRequest(url, options = {}, maxRetries = 3) {
  for (let attempt = 0; ; attempt++) {
    const response = await fetch(url, options);
    const code = response.status === 429 ? (await response.clone().json()).error_code : null;
    const retryable =
      response.status === 409 || response.status >= 500 || code === 'rate_limited';
    if (!retryable || attempt === maxRetries) return response;

    const retryAfter = Number(response.headers.get('Retry-After'));
    const seconds = retryAfter > 0 ? retryAfter : 2 ** attempt;
    await new Promise((resolve) => setTimeout(resolve, seconds * 1000));
  }
}

Retry a request that starts a run only with an idempotency key, or a timeout could start the same run twice.

Idempotency

POST requests, Run a workflow and Stop a run, accept an Idempotency-Key header. Lodol remembers the response to the first request with each key, and returns that same response to any later request with the same key, instead of doing the work again.

curl -X POST https://api-prod.lodol.com/api/v1/workflows/665f1a2b3c4d5e6f7a8b9c0d/run-async \
  -H "Authorization: Bearer $LODOL_API_KEY" \
  -H "Idempotency-Key: order-1042-confirmation"
  • Make the key from what the run is for, such as your own order or event ID, so a retry of the same work always sends the same key. Keys can be up to 256 characters.
  • Responses are kept for 24 hours. A repeated request in that time gets the first response back, with an X-Idempotent-Replayed: true header.
  • Requests in flight return 409. If the first request with a key is still being processed, a second one gets 409 Conflict with Retry-After: 5.
  • A key belongs to one request. Reusing a key for a different request, such as the same workflow with different inputs, returns 422.

DELETE requests take no idempotency key. Deleting a workflow or a run that's already gone returns 404, so check with Get a workflow or Get a run before retrying a delete that timed out.

On this page