Skip to content

API reference

The Halyard API

A REST API over HTTPS with predictable, resource-oriented URLs. It accepts and returns JSON, uses standard HTTP verbs and status codes, and authenticates with a bearer key.

Base URL

Every endpoint lives under one host, and the major version is part of the path. All requests must use HTTPS; plain HTTP connections are refused rather than redirected, so a key is never sent in the clear.

Test and live data share the same URL. Which one you reach depends only on the key: hy_test_ keys talk to the sandbox, hy_live_ keys to production.

The official SDKs wrap this API with types, retries and automatic pagination. The examples in this reference show cURL, Node.js and Python side by side.

Base URL
https://api.halyard.example/v3

Authentication

Authenticate by sending your secret key in the Authorization header as a bearer token. Keys are created in the dashboard or with the API keys endpoints, and each one carries scopes that limit what it can do.

Keep secret keys on your servers. Requests without a key, or with a revoked one, fail with 401 Unauthorized; a valid key without the right scope gets 403 Forbidden. Read Authentication for key rotation and scopes.

curl https://api.halyard.example/v3/queues \  -H "Authorization: Bearer hy_test_51Hq8Zx2rTmV9cKpL3d"

Versioning

Breaking changes only ship in a new major version, which gets a new path such as /v4. Within v3, behavior that could affect existing code ships in dated releases.

Your account is pinned to the release that was current when you made your first request. To try a newer one, send the Halyard-Version header with a release date; to move the whole account, upgrade in the dashboard. Every response echoes the version it was rendered with.

Pin a version for one request
curl https://api.halyard.example/v3/jobs/job_3Rk9Tq7Xw2 \  -H "Authorization: Bearer hy_test_51Hq8Zx2rTmV9cKpL3d" \  -H "Halyard-Version: 2026-09-15"

Current release

2026-09-15v3.4 · see the changelog

Requests and responses

  • Request bodies are JSON with Content-Type: application/json. Query parameters are used for GET filters only.
  • Field names are snake_case. Timestamps are ISO 8601 strings in UTC, such as 2026-10-14T09:12:03Z. Durations are strings like 10s or 1h.
  • IDs are strings with a type prefix: job_, que_, evt_, sch_, whk_, key_. Treat them as opaque, up to 64 characters.
  • Every response carries a Request-Id header. Include it when you contact support and we can find the request in seconds.
  • Rate limit headers follow the IETF RateLimit-* draft. See Rate limits.
Request and response headers
POST /v3/jobs HTTP/2Host: api.halyard.exampleAuthorization: Bearer hy_test_51Hq8Zx2rTmV9cKpL3dContent-Type: application/jsonHalyard-Version: 2026-09-15 HTTP/2 201Content-Type: application/json; charset=utf-8Halyard-Version: 2026-09-15Request-Id: req_6Tn2Vb9Kx4LmRateLimit-Limit: 100RateLimit-Remaining: 99RateLimit-Reset: 1

Pagination

List endpoints return a list object and page with cursors, so results stay stable while new objects are created. Pass limit (1 to 100, default 20) to set the page size and starting_after with the last ID you received to get the next page. Use ending_before to go back.

Keep going while has_more is true. The SDKs can do this for you:

Auto-pagination in Node.js
// The SDKs page for you: this loop follows has_more and starting_after.for await (const job of halyard.jobs.list({ queue: "emails", status: "failed" })) {  await halyard.jobs.retry(job.id);}
curl -G https://api.halyard.example/v3/jobs \  -H "Authorization: Bearer hy_test_51Hq8Zx2rTmV9cKpL3d" \  -d queue=emails \  -d limit=50 \  -d starting_after=job_3Rk9Tq7Xw2
Response200 OK
{  "object": "list",  "url": "/v3/jobs",  "has_more": true,  "data": [    {      "id": "job_9Lc4Wd2Pq7",      "object": "job",      …    },    …  ]}

Idempotency

Networks fail. To retry a POST safely, send an Idempotency-Key header with a value that is unique to the operation, such as signup-usr_8KfQ2. Halyard stores the first response for 24 hours and returns it again for any request with the same key, instead of doing the work twice.

Reusing a key with different parameters returns 409 idempotency_key_reused. GET, PATCH and DELETE are idempotent by definition and ignore the header.

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"    }  }'

Expanding objects

Some attributes hold the ID of a related object, such as a job's schedule. Pass expand[] with the attribute name to get the full object inline and save a round trip.

Expandable attributes are marked in each object's reference. You can expand up to four levels deep with dot notation, like data.schedule on list endpoints.

Expand a related object
curl -G https://api.halyard.example/v3/jobs/job_8Vx1Lk5Pq3 \  -H "Authorization: Bearer hy_test_51Hq8Zx2rTmV9cKpL3d" \  -d "expand[]=schedule"
Response200 OK
{  "id": "job_8Vx1Lk5Pq3",  "object": "job",  "task": "build-daily-report",  "schedule": {    "id": "sch_2Mf6Xb8Qn4",    "object": "schedule",    "name": "nightly-report",    "cron": "0 2 * * *",    "timezone": "Europe/Amsterdam"  }}

Errors

Halyard uses conventional HTTP status codes: 2xx for success, 4xx when something about the request is wrong, 5xx when something failed on our side. Error bodies always have the same shape, with a stable code you can branch on. The Errors guide lists every code.

200 / 201OK / Created
The request worked.
400Bad Request
A parameter is missing or invalid. Check param.
401Unauthorized
No API key, or the key is invalid or revoked.
403Forbidden
The key is valid but lacks the scope for this call.
404Not Found
The object doesn't exist, or belongs to the other mode.
409Conflict
The object's state doesn't allow this, or an idempotency key was reused.
429Too Many Requests
Slow down; retry after RateLimit-Reset seconds.
5xxServer error
Something failed on our side. Safe to retry with the same idempotency key.
Response400 Bad Request
{  "error": {    "type": "invalid_request_error",    "code": "parameter_missing",    "message": "Missing required parameter: task.",    "param": "task",    "doc_url": "https://docs.halyard.example/docs/errors#parameter_missing",    "request_id": "req_6Tn2Vb9Kx4Lm"  }}

Resources

Six resources cover the whole API. Each page documents the object and every endpoint, with examples you can copy or try in the explorer.

Facts your services publish once and Halyard fans out to queues and webhook endpoints.

Open reference: Events

Suggested