Skip to content

API reference

Jobs

A unit of background work: a task name, a payload and a lifecycle you can follow.

Overview

A job is one piece of work for your workers: a task name, a JSON payload and the queue it runs on. Halyard stores it durably before answering, hands it to a worker and records every attempt.

Jobs move from queued to running to succeeded. A failed attempt is retried with backoff until max_attempts is reached; then the job is failed and stays available for 30 days so you can inspect or retry it.

Endpoints
5
ID prefix
job_
Attributes
19

The job object

Every job endpoint returns this object, or a list of them. Attributes marked null are always present in the response, so you can rely on the shape.

Attributes

idstring

Unique identifier, prefixed with job_.

objectstring

Always job.

queuestring

Name of the queue the job runs on.

taskstring

The task your worker runs, such as send-welcome-email.

payloadobject

The JSON you passed when creating the job, handed to your worker as-is. Up to 256 KB.

statusenum

Where the job is in its lifecycle: scheduled, queued, running, succeeded, failed or cancelled.

priorityinteger

From -10 to 10. Higher runs first within its queue.

attemptsinteger

How many times a worker has picked the job up so far.

max_attemptsinteger

Attempts allowed before the job fails. Inherited from the queue's retry policy unless set.

run_attimestamp | null

If set, the job waits in scheduled until this time.

schedulestring | null

ID of the schedule that created this job, or null. Expandable to the full schedule object.

idempotency_keystring | null

The Idempotency-Key header sent with the create request, if any.

resultobject | null

What your worker returned when the job succeeded.

last_errorobject | null

Details of the most recent failed attempt.

Show 3 child attributes
codestring

Machine-readable reason, such as task_timeout or worker_error.

messagestring

Human-readable message from Halyard or from your worker.

attimestamp

When the attempt failed.

metadataobject

Up to 20 string key-value pairs you can attach for your own reference. Halyard never reads them.

created_attimestamp

When the object was created, in ISO 8601 UTC.

started_attimestamp | null

When the first attempt started.

finished_attimestamp | null

When the job reached succeeded, failed or cancelled.

livemodeboolean

true for objects created with a live key, false for the test sandbox.

The job object
{  "id": "job_3Rk9Tq7Xw2",  "object": "job",  "queue": "emails",  "task": "send-welcome-email",  "payload": {    "user_id": "usr_8KfQ2"  },  "status": "queued",  "priority": 0,  "attempts": 0,  "max_attempts": 5,  "run_at": null,  "schedule": null,  "idempotency_key": "signup-usr_8KfQ2",  "result": null,  "last_error": null,  "metadata": {},  "created_at": "2026-10-14T09:12:03Z",  "started_at": null,  "finished_at": null,  "livemode": false}

Create a job

POST/v3/jobs

Queues a new job. The response comes back once the job is written to three zones, usually within a few milliseconds. Send an Idempotency-Key header so a retried request never creates the job twice.

Body parameters

queuestringrequired

Name of an existing queue. Unknown queues return a 404.

taskstringrequired

Task name your worker registered, up to 120 characters.

payloadobjectdefault: {}

Any JSON object up to 256 KB, passed to your worker unchanged.

priorityintegerdefault: 0

From -10 to 10. Higher runs first within the queue.

run_attimestamp

Delay the job until this time. Up to one year ahead.

max_attemptsinteger

Override the queue's retry policy for this job only.

metadataobject

Up to 20 string key-value pairs you can attach for your own reference. Halyard never reads them.

Returns

The new job object, with status set to queued (or scheduled when run_at is in the future).

curl https://api.halyard.example/v3/jobs \  -H "Authorization: Bearer hy_test_51Hq8Zx2rTmV9cKpL3d" \  -H "Idempotency-Key: signup-usr_8KfQ2" \  -H "Content-Type: application/json" \  -d '{    "queue": "emails",    "task": "send-welcome-email",    "payload": {      "user_id": "usr_8KfQ2"    }  }'
Response201 Created
{  "id": "job_3Rk9Tq7Xw2",  "object": "job",  "queue": "emails",  "task": "send-welcome-email",  "payload": {    "user_id": "usr_8KfQ2"  },  "status": "queued",  "priority": 0,  "attempts": 0,  "max_attempts": 5,  "run_at": null,  "schedule": null,  "idempotency_key": "signup-usr_8KfQ2",  "result": null,  "last_error": null,  "metadata": {},  "created_at": "2026-10-14T09:12:03Z",  "started_at": null,  "finished_at": null,  "livemode": false}

Retrieve a job

GET/v3/jobs/{id}

Fetches a job by ID with its current status, attempt count and the latest error, if any.

Path parameters

idstringrequired

The job's ID, such as job_3Rk9Tq7Xw2.

Query parameters

expand[]array

Fields to expand inline. Supports schedule.

Returns

The job object, or a 404 if no job has that ID.

curl https://api.halyard.example/v3/jobs/job_3Rk9Tq7Xw2 \  -H "Authorization: Bearer hy_test_51Hq8Zx2rTmV9cKpL3d"
Response200 OK
{  "id": "job_3Rk9Tq7Xw2",  "object": "job",  "queue": "emails",  "task": "send-welcome-email",  "payload": {    "user_id": "usr_8KfQ2"  },  "status": "succeeded",  "priority": 0,  "attempts": 1,  "max_attempts": 5,  "run_at": null,  "schedule": null,  "idempotency_key": "signup-usr_8KfQ2",  "result": {    "message_id": "msg_61dQe"  },  "last_error": null,  "metadata": {},  "created_at": "2026-10-14T09:12:03Z",  "started_at": "2026-10-14T09:12:04Z",  "finished_at": "2026-10-14T09:12:05Z",  "livemode": false}

List jobs

GET/v3/jobs

Lists jobs, newest first. Filter by queue, task or status, and page through results with cursors.

Query parameters

queuestring

Only jobs on this queue.

taskstring

Only jobs with this task name.

statusenum

Only jobs in this status, such as failed.

created_aftertimestamp

Only jobs created after this time.

limitintegerdefault: 20

How many objects to return, between 1 and 100.

starting_afterstring

A cursor: the ID of the last object on the previous page. The next page starts right after it.

ending_beforestring

A cursor for paging backwards: the ID of the first object on the current page.

Returns

A list object with up to limit jobs in data and a has_more flag.

curl -G https://api.halyard.example/v3/jobs \  -H "Authorization: Bearer hy_test_51Hq8Zx2rTmV9cKpL3d" \  -d queue=billing \  -d status=failed \  -d limit=2
Response200 OK
{  "object": "list",  "url": "/v3/jobs",  "has_more": true,  "data": [    {      "id": "job_7Pw4Hc2Zn8",      "object": "job",      "queue": "billing",      "task": "sync-invoice",      "payload": {        "invoice_id": "inv_20931"      },      "status": "failed",      "priority": 0,      "attempts": 5,      "max_attempts": 5,      "run_at": null,      "schedule": null,      "idempotency_key": null,      "result": null,      "last_error": {        "code": "task_timeout",        "message": "Task exceeded its 30s timeout.",        "at": "2026-10-14T08:41:27Z"      },      "metadata": {},      "created_at": "2026-10-14T08:02:11Z",      "started_at": "2026-10-14T08:02:12Z",      "finished_at": "2026-10-14T08:41:27Z",      "livemode": false    },    {      "id": "job_1Qm8Df6Ts3",      "object": "job",      "queue": "billing",      "task": "sync-invoice",      "payload": {        "invoice_id": "inv_20927"      },      "status": "failed",      "priority": 0,      "attempts": 5,      "max_attempts": 5,      "run_at": null,      "schedule": null,      "idempotency_key": null,      "result": null,      "last_error": {        "code": "task_timeout",        "message": "Task exceeded its 30s timeout.",        "at": "2026-10-14T08:41:27Z"      },      "metadata": {},      "created_at": "2026-10-14T07:55:40Z",      "started_at": "2026-10-14T08:02:12Z",      "finished_at": "2026-10-14T08:41:27Z",      "livemode": false    }  ]}

Cancel a job

POST/v3/jobs/{id}/cancel

Cancels a job that is scheduled or queued. A running job is marked for cancellation and your worker sees job.cancelRequested on its next heartbeat. Finished jobs can't be cancelled and return a 409.

Path parameters

idstringrequired

The ID of the job to cancel.

Body parameters

reasonstring

A note stored on the job and shown in the dashboard, up to 500 characters.

Returns

The job object with status set to cancelled.

curl https://api.halyard.example/v3/jobs/job_3Rk9Tq7Xw2/cancel \  -H "Authorization: Bearer hy_test_51Hq8Zx2rTmV9cKpL3d" \  -H "Content-Type: application/json" \  -d '{    "reason": "User deleted their account"  }'
Response200 OK
{  "id": "job_3Rk9Tq7Xw2",  "object": "job",  "queue": "emails",  "task": "send-welcome-email",  "payload": {    "user_id": "usr_8KfQ2"  },  "status": "cancelled",  "priority": 0,  "attempts": 0,  "max_attempts": 5,  "run_at": null,  "schedule": null,  "idempotency_key": "signup-usr_8KfQ2",  "result": null,  "last_error": null,  "metadata": {},  "created_at": "2026-10-14T09:12:03Z",  "started_at": null,  "finished_at": "2026-10-14T09:12:40Z",  "livemode": false}

Retry a job

POST/v3/jobs/{id}/retry

Puts a failed or cancelled job back on its queue with a fresh attempt budget. The job keeps its ID, payload and history.

Path parameters

idstringrequired

The ID of the job to retry.

Body parameters

run_attimestamp

Retry later instead of right away.

max_attemptsinteger

A new attempt budget. Defaults to the queue's retry policy.

Returns

The job object with status set to queued and attempts reset to 0.

curl -X POST https://api.halyard.example/v3/jobs/job_7Pw4Hc2Zn8/retry \  -H "Authorization: Bearer hy_test_51Hq8Zx2rTmV9cKpL3d"
Response200 OK
{  "id": "job_7Pw4Hc2Zn8",  "object": "job",  "queue": "billing",  "task": "sync-invoice",  "payload": {    "invoice_id": "inv_20931"  },  "status": "queued",  "priority": 0,  "attempts": 0,  "max_attempts": 5,  "run_at": null,  "schedule": null,  "idempotency_key": null,  "result": null,  "last_error": {    "code": "task_timeout",    "message": "Task exceeded its 30s timeout.",    "at": "2026-10-14T08:41:27Z"  },  "metadata": {},  "created_at": "2026-10-14T08:02:11Z",  "started_at": "2026-10-14T08:02:12Z",  "finished_at": null,  "livemode": false}

Suggested