Browse the docs

Changelog

User-visible changes to the API, webhooks and the SDK, newest first. Breaking changes come with migration steps; every operation is in the API reference.

SDK 0.1.0

Request ids, idempotency keys and SDK 0.1.0

  • AddedAPIEvery answer carries X-Request-Id; send your own to have it echoed. Audit log entries record it.
  • AddedAPIIdempotency-Key on authenticated POST /v1/* calls: a retry with the same key within 24 hours replays the first answer (Idempotent-Replayed: true) instead of running twice. New reasons idempotency_key_reused, idempotency_key_in_progress and invalid_idempotency_key.
  • AddedAPIRateLimit-Limit, RateLimit-Remaining and RateLimit-Reset headers on rate-limited calls.
  • AddedSDK@workwae/sdk 0.1.0: errors expose requestId, and every POST sends an Idempotency-Key that is reused across the SDK's own retries (or pass context.idempotencyKey).
  • AddedWebhooksSecret rotation with a grace period: POST /v1/webhooks/{endpointId}/rotate-secret takes graceSeconds (default 24 hours, 0 = at once), during which deliveries carry a second signature by the old secret in webhook-signature. The answer and the endpoint show previousSecretExpiresAt.
  • AddedWebhooksPOST /v1/webhooks/{endpointId}/replay-failed queues every event the endpoint gave up on again, once each, optionally within since/until; GET /v1/webhooks/{endpointId}/failed-deliveries/count says how many that is.
  • AddedAPIAPI keys can expire, and can be renamed, rescoped and rotated with a grace period on the board. A request with an expired key answers 401 with the new reason api_key_expired.

A consistent /v1 surface

  • BreakingAPIPaths follow resource nouns: /v1/imap-accounts, /v1/accounts/{accountId}/outbox, /v1/accounts/{accountId}/calendar-events, /v1/suppressions/{listId}/entries, and the hosted connect pages under /v1/hosted/*.
  • BreakingAPIError bodies are { defined, code, status, message, data? } where code is the error's reason (there is no data.reason), and each reason always answers with the same HTTP status.
  • BreakingAPIListings answer { items, nextCursor } pages or, for small bounded lists, { items }. Creates answer 201, deletes 204, accepted work 202.
  • BreakingAPIDELETE operations take their options in the query string, not a body.
  • BreakingWebhooksEvent types were renamed (calendar_event.*, suppression.created), and webhooks and GET /v1/changes share one event envelope with typed data per event type.
  • BreakingSDKThe SDK is generated from the new contract: methods are named after the operations (workwae.calendarEvents.list), dates arrive as Date, and errors are ORPCErrors whose code is the reason (isApiError, safe, isDefinedError).
  • AddedAPIEvery schema is a named component of the OpenAPI document (/v1/openapi.json), and every operation lists the reasons it can answer with.
  • ChangedAPIDeleting an account or a tenant revokes its Google grant.
  • ChangedAPIWhen a Zoom user removes the workwae app, their meeting connections must be reconnected and meeting_connection.reauth_required is sent.

Migrating

  1. Update request paths to the new resource names; the API reference lists every operation.
  2. Read an error's reason from code instead of data.reason.
  3. Read list results from items and continue with nextCursor (null on the last page).
  4. Move DELETE options (for example purge, notify) into the query string.
  5. Rename the event types your webhook endpoints and change-feed readers filter on.
  6. Upgrade @workwae/sdk and follow the type errors: method names, Date fields and error codes changed with the API.

Suppression reviews, AI drafting and health probes

  • AddedAPIManage suppression lists (/v1/suppressions) and review opt-outs detected in replies (/v1/suppression-reviews).
  • AddedAPIPOST /v1/ai/draft drafts email text. Reply classification sorts auto-replies into categories; it is off until a tenant turns on aiReplyClassification and is capped per day.
  • AddedAPIGET /readyz reports whether the API can serve (database and Redis answer); /healthz turns 503 while an instance drains.
  • AddedAPIA connect session without a redirectUri ends on a workwae outcome page.
  • AddedAPIPlans have modules (calendar, contacts, tracking, AI, meetings, shared mailboxes): a module outside the tenant's plan answers 403 plan_module_unavailable.
  • AddedWebhooksWebhook tester inboxes on the board capture deliveries for inspection.
  • ChangedWebhooksNew webhook endpoints must use https.
  • ChangedWebhooksAn endpoint answering 429 or 503 is backed off politely, honoring Retry-After, without counting against its failure streak.
  • FixedAPIA send whose SMTP reply was lost after the message was handed over fails with outcome_unknown instead of being sent again.
  • FixedSDKWebhook verification computes the signature once and checks at most 8 candidate signatures.

List unsubscribe, Markdown templates and search

  • AddedAPISends and mail merges take a listId: one-click unsubscribe headers (RFC 8058), {{rcpt.unsubscribeUrl}}, and recipients on the list or the global list skipped.
  • AddedAPITemplates take format: "markdown".
  • AddedAPISuppress up to 1,000 addresses in one call with POST /v1/suppressions/{listId}/entries.
  • AddedAPIGET /v1/templates?query= filters by a name substring; GET /v1/accounts?q= searches accounts by email address or external reference.

Templates and mail merge

  • AddedAPIStored Handlebars templates (/v1/templates), previews (POST /v1/template-renders), and template plus render.params on sends and drafts.
  • AddedAPIMail merges: POST /v1/accounts/{accountId}/mail-merges sends one message per recipient, each with its own params, events and tracking.
  • AddedSDKThe workwae templates push command uploads react-email components as templates.

Open and click tracking

  • AddedAPISends track opens and clicks per account or per send (tracking), tell people from proxies, prefetchers and scanners, and report message.opened and message.clicked events.
  • AddedAPIAn optional honeypot link catches scanners; GET .../outbox/{outboxId}/tracking lists every hit with what its request revealed.
  • AddedAPIGET /v1/accounts/{accountId}/outbox/{outboxId} reads one send.

Message priority

  • AddedAPISends and drafts take priority (high, normal, low); messages carry importance.

Contacts, meetings, threads and the SDK

  • AddedSDKThe TypeScript SDK, @workwae/sdk, typed from the API contract, with cursor and webhook helpers.
  • AddedAPIIMAP and SMTP accounts, with calendars and contacts over CalDAV and CardDAV.
  • AddedAPIContacts sync and free/busy availability (POST .../availability/find).
  • AddedAPIZoom and Webex meetings for calendar events, and onlineMeetingUrl for links from other services.
  • AddedAPIThreads, send-as identities, signatures and message.bounced events.
  • AddedAPIAn undo send window (undoSendSeconds), scheduled sends and rescheduling.
  • AddedAPIOrganization-wide connections and shared mailboxes.
  • AddedAPIMessage body storage and full-text search; data exports and account purge.
  • AddedWebhooksEndpoint filters by mailbox and message criteria; delivery log, replays and test events.

First release

  • AddedAPIThe /v1 API: hosted and headless OAuth connect for Google and Microsoft 365, mail and calendar endpoints with push intake, webhooks and the change feed.