SDK
@oqim/sdk is the TypeScript client for the Oqim API. It has no runtime dependencies and uses fetch, so it runs on Node.js 18 and later, Deno, Bun and in browsers. It isn't on npm yet: install it from the repository.
Install#
The package isn't published to npm yet. Build it from a clone of the Oqim repository, then install the file that makes:
It's an ES module with type declarations: import { Oqim } from "@oqim/sdk". The package's README, in packages/sdk, has more examples.
The client#
Create one client with your host and an API key, and reuse it. Each property groups the endpoints of one resource, with typed parameters and responses.
- The key acts as the
API_CLIENTrole. Endpoints for people, such as connecting Telegram accounts or managing the team, answer403 forbiddento it. Keep keys on servers. - In the browser, on the console's own origin, leave the key out: requests then use the console session.
- Every method takes an optional last argument with
signal,timeoutMs,maxRetriesandheadersfor that request.
Access tokens
To avoid sending the long-lived key on every request, exchange it for a one-hour access token with auth.token(). Give the client a function, and it asks for the current token before each request:
Resources
For an endpoint the SDK doesn't wrap yet, call it directly with a path relative to /api/v1: oqim.request("GET", "/public/config"). You get the same credentials, retries and errors.
Errors#
Every failure is an OqimError, built from the API's error envelope:
Pagination#
List methods return a page request. Await it for one page, or loop over it with for await to get every item: the SDK fetches pages of 100 as the loop goes.
Lists are newest first and paged by offset, so an item created while you loop can push one you've already seen into the next page. The loop skips IDs it has already given you. .all() collects every item into an array, for small lists.
Retries and timeouts#
429 rate_limitedis retried for any method after theRetry-Afterthe API sends: the rate limiter answers before the request does anything, so repeating it is safe. A wait longer thanmaxRetryAfterSeconds(default 60) is thrown instead. Other 429s, such astest_limit_reached, aren't retried. See Rate limits.5xxresponses, network errors and timeouts are retried only for requests that are safe to repeat: GET, PUT and DELETE, plus POSTs that can't do anything twice, such as pausing, resuming, validating and previews.- Creating things (recipients, campaigns, keys) isn't retried after a 5xx or a timeout: it may have worked. Check before sending it again; recipients are unique by Telegram ID and username, so a repeat fails with
409 recipient_existsrather than creating a duplicate. - Waits grow from half a second to at most 8 seconds, with jitter so clients don't retry in step.
Live events#
events.stream() reads GET /events/stream as an async iterator, with the same events webhooks deliver:
- It reconnects after network errors, API restarts and silence: the API pings every 20 seconds, and after 45 seconds without anything the SDK connects again.
- After reconnecting it fetches what it missed from
GET /eventsand skips events it has already given you, so a short outage loses nothing. sincereplays earlier events first, then goes live.typestakes event types, withcampaign.*matching a prefix.- Aborting the signal, or
break, ends the loop and closes the connection. A revoked key or a missing permission is thrown rather than retried.
Webhook verification#
verifyWebhookSignature checks a delivery's Oqim-Signature header exactly as the API makes it: HMAC-SHA256 over <t>.<raw body> with the endpoint's whsec_ secret, compared in constant time, and a t more than 5 minutes from your clock rejected. It needs no API key; it's also on the client as oqim.webhooks.verifySignature.
While you roll out a rotated secret, pass both: [newSecret, oldSecret]. See Webhooks for the scheme and examples in Go and Python.
The same with curl#
Other languages#
The API reference is also an OpenAPI 3.1 spec. Point a client generator at it for another language, or import it into Postman or Insomnia.