API reference / Jobs

Jobs

A job is a single unit of background work: a target URL, a JSON payload, and the rules for when and how Tend should run it. Create a job with run_at for a delayed one-off, or omit it to run immediately. Tend delivers the payload to your target, records each attempt as a run, and retries failures with exponential backoff and full jitter. Payloads are limited to 256 KB after JSON encoding, and a single attempt may run for up to 15 minutes.

The job object

FieldTypeDescription
idstringUnique job identifier, prefixed job_. Immutable.
statusstringOne of queued, running, succeeded, failed, or canceled. A job is failed only after its final retry attempt.
target_urlstringThe HTTPS URL that receives the payload when the job runs.
payloadobjectArbitrary JSON delivered to the target. Maximum 256 KB after encoding.
run_atstring (ISO 8601)When the job is scheduled to first run. Equal to created_at for immediate jobs.
regionstringRegion that executes the job: us-east, us-west, eu-central, or ap-southeast. Defaults to us-east.
retry_policyobjectContains max_attempts (default 5, maximum 25), base_seconds (default 10), and cap_seconds (default 3600, range 1 to 86400).
attemptsintegerNumber of runs recorded so far, including the one in progress.
created_atstring (ISO 8601)Timestamp of job creation, in UTC.

#Create a job

POST /v2/jobs

Creates a job and queues it for execution at run_at, or immediately if run_at is omitted. Send an Idempotency-Key header to make retries of this call safe for 24 hours. Requests with a run_at more than 60 seconds in the past are rejected with run_at_in_past.

ParameterInTypeRequiredDescription
target_urlbodystringyesHTTPS URL that will receive the payload.
payloadbodyobjectnoJSON payload to deliver. Defaults to an empty object. Maximum 256 KB.
run_atbodystring (ISO 8601)noTime of first execution. Omit to run immediately.
regionbodystringnoRegion to execute in. Hobby projects are limited to us-east.
retry_policybodyobjectnoOverrides max_attempts, base_seconds, and cap_seconds for this job.
Idempotency-KeyheaderstringnoUnique string per logical request. Reusing it within 24 hours with a different body returns idempotency_conflict.
Shell
curl -X POST https://api.tendcomputer.com/v2/jobs \
  -H "Authorization: Bearer tnd_live_8fQ2xLm9Zc41" \
  -H "Idempotency-Key: invoice-4471-reminder" \
  -H "Content-Type: application/json" \
  -d '{"target_url":"https://billing.example-shop.dev/hooks/remind","payload":{"invoice_id":4471},"run_at":"2026-05-14T09:00:00Z","region":"eu-central","retry_policy":{"max_attempts":8}}'
JSON
{
  "id": "job_01HZX7Q4M2",
  "status": "queued",
  "target_url": "https://billing.example-shop.dev/hooks/remind",
  "payload": { "invoice_id": 4471 },
  "run_at": "2026-05-14T09:00:00Z",
  "region": "eu-central",
  "retry_policy": {
    "max_attempts": 8,
    "base_seconds": 10,
    "cap_seconds": 3600
  },
  "attempts": 0,
  "created_at": "2026-05-12T16:22:41Z"
}

#Retrieve a job

GET /v2/jobs/{job_id}

Returns a single job by ID, including its current status and attempt count. Jobs are scoped to the environment of the key, so a tnd_dev_ key cannot read a job created with a tnd_live_ key and receives resource_not_found instead.

ParameterInTypeRequiredDescription
job_idpathstringyesThe job ID, beginning with job_.
Shell
curl https://api.tendcomputer.com/v2/jobs/job_01HZX7Q4M2 \
  -H "Authorization: Bearer tnd_live_8fQ2xLm9Zc41"
JSON
{
  "id": "job_01HZX7Q4M2",
  "status": "succeeded",
  "target_url": "https://billing.example-shop.dev/hooks/remind",
  "payload": { "invoice_id": 4471 },
  "run_at": "2026-05-14T09:00:00Z",
  "region": "eu-central",
  "retry_policy": {
    "max_attempts": 8,
    "base_seconds": 10,
    "cap_seconds": 3600
  },
  "attempts": 2,
  "created_at": "2026-05-12T16:22:41Z"
}

#List jobs

GET /v2/jobs

Returns jobs in reverse chronological order using cursor-based pagination. Pass limit (default 50, maximum 200) and the next_cursor value from the previous response to fetch the next page. When next_cursor is null, you have reached the end.

ParameterInTypeRequiredDescription
limitqueryintegernoPage size. Default 50, maximum 200.
cursorquerystringnoThe next_cursor value from the previous response.
statusquerystringnoFilter by status: queued, running, succeeded, failed, or canceled.
regionquerystringnoFilter by region ID.
Shell
curl "https://api.tendcomputer.com/v2/jobs?status=failed&limit=2" \
  -H "Authorization: Bearer tnd_live_8fQ2xLm9Zc41"
JSON
{
  "data": [
    {
      "id": "job_01HZX9B7T5",
      "status": "failed",
      "target_url": "https://api.example-shop.dev/sync",
      "region": "us-west",
      "attempts": 5,
      "created_at": "2026-05-13T08:04:10Z"
    },
    {
      "id": "job_01HZX6D1K8",
      "status": "failed",
      "target_url": "https://api.example-shop.dev/export",
      "region": "us-east",
      "attempts": 5,
      "created_at": "2026-05-11T22:47:03Z"
    }
  ],
  "next_cursor": "cur_WzE3NDc5"
}

#Cancel a job

DELETE /v2/jobs/{job_id}

Cancels a job that is still queued, preventing any further attempts. A job that is already running finishes its current attempt but is not retried. Jobs in a terminal state cannot be canceled and return invalid_request.

ParameterInTypeRequiredDescription
job_idpathstringyesThe job ID, beginning with job_.
Shell
curl -X DELETE https://api.tendcomputer.com/v2/jobs/job_01HZXB3N6R \
  -H "Authorization: Bearer tnd_live_8fQ2xLm9Zc41"
JSON
{
  "id": "job_01HZXB3N6R",
  "status": "canceled",
  "target_url": "https://billing.example-shop.dev/hooks/remind",
  "run_at": "2026-05-20T09:00:00Z",
  "region": "us-east",
  "attempts": 0,
  "created_at": "2026-05-13T10:15:56Z"
}