TypeScript SDK
npm install @herald-run/sdk
Node.js 20 or later, ESM only. The client reads HERALD_API_KEY (or HERALD_TOKEN) and HERALD_URL, or takes { apiKey, url }.
import { Herald } from '@herald-run/sdk';
const herald = new Herald();
await herald.send({ title: 'Build passed', body: 'Preview is **ready**.' });
Asking
ask sends a form and resolves with the answer values; askAction returns which action button was pressed.
const answer = await herald.ask({
title: 'Release notes?',
fields: [{ id: 'notes', type: 'textarea', label: 'Notes', required: true }],
timeout: '1h', // server deadline
});
const { actionId } = await herald.askAction({
title: 'Deploy to production?',
actions: [
{ id: 'approve', label: 'Approve', values: {} },
{ id: 'reject', label: 'Reject', values: {} },
],
timeout: '10m',
});
timeout sets the server deadline; the optional second argument { waitTimeout } only bounds how long your process waits, after which wait(id) can resume. Pass a stable idempotencyKey so a restarted job does not ask twice. Expired or cancelled requests throw HeraldError with status 410.
Files
import { readFile } from 'node:fs/promises';
const file = await herald.upload('report.pdf', await readFile('report.pdf'), 'application/pdf');
await herald.send({ title: 'Nightly report', attachments: [file] });
const download = await herald.download(file.id);
const bytes = await download.bytes();
Streams need { size }; uploads abort after idleTimeout seconds (default 60) without progress.
Methods
| Area | Methods |
|---|---|
| Messages | send, ask, askAction, wait, cancel, get, messages, watch |
| Threads | thread, threadMessages |
| Files | upload, download |
| Destinations | register, destinations, updateDestination, deleteDestination, rotateDestinationSecret |
| Tasks | claimTask, heartbeatTask, updateTask, taskLogs |
| Secrets | createKeys, seal, unseal, collectSecrets, revealSecrets, secretReceiver, deliverSecret |
| Webhooks | verifyWebhook |
| Account | ping, token, revokeToken, account |
watch(onMessage) calls you for every changed message over one shared live socket with jittered reconnects. Requests retry network errors and 5xx when safe, and wait out 429 responses up to maxRetryAfter (60 s).
Errors
Failures throw HeraldError with status, code (when the server sends one), messageId and retryAfter. See Limits and errors.
Compatibility
Clients follow semver; a 0.x minor may break and the changelog says how. The latest two minor releases of each package are supported by the server.