Authentication
A bearer token in one header, a User-Agent in another. Both are required on every request.
Where to send requests
https://api.rasket.comHTTPS only. Until that hostname is attached to the deployment, the identical routes answer on the deployment's own host with the /api/v1 prefix written out — that fallback is what works today:
https://<deployment-host>/api/v1The key
Send your API key as a bearer token. Tokens start with rk_.
Authorization: Bearer rk_live_2f7a9c1d8e3b5074a6c2f019d4b83e5aA key belongs to exactly one team and can reach nothing outside it. It can also be narrowed further — see API keys for the two permissions and for restricting a key to a single domain.
Never call this API from a browser. A key in client-side code is a key you have published. Send from your server, and let your server hold the credential.
OAuth access tokens
An app a team has connected through OAuth holds a second kind of bearer credential: an access token starting rko_. It goes in the same header as a key and belongs to one team in the same way, but it is authorised by the scopes the team approved rather than by a key's permission — and no scope reaches API keys, the member list, a billing change or the OAuth grants.
- An expired or revoked token is
401 missing_api_key, withWWW-Authenticate: Bearer realm="rasket", error="invalid_token", resource_metadata="…/.well-known/oauth-protected-resource". - A route the token's scopes do not reach is
403 invalid_permission, withWWW-Authenticate: Bearer error="insufficient_scope"and ascope=naming the one needed — left out where no scope would do. - An
rk_key is refused by the MCP endpoint, which takes OAuth tokens only.
Scopes
A token carries some of these 28 scopes, in this order — the order the consent page lists them in. A full_access key reaches everything a scope reaches.
| Scope | What it reaches |
|---|---|
emails:send | Send an email or a batch. |
emails:read | Retrieve, list, update and cancel sent email; attachments, shares and metrics; read received mail. |
domains:read | Every read under /domains. |
domains:write | Add, verify, update and delete a domain. |
templates:read | Retrieve and list templates. |
templates:write | Create, update, publish, duplicate and delete templates. |
contacts:read | Retrieve and list contacts, contact properties and imports. |
contacts:write | Create, update and delete contacts and their properties. |
segments:read | Retrieve and list segments and their members. |
segments:write | Create, update and delete segments; add and remove members. |
topics:read | Retrieve and list topics. |
topics:write | Create, update and delete topics. |
broadcasts:read | Retrieve and list broadcasts and their reports. |
broadcasts:write | Create, update, send, cancel and delete broadcasts. |
suppressions:read | Retrieve and list suppressions. |
suppressions:write | Add, remove and batch-change suppressions. Reading them needs suppressions:read. |
webhooks:read | Retrieve and list webhooks, the events delivered to them and the events parked while one was off. |
webhooks:write | Create, update, rotate and delete webhooks; replay an event and deliver a parked backlog. Reading them needs webhooks:read. |
logs:read | Retrieve and list request logs. |
automations:read | Retrieve and list automations, their versions and their runs. |
automations:write | Create, update, publish, duplicate, stop and delete automations. |
events:read | Retrieve and list custom event definitions. |
events:write | Create, update and delete custom event definitions. |
events:send | Send a custom event, which can start an automation. |
team:read | Read the team: its plan and limits, sender identity, AI assist and SSO summary. |
team:write | Change the team's sender identity, and turn AI assist on or off. |
billing:read | Read the plan, usage, add-ons and invoices. |
ai:use | Suggest subject lines, draft a body and diagnose an email with AI assist, spending the team's AI credits. |
No scope maps to eight permission groups, so no grant of scopes ever unlocks them: api_keys, team, members, billing, operator, oauth_grants, mcp and emails. These are group names, not scopes — team is the dashboard session's own surface, members the member list, billing every billing change, emails deleting received mail, and mcp the MCP endpoint, where each tool asks for its own scope.
Every operation in the OpenAPI document carries x-rasket-permission — the weakest key permission that reaches it — and x-rasket-scope — the scope a token needs, or null — both generated from the route's own authorization, so they cannot disagree with what the API enforces.
The User-Agent
A User-Agent header is mandatory on every request. Missing or empty, the request is refused before any authentication work happens:
HTTP/1.1 403 Forbidden
{
"statusCode": 403,
"name": "validation_error",
"message": "Missing User-Agent header.",
"code": 1010
}code: 1010 appears on this response and on no other, so you can match it exactly. Name your client something identifiable — acme-billing/1.0 is the shape we use in every example — because when something is wrong with your traffic, that string is how we find you.
- Most HTTP clients set a
User-Agentby default. Some, including barefetchin certain runtimes, do not. - In a browser the header is set by the browser and cannot be overridden — one more reason the call belongs on your server.
A complete request
curl -X GET "https://api.rasket.com/domains" \
-H "Authorization: Bearer $RASKET_API_KEY" \
-H "User-Agent: acme-billing/1.0"const response = await fetch("https://api.rasket.com/domains", {
method: "GET",
headers: {
Authorization: `Bearer ${process.env.RASKET_API_KEY}`,
"User-Agent": "acme-billing/1.0",
},
});
const data = await response.json();import os
import requests
response = requests.get(
"https://api.rasket.com/domains",
headers={
"Authorization": f"Bearer {os.environ['RASKET_API_KEY']}",
"User-Agent": "acme-billing/1.0",
},
)
print(response.json())What each refusal means
| When | Status | name |
|---|---|---|
| No Authorization header, a malformed one, or a token we do not recognise | 401 | missing_api_key |
| A sending_access key on an endpoint that is not sending | 401 | restricted_api_key |
| The key has been revoked | 403 | restricted_api_key |
| The key or the team is suspended | 403 | suspended_api_key |
| The key lacks a scope this endpoint needs | 403 | invalid_permission |
| Sending from a domain this key is not allowed to use, or one that is not verified | 403 | validation_error |
| No User-Agent header | 403 | validation_error |
restricted_api_key deliberately appears at both 401 and 403: 401 means this kind of key cannot reach this endpoint, 403 means this key is no longer active. The full vocabulary is on the errors page.