What you can do
Rolling out.
GET /v1/mailboxes is live now. The rest are shipping
shortly — until they land, a call may answer 404. Nothing about the request
or response shapes below will change when they do.Base URL
Authentication
Send your key as a bearer token:rk_, and the full key is shown exactly once, in the dialog that creates
it. Ruber stores only a SHA-256 hash — we cannot show it to you again, and we
cannot recover it. If a key is lost, revoke it and create another.
Every authentication failure looks the same
A missing header, a malformed header, a key that never existed and a key you revoked all answer the same401 with the same sentence. That is deliberate:
distinguishing them would let someone holding a list of guesses learn which
ones are real keys that happen to be revoked.
A missing permission is different, and is deliberately specific — see below.
Permissions
Every key carries a set of permissions, and a key can only do what you granted it when you created it. There is no “full access” key, noadmin, and no
wildcard. Permissions cannot be changed after creation — to change what a
key may do, create a new one and revoke the old.
When you create a key you choose one level per resource:
Two things about that table are worth reading twice.
Write includes Read. Choosing Write on a resource grants its read scope
too. A key that may move a message between folders but cannot see which folder
it is in describes no real integration.
Sending is its own resource.
messages:write covers changing mail that
already exists — marking it read, starring it, filing it. It does not let a
key send anything. Sending creates mail that leaves under your domain’s
reputation and spends your plan’s daily allowance, so it is a separate,
deliberate choice.
When a key lacks a permission
You get a403 that names exactly what was missing, because by then the caller
has proved they hold a real key and there is nothing left to protect:
Private mailboxes are not readable
A Private mailbox is encrypted to a key held only in its owner’s browser. Ruber holds no copy, so there is nothing the API could return but ciphertext and nothing it could send. Private mailboxes do appear inGET /v1/mailboxes, with
"mode": "private" — hiding them would make an integration report a mailbox as
missing when it simply cannot be read by anyone but its owner. Any endpoint that
takes an address will refuse a Private one with invalid_request and say why.
Smart mailboxes work normally.
Errors
Every error has the same shape. Thecode is stable and is what your software
should branch on; the message is written for a human reading a log and may be
reworded at any time.
404 does not mean “does not exist”. A mailbox belonging to another
organization and a mailbox that was never created both answer not_found.
Telling them apart would turn the API into a way to test whether an address
exists on the platform, one guess at a time.Rate limits
Requests are limited per key, at 600 per minute. That is ten a second sustained — comfortably above any integration doing real work. Going over returns429 with a Retry-After header giving the seconds to wait.
There is no lockout: a client that misjudges its own rate recovers on the next
window.
quota_exceeded, not rate_limited.
Caching
Every response carriesCache-Control: no-store. Responses are scoped to one
organization’s mail, and a shared cache keyed on the URL alone would serve one
customer’s inbox to another. Do not cache these responses in shared
infrastructure.