API reference

Operations

Health and readiness probes, and the dead-letter lists for background jobs and webhook deliveries.

These endpoints tell you whether the API is up and let a workspace admin see and retry work that failed for good. Two are public probes for load balancers and monitors. The others list background jobs and webhook deliveries that ran out of attempts, so that nothing fails silently.

OperationMethod and pathMinimum role
Check livenessGET /healthnone
Check readinessGET /readynone
List dead jobsGET /jobs/deadadmin
Requeue a dead jobPOST /jobs/dead/{job_id}/requeueadmin
Dismiss a dead jobDELETE /jobs/dead/{job_id}admin
List dead webhook deliveriesGET /webhooks/deadadmin
Resend a dead webhook deliveryPOST /webhooks/dead/{delivery_id}/resendadmin

The platform's own monitoring (minute-by-minute probes of the API, the database, the voice engine and the model servers; incidents; email alerts) is the operator's: it shows on the operator workspace's Home summary as incident alerts (Home summary) and through an operator-only endpoint that is not part of this API.

The dead-letter endpoints need the admin role for reading as well as for changing. A caller below admin gets 403:

text
Your role (member) can't do this. It needs admin access; ask an owner or admin of the workspace.
Your role (member) can't change background jobs. It needs admin access; ask an owner or admin of the workspace.

Probes

Check liveness

GET /health

Says that the API process answers. It touches no dependency, so it stays 200 even when the database is down. Use GET /ready to decide whether to send traffic.

Auth: none.

Request

bash
curl https://api.sevennadi.si/health

Response 200 OK

json
{"status": "ok"}

Check readiness

GET /ready

Checks each dependency and reports whether it answered and how long it took. The database and Redis are required: if either fails, the status code is 503. The voice engine and the platform's own model servers are reported when the operator has configured their health URLs, but they never change the status code.

Auth: none. The response has dependency names and timings only.

Request

bash
curl https://api.sevennadi.si/ready

Response 200 OK

json
{
  "status": "ready",
  "dependencies": {
    "database": {"ok": true, "ms": 4.8, "required": true},
    "redis": {"ok": true, "ms": 0.8, "required": true},
    "engine": {"ok": true, "ms": 12.1, "active_calls": 2, "max_calls": 20, "full": false, "required": false}
  }
}
FieldMeaning
statusready or not_ready.
dependencies.<name>.okWhether the dependency answered.
dependencies.<name>.msHow long the check took, in milliseconds.
dependencies.<name>.errorOn failure, the kind of error (an exception name, never a connection string).
dependencies.<name>.requiredWhether a failure makes the API not ready.
dependencies.enginePresent only when the operator set the engine's health URL. It may also carry active_calls, max_calls, full, draining, rejected_calls and concurrency_caps, as the engine reports them.
dependencies.model_stt, model_tts, model_llmPresent only when the operator enabled model checks.

The numbers in the example are illustrative.

Errors

StatusBody
503The same body with "status": "not_ready" and the failing dependency's "ok": false. This response is not in the usual error shape.

Dead jobs

Background work such as running a call, sending a batch or advancing a workflow is done by queued jobs. A job that keeps failing is retried a limited number of times and then moved to the dead-letter list instead of being lost. You see only the jobs of your own workspace.

List dead jobs

GET /jobs/dead

Lists the workspace's dead jobs, newest first.

Auth: API key or session token. Role: admin and up.

ParameterInTypeRequiredDescription
statusquerystringnodead (default), requeued, dismissed or all.
limitqueryintegerno1 to 200. Default 50.

Request

bash
curl "https://api.sevennadi.si/jobs/dead?status=all" \
  -H "Authorization: Bearer vk-0123456789abcdef0123456789abcdef"

Response 200 OK

json
{
  "jobs": [
    {
      "id": "b7e1c2d3-4f5a-4b6c-8d7e-9f0a1b2c3d4e",
      "function": "run_execution",
      "subject": "execution 0f9e8d7c-6b5a-4c3d-9e2f-1a0b9c8d7e6f",
      "args": ["0f9e8d7c-6b5a-4c3d-9e2f-1a0b9c8d7e6f"],
      "error": "ConnectError: all connection attempts failed",
      "tries": 3,
      "status": "dead",
      "requeue_count": 0,
      "created_at": "2026-10-13T09:00:00Z",
      "requeued_at": null
    }
  ]
}

function is the job's name and args its arguments. subject identifies what the job was about. The values in the example are illustrative.

Errors

StatusMessage
400limit must be between 1 and 200

Requeue a dead job

POST /jobs/dead/{job_id}/requeue

Puts the job back in the queue with the same arguments and marks it requeued. A dismissed job can be requeued; a job that was already requeued cannot. If the new run fails for good, a new dead job appears.

Auth: API key or session token. Role: admin and up.

ParameterInTypeRequiredDescription
job_idpathstring (UUID)yesThe dead job's id.

Request

bash
curl -X POST https://api.sevennadi.si/jobs/dead/b7e1c2d3-4f5a-4b6c-8d7e-9f0a1b2c3d4e/requeue \
  -H "Authorization: Bearer vk-0123456789abcdef0123456789abcdef"

Response 202 Accepted

The job, as in List dead jobs, with "status": "requeued", requeue_count increased and requeued_at set.

Errors

StatusMessage
404Job not found
409This job was already queued again

Dismiss a dead job

DELETE /jobs/dead/{job_id}

Marks the job dismissed so it no longer shows in the default list. The row is kept.

Auth: API key or session token. Role: admin and up.

ParameterInTypeRequiredDescription
job_idpathstring (UUID)yesThe dead job's id.

Request

bash
curl -X DELETE https://api.sevennadi.si/jobs/dead/b7e1c2d3-4f5a-4b6c-8d7e-9f0a1b2c3d4e \
  -H "Authorization: Bearer vk-0123456789abcdef0123456789abcdef"

Response 200 OK

The job, with "status": "dismissed".

Errors

StatusMessage
404Job not found

Dead webhook deliveries

A webhook delivery is retried with backoff up to an operator-configured number of attempts. A delivery that used them all without success, or whose URL was refused, is listed here.

List dead webhook deliveries

GET /webhooks/dead

Lists the workspace's exhausted deliveries, newest first, with the total count.

Auth: API key or session token. Role: admin and up.

ParameterInTypeRequiredDescription
limitqueryintegerno1 to 200. Default 50.

Request

bash
curl https://api.sevennadi.si/webhooks/dead \
  -H "Authorization: Bearer vk-0123456789abcdef0123456789abcdef"

Response 200 OK

json
{
  "total": 1,
  "deliveries": [
    {
      "id": 4182,
      "execution_id": "0f9e8d7c-6b5a-4c3d-9e2f-1a0b9c8d7e6f",
      "webhook_url": "https://hooks.example.test/calls",
      "status": "completed",
      "attempts": 5,
      "response_code": 500,
      "error": "HTTP 500",
      "created_at": "2026-10-13T09:00:00Z"
    }
  ]
}

status is the call status the delivery was reporting, not the state of the delivery. response_code and error describe the last attempt. The values in the example are illustrative.

Errors

StatusMessage
400limit must be between 1 and 200

Resend a dead webhook delivery

POST /webhooks/dead/{delivery_id}/resend

Gives an exhausted delivery a fresh set of attempts: the same payload, to the same URL, starting now. Fix the receiving endpoint first.

Auth: API key or session token. Role: admin and up.

ParameterInTypeRequiredDescription
delivery_idpathintegeryesThe delivery's id.

Request

bash
curl -X POST https://api.sevennadi.si/webhooks/dead/4182/resend \
  -H "Authorization: Bearer vk-0123456789abcdef0123456789abcdef"

Response 202 Accepted

json
{
  "id": 4182,
  "execution_id": "0f9e8d7c-6b5a-4c3d-9e2f-1a0b9c8d7e6f",
  "webhook_url": "https://hooks.example.test/calls",
  "status": "completed",
  "attempts": 0,
  "response_code": 500,
  "error": null,
  "created_at": "2026-10-13T09:00:00Z"
}

Errors

StatusMessage
400A validation message when delivery_id is not an integer.
404Delivery not found (no such delivery in this workspace, or it is not exhausted)