Changelog

User-visible changes to the API, webhooks and the SDK, newest first.

Each release lists its changes as Breaking, Added, Changed or Fixed, and the area they affect: API, Webhooks or SDK. Releases with breaking changes end with migration steps. Every operation is in the API reference.

Scheduling links, folder and calendar management, and on-demand sync

October 17, 2026

  • Added, API. Scheduling links:
    • POST /v1/scheduling-links stores a bookable configuration: accounts, all or round-robin any mode, duration, working hours, buffers, notice and a daily cap.
    • GET /v1/scheduling-links/{linkId}/slots returns open slots.
    • POST /v1/scheduling-links/{linkId}/bookings re-checks availability, creates the event and answers 409 slot_taken when the slot is gone.
    • DELETE /v1/bookings/{bookingId} cancels a booking.
  • Added, Webhooks. booking.created and booking.cancelled events.
  • Added, API. POST /v1/availability/find finds free time across several accounts: slots where all of them are free or, with mode any, which of them are free per slot.
  • Added, API. Availability answers say whether every attendee was read: complete and unresolved. With requireAll: true, no slots are suggested while an attendee is unresolved.
  • Added, API. Create, rename, move and delete mailboxes (POST, PATCH, DELETE /v1/accounts/{accountId}/mailboxes) on Microsoft 365, Gmail (labels) and IMAP, and calendars (/v1/accounts/{accountId}/calendars) on Microsoft 365, Google and CalDAV. System folders answer mailbox_protected and the primary calendar calendar_primary.
  • Added, API. POST /v1/accounts/{accountId}/sync starts a sync pass now for mail, calendar or contacts, limited per account per minute.
  • Changed, API. The API reference shows each operation's required scope, and SDK samples for deletes with options pass { params, query }.
  • Fixed, API. A contact birthday accepts --MM-DD for a birthday without a year, as documented.

MCP server and account-scoped API keys

October 17, 2026

  • Breaking, API. MCP tools renamed or removed:
    • list_messages is now search_messages (q optional).
    • update_message and update_thread are mark_messages (read, flagged) and move_messages (mailbox, Gmail labels).
    • trash_thread is move_messages with to: "trash".
    • list_contacts and get_contact are search_contacts.
    • list_identities is gone; list_accounts lists each account's send-as addresses.
  • Breaking, API. MCP tool arguments changed:
    • create_draft, update_draft and send_message take body and format (text or html) instead of text and html.
    • create_event takes meeting ({ provider: teams | meet | zoom | webex } or { url }) instead of onlineMeeting, onlineMeetingService and onlineMeetingUrl.
    • update_event takes meeting: { url } or null.
  • Breaking, API. The MCP send policy's mode defaults to confirm instead of allow: a workspace that never set one has the user confirm every agent send, in a form or the review card. Clients that can do neither, and backend API keys, get send_policy_refused with rule confirm until an admin sets mode: allow. A mode already saved is unchanged.
  • Added, API. An MCP server at /mcp with mail, calendar and contacts tools for agents.
    • Clients connect with an API key, whose scopes decide the tools they see, or with OAuth, where the user picks a workspace, scopes and accounts in the console.
    • Tools take an account's id or its email address as accountId.
    • Every tool call is recorded in the audit log under the surface mcp.
  • Added, API. OAuth for MCP clients:
    • Open client registration (POST /api/auth/oauth2/register) takes 10 registrations per 10 minutes from one client address; past that it answers 429 with Retry-After and the OAuth error temporarily_unavailable.
    • A client that registered itself or was read from a client ID metadata document, and that no user ever consented to, is deleted after 7 days.
    • Granting a workspace no longer switches the console to it.
    • Owners and admins can see and revoke every member's connected apps under Settings.
  • Added, API. API keys can be limited to specific accounts (accountIds). Such a key reaches only those accounts' operations, GET /v1/accounts and GET /v1/changes return only those accounts and their events, and anything tenant-wide answers the new reason account_scope_forbidden (403).
  • Added, API. A developer toolset at /mcp/developer for coding agents working on an integration: accounts' sync health, webhook endpoints, the delivery log, failed delivery counts, test events and replays, hosted connect links, the change feed, usage, the audit log, and a search of the API reference. It takes API keys only; other bearer tokens answer the new reason api_key_required (403), and MCP keys minted for an account mcp_only_key (403).
  • Added, API. MCP keys for your users:
    • POST /v1/accounts/{accountId}/mcp-keys mints a key for one account with read, write or send (never admin), returned once. GET lists them and DELETE /v1/accounts/{accountId}/mcp-keys/{keyId} revokes one; deleting the account revokes its keys.
    • Such a key works only at /mcp; anywhere else it answers the new reason mcp_only_key (403).
    • An account holds at most 25 live keys (mcp_key_limit, 409).
    • POST /v1/connect-sessions takes mcp: { scopes, name? } to mint a key when the session connects an account and show it once to the person who connected it, on a Workwae page with setup steps for MCP clients. GET /v1/connect-sessions/{sessionId} names it as mcpKeyId, or answers mcpKeySkipped: "mcp_key_limit" when the account was already at the cap and got no key.
  • Added, API. MCP mail tools:
    • search_messages filters by from, to, unread, flagged, hasAttachments, after, before and mailbox (an id or a role such as inbox), with detail brief or full and 20 a page.
    • get_message and get_thread leave out quoted history unless quoted: true; get_thread returns bodies (bodies: latest, all or none).
    • mark_messages and move_messages take up to 50 ids or a thread.
    • Drafts and sends take reply: { messageId, mode } (reply, replyAll, forward), the server filling in recipients, subject, threading and the quote, and attachments by reference ({ fromMessageId, attachmentId }).
  • Added, API. MCP calendar and account tools:
    • Times show in the account's calendar zone or timeZone.
    • list_events takes q and detail and defaults to the next 90 days; create_event defaults to the primary calendar.
    • list_accounts shows each account's zone, capabilities and send-as addresses.
    • connect_account returns a hosted connect link for another mailbox (as URL elicitation where the client supports it).
    • get_current_time takes accountId, else answers in the zone the credential's accounts' calendars share.
    • accountId may be left out where a message id names the account, and for calendar and contacts tools when only one account syncs them; a refusal for a missing one names the accounts.
  • Added, API. Safe MCP sends: on 2026-07-28 clients that support forms, send_message and send_draft ask the user to confirm first, and a declined or cancelled form sends nothing (a cancel points the model to create_draft). An identical send within 10 minutes answers duplicate_send unless allowDuplicate: true. Sends, update_draft, cancel_send, update_event and update_contact are annotated destructive.
  • Added, API. An MCP send policy, mcpSendPolicy in GET/PATCH /v1/settings and under Settings, Agents (MCP):
    • mode: allow, confirm or drafts_only.
    • allowedRecipientDomains, where the account's own domain counts unless it is a public mailbox provider such as gmail.com.
    • dailySendLimit per credential per UTC day.
    • externalRecipientConfirmation, for addresses the account has never sent to.
    • Refused sends answer send_policy_refused with the rule. POST /v1/accounts/{accountId}/mcp-keys takes sendPolicy, which only tightens the workspace's. /v1 sends are unaffected.
  • Added, API. MCP calendar writes that email anyone outside the account (create_event, update_event, delete_event notifying attendees, respond_to_event telling the organizer or with a comment) are sends: they need the send scope (else missing_scope; pass notify: false), follow the send policy and its confirmation, and count toward the daily limit. On Microsoft 365 an organizer's changes always notify.
  • Added, API. MCP Apps:
    • preview_message shows a message as it would go out in a review card: an HTML body rendered as mail clients do but without remote content, followed by its link targets and remote hosts. The card's Send commits exactly that message (commit_message, single use within 10 minutes; the proposalId goes only to the card).
    • Send counts as the user's confirmation only when the preview and the commit come from a 2026-07-28 client declaring the extension; policy confirmations still ask where the client supports forms.
    • pick_meeting_time shows free slots in a picker.
    • New reasons proposal_not_found and proposal_changed.
  • Added, API. MCP Events for 2026-07-28 clients (events/list, events/subscribe, events/unsubscribe):
    • mail.message_received, mail.reply_received and calendar.event_changed, delivered as signed webhooks carrying ids, the account, the sender's address and times, never subjects or bodies.
    • Subscriptions last 24 hours by default (at most 30 days), at most 20 per credential.
    • Callback verification is limited to 10 attempts per credential and 20 per host every 10 minutes, and a failed host is refused for 10 minutes.
    • Queued deliveries stop once a subscription ends or its credential loses the account.
  • Added, API. MCP prompts triage_inbox, draft_reply, schedule_meeting, weekly_agenda and summarize_thread; server cards at /mcp/server-card and /mcp/developer/server-card; and an AI catalog at /.well-known/ai-catalog.json. A tool call needing a scope an OAuth grant lacks answers 403 insufficient_scope naming every scope needed, so the client can ask for them.
  • Added, API. GET /v1/accounts/{accountId}/messages takes from, to, flagged, hasAttachments, after and before (invalid_range when before is not after after). GET /v1/accounts/{accountId}/search/messages takes from, to, unread, flagged and hasAttachments.
  • Changed, API. MCP results with mail, calendar or contact text return it only as fenced text, without structuredContent. Other results carry compact structuredContent, their summary included as summary, and the same as text. Invisible Unicode (tag characters, bidi controls, zero-width characters, lone surrogates) is stripped from third-party text and from outgoing mail, its recipient names and attachment filenames included.

Migrating

  1. MCP: replace list_messages with search_messages, update_message/update_thread with mark_messages or move_messages, trash_thread with move_messages (to: "trash"), list_contacts/get_contact with search_contacts and list_identities with list_accounts.
  2. MCP: pass body and format instead of text/html to create_draft, update_draft and send_message, and meeting instead of onlineMeeting* to create_event and update_event.

Request ids, idempotency keys and the SDK alpha

October 17, 2026 · SDK 0.1.0-alpha.1

  • Added, API. Every answer carries X-Request-Id; send your own to have it echoed. Audit log entries record it.
  • Added, API. Idempotency-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.
  • Added, API. RateLimit-Limit, RateLimit-Remaining and RateLimit-Reset headers on rate-limited calls.
  • Added, API. API keys can expire, and can be renamed, rescoped and rotated with a grace period in the console. A request with an expired key answers 401 with the new reason api_key_expired.
  • Added, Webhooks. Secret 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.
  • Added, Webhooks. POST /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. See webhook delivery.
  • Added, SDK. @workwae/sdk 0.1.0-alpha.1, an alpha whose API may still change: errors expose requestId, and every POST sends an Idempotency-Key that is reused across the SDK's own retries (or pass context.idempotencyKey).

Consistent /v1 paths, errors, lists and event types

October 16, 2026

  • Breaking, API. Paths 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/*.
  • Breaking, API. Error 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.
  • Breaking, API. Listings answer { items, nextCursor } pages or, for small bounded lists, { items }. Creates answer 201, deletes 204, accepted work 202.
  • Breaking, API. DELETE operations take their options in the query string, not a body.
  • Breaking, Webhooks. Event types were renamed (calendar_event.*, suppression.created), and webhooks and GET /v1/changes share one event envelope with typed data per event type.
  • Breaking, SDK. The 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).
  • Added, API. Every schema is a named component of the OpenAPI document (/v1/openapi.json), and every operation lists the reasons it can answer with.
  • Changed, API. Deleting an account or a tenant revokes its Google grant.
  • Changed, API. When 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

October 15, 2026

  • Added, API. Manage suppression lists (/v1/suppressions) and review opt-outs detected in replies (/v1/suppression-reviews).
  • Added, API. POST /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.
  • Added, API. GET /readyz reports whether the API can serve requests; /healthz turns 503 while the API is shutting down.
  • Added, API. A connect session without a redirectUri ends on a Workwae outcome page.
  • Added, API. Plans have modules (calendar, contacts, tracking, AI, meetings, shared mailboxes): a module outside the tenant's plan answers 403 plan_module_unavailable.
  • Added, Webhooks. Webhook tester inboxes in the console capture deliveries for inspection.
  • Changed, Webhooks. New webhook endpoints must use https.
  • Changed, Webhooks. An endpoint answering 429 or 503 is backed off politely, honoring Retry-After, without counting against its failure streak.
  • Fixed, API. A send whose SMTP reply was lost after the message was handed over fails with outcome_unknown instead of being sent again.
  • Fixed, SDK. Webhook verification computes the signature once and checks at most 8 candidate signatures.

List unsubscribe, Markdown templates and search

October 14, 2026

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

Templates and mail merge

October 13, 2026

  • Added, API. Stored Handlebars templates (/v1/templates), previews (POST /v1/template-renders), and template plus render.params on sends and drafts.
  • Added, API. Mail merges: POST /v1/accounts/{accountId}/mail-merges sends one message per recipient, each with its own params, events and tracking.

Open and click tracking

October 12, 2026

  • Added, API. Sends 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.
  • Added, API. An optional honeypot link catches scanners; GET /v1/accounts/{accountId}/outbox/{outboxId}/tracking lists every hit with what its request revealed.
  • Added, API. GET /v1/accounts/{accountId}/outbox/{outboxId} reads one send.

Message priority

October 10, 2026

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

Contacts, meetings, threads and the SDK

October 9, 2026

  • Added, API. IMAP and SMTP accounts, with calendars and contacts over CalDAV and CardDAV.
  • Added, API. Contacts sync and free/busy availability (POST /v1/accounts/{accountId}/availability/find).
  • Added, API. Zoom and Webex meetings for calendar events, and onlineMeetingUrl for links from other services.
  • Added, API. Threads, send-as identities, signatures and message.bounced events.
  • Added, API. An undo send window (undoSendSeconds), scheduled sends and rescheduling.
  • Added, API. Organization-wide connections and shared mailboxes.
  • Added, API. Message body storage and full-text search; data exports and account purge.
  • Added, Webhooks. Endpoint filters by mailbox and message criteria; delivery log, replays and test events.
  • Added, SDK. The TypeScript SDK, @workwae/sdk, typed from the API contract, with cursor and webhook helpers.

First release: the /v1 API

October 8, 2026

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

On this page