Skip to main content
Every request carries a bearer token:
A missing or unrecognised token returns 401 unauthorized. A valid token that does not cover the inbox you asked for returns 404 not found — deliberately, so a scoped key cannot probe which addresses exist on the service. Two kinds of token work here.

Your Waterr developer key

If you already have a wai_ key for the Waterr platform API, it works here too. Nothing to provision:
The key is scoped to your workspace. The first time you use it, a mailbox namespace is created for that workspace automatically, and every inbox you create lands inside it. You see your own inboxes and nobody else’s — a request for an address outside your workspace returns 404, exactly as if it did not exist. Teammates share it. Anyone with a wai_ key in the same organization reaches the same inboxes, the same way they already share scenarios and personas in Studio.
A wai_ key cannot reach the key-management endpoints (/v0/api-keys), which stay admin-only. Everything else — inboxes, messages, threads, drafts, events, lists — is available to it.

Native mailbox keys

aik_ keys are issued by this service and are the right choice when you want scoping narrower than a whole workspace — a key that reaches exactly one inbox, for example, so a single agent cannot touch the others. Agent Mailbox is in limited access while outbound deliverability is being hardened, so these are issued per account rather than self-serve.

Request access

Tell us what you are building and roughly what volume you expect, and we will provision a key and the inboxes to go with it.

Key scopes

There are three kinds of principal.

Waterr developer key

A wai_ key, resolved against your Waterr account on each use and scoped to that account’s workspace. It carries no inbox list of its own — the workspace is the boundary, so inboxes you create later are covered without re-issuing anything. Revoking the key in the Waterr dashboard revokes it here. Allow up to a minute for that to take effect, since resolved identities are cached briefly.

Admin key

The service-wide key. It reaches every inbox, every pod, and the key-management endpoints themselves. Use it from your backend for provisioning; do not hand it to an agent.

Scoped key

Created through POST /v0/api-keys, and constrained at creation time:
Response
The api_key value is returned once, at creation. It is not retrievable afterwards — GET /v0/api-keys lists metadata only. Store it before you close the response.
An empty inbox_ids means every inbox, not no inboxes. Be deliberate: a key created without it can read every conversation in the service.

Scope is enforced everywhere

A scoped key cannot widen itself. This matters most on the two surfaces where it would be easy to miss:
  • Webhooks created with a scoped key are automatically narrowed to that key’s inboxes, even if the request asks for more.
  • WebSocket subscriptions are filtered against the key’s scope at subscribe time. Asking for an out-of-scope inbox returns an error frame rather than silently widening the stream.

WebSocket authentication

Browsers cannot set headers on a WebSocket, so the socket endpoints also accept the key as a query parameter:
This is permitted on /ws routes and nowhere else, because query strings are recorded in access logs and proxy traces. Prefer the Authorization header wherever your client can send one, and treat any key that has travelled in a URL as lower-trust.

Rate limiting

Requests are limited per key at 300 requests per 60 seconds. Exceeding it returns 429 rate_limited with a Retry-After: 60 header. Because the limit is per key rather than per account, giving each agent its own scoped key also stops one busy agent from throttling the others.

Revoking

Revocation takes effect on the next request. Rotate by creating the replacement first, moving the agent over, then deleting the old key.