SDKs
SDKs and libraries
Official Halyard SDKs for Node.js, Python, Go and Ruby. They share one design: the same method names, automatic retries, typed errors and webhook verification built in.
On this page
Official SDKs
Each SDK is maintained by Halyard Labs, tested against the live API on every release and versioned in step with API v3. Pick yours to see installation, workers, webhooks and framework guides.
Node.js
Stable@halyard/node · v3.4.2
Node.js 20+, Bun 1.2+ and Deno 2 · ships ESM, CommonJS and TypeScript types
npm install @halyard/nodePython
Stablehalyard · v3.4.0
Python 3.10 – 3.14 · sync and asyncio clients · fully typed (PEP 561)
pip install halyardGo
Stablehalyard.example/go/halyard · v3.3.1
Go 1.22+ · context-aware · no dependencies outside the standard library
go get halyard.example/go/halyard@v3Ruby
Stablehalyard · v3.2.5
Ruby 3.2+ · Rails 7.1+ integration and Active Job adapter · RBS signatures included
gem install halyardFeature support
All four SDKs cover the full v3 API. A few conveniences arrive in one language before the others; this table shows where each one stands in the latest release.
- JobsCreate, retrieve, cancel, list
- Node.js
- Yes
- Python
- Yes
- Go
- Yes
- Ruby
- Yes
- Batch createUp to 500 jobs per request
- Node.js
- Yes
- Python
- Yes
- Go
- Yes
- Ruby
- Planned
- WorkersLong-polling, concurrency, graceful shutdown
- Node.js
- Yes
- Python
- Yes
- Go
- Yes
- Ruby
- Yes
- EventsPublish and manage subscriptions
- Node.js
- Yes
- Python
- Yes
- Go
- Yes
- Ruby
- Yes
- Schedules1Cron with time zones, pause and resume
- Node.js
- Yes
- Python
- Yes
- Go
- Yes
- Ruby
- Partial
- Webhook verificationHMAC SHA-256 with timestamp tolerance
- Node.js
- Yes
- Python
- Yes
- Go
- Yes
- Ruby
- Yes
- Typed payloads2Checked at compile time or on enqueue
- Node.js
- Yes
- Python
- Yes
- Go
- Yes
- Ruby
- Partial
- Retries configPer-job attempts and backoff override
- Node.js
- Yes
- Python
- Yes
- Go
- Yes
- Ruby
- Yes
- Automatic idempotency keysSafe client-side retries
- Node.js
- Yes
- Python
- Yes
- Go
- Yes
- Ruby
- Yes
- Auto-paginationIterate every page with one loop
- Node.js
- Yes
- Python
- Yes
- Go
- Yes
- Ruby
- Yes
- Async client3Non-blocking I/O
- Node.js
- Yes
- Python
- Yes
- Go
- Yes
- Ruby
- Planned
- OpenTelemetry4Traces across enqueue and run
- Node.js
- Yes
- Python
- Yes
- Go
- Partial
- Ruby
- Planned
- Test helpersIn-memory client for unit tests
- Node.js
- Yes
- Python
- Yes
- Go
- Yes
- Ruby
- Yes
YesPartialPlanned
- 1Ruby 3.2 can create and delete schedules; pause and resume land in 3.3.
- 2Ruby validates at runtime and ships RBS signatures.
- 3Go uses goroutines and context; Node is promise-based.
- 4Go propagates trace context but doesn't create spans yet.
Shared behavior
Whatever language you use, the SDKs behave the same way on the wire. That means you can read an example in one language and trust it in another.
- Method names mirror the API.
POST /jobsisjobs.create,GET /events/:idisevents.retrieve, in every SDK. - Errors are typed. Each error type maps to its own exception or error value, with the request ID attached.
- Timeouts are explicit. 30 seconds per request by default, configurable per client and per call.
- Requests are identifiable. Every request sends a
Halyard-Clientheader with the SDK name and version, so support can tell what you are running.
Retries and idempotency
The SDKs retry connection errors, 429 and 5xx responses twice by default, with exponential backoff and jitter, and they honor Retry-After. Every mutating request carries an idempotency key, so a retry never creates a second job. Pass your own key when the same business action might be sent twice, for example from two web servers.
await halyard.jobs.create({ queue: "billing", task: "charge-invoice", payload: { invoice_id: "inv_2Gd7" }, idempotencyKey: "charge-inv_2Gd7",});halyard.jobs.create( queue="billing", task="charge-invoice", payload={"invoice_id": "inv_2Gd7"}, idempotency_key="charge-inv_2Gd7",)jobs.Client.Jobs.Create(ctx, &halyard.JobCreateParams{ Queue: "billing", Task: "charge-invoice", Payload: map[string]any{"invoice_id": "inv_2Gd7"},}, halyard.WithIdempotencyKey("charge-inv_2Gd7"))Halyard.jobs.create( queue: "billing", task: "charge-invoice", payload: { invoice_id: "inv_2Gd7" }, idempotency_key: "charge-inv_2Gd7")Pagination
List endpoints return up to 100 items per page with a cursor. Each SDK wraps that in an iterator that fetches the next page only when you reach it, so you can loop over thousands of jobs without thinking about cursors.
for await (const job of halyard.jobs.list({ queue: "emails", status: "failed" })) { console.log(job.id, job.lastError?.message);}for job in halyard.jobs.list(queue="emails", status="failed"): print(job.id, job.last_error and job.last_error.message)iter := jobs.Client.Jobs.List(ctx, &halyard.JobListParams{ Queue: "emails", Status: halyard.JobStatusFailed,})for iter.Next() { job := iter.Current() log.Println(job.ID, job.LastError.Message)}if err := iter.Err(); err != nil { return err}Halyard.jobs.list(queue: "emails", status: "failed").auto_paging_each do |job| puts [job.id, job.last_error&.message].join(" ")endCommunity libraries
These libraries are written and maintained by people outside Halyard Labs. We list them because they are actively maintained and pass our public conformance suite, but we don't review their code.
- halyard_exElixirClient and GenStage-based worker for Phoenix apps.Fjord & Pinev0.9.2
- halyard-rsRustAsync client on reqwest and tokio, with a typed worker trait.Mira Okonkwov0.6.0
- Halyard.NetC#Client for .NET 8 with a hosted-service worker and DI extensions.Larchwood Softwarev2.1.0
- halyard-laravelPHPLaravel queue driver, so dispatch() sends jobs to Halyard.Tamsin Rowev1.4.3
- halyard-ktKotlinCoroutine client for the JVM with Spring Boot autoconfiguration.Quayside Labsv0.4.1
Built a library? Run it against halyard conformance run and write to sdks@halyard.example to have it listed here.
Versioning policy
SDKs follow semantic versioning, and the major version matches the API version it targets: every 3.x release talks to API v3. Within a major version:
- Minor releases add methods and options. Upgrading never requires code changes.
- Patch releases fix bugs and update dependencies.
- Deprecations are announced in the changelog and log a warning at runtime for at least two minor releases before anything is removed in the next major.
- Runtimes are supported until their upstream end of life. Dropping one is treated as a breaking change.
Support windows
| Major | Status | API | Supported until | What you get |
|---|---|---|---|---|
| 3.x | Active | v3 | Current | New features, fixes and security patches. |
| 2.x | Maintenance | v2 | June 30, 2027 | Security and critical fixes only. |
| 1.x | End of life | v1 | Ended March 4, 2026 | No updates. The v1 API stops answering on December 1, 2026. |