Skip to content
Esc
  • OverviewGuidesWhat exists today, and where to start.
  • QuickstartGuidesKey, domain, first send — in that order.
  • AuthenticationGuidesBearer keys, the mandatory User-Agent, and what each refusal means.
  • ErrorsGuidesThe whole vocabulary, with the status each name carries.
  • IdempotencyGuidesRetry a send without sending it twice.
  • PaginationGuidesCursors are item IDs, not page numbers.
  • Rate limitsGuidesTen a second per team, and the headers that tell you where you are.
  • EventsGuidesEvery event a webhook can carry, with one real payload each.
  • DomainsGuidesThe records, where they go at each registrar, and what the page does while you wait.
  • TrackingGuidesOpens and clicks: one record, two toggles, and what an open really means.
  • ReceivingGuidesInbound mail, and the Inbox: a webhook fires, you read it, you answer it.
  • InboxGuidesChannels, personal mailboxes and seats: who sees what, and where a reply goes.
  • Node SDKGuidesThe rasket package: typed from the API's own document, retries only what is safe.
  • Python SDKGuidesThe rasket package on PyPI: the Node client's methods, in snake_case, over httpx.
  • MCP serverGuidesConnect Claude, ChatGPT or any MCP client: your scopes, no key.
  • AI assistGuidesSubject lines, drafts and diagnosis — in the dashboard and over the API, off until you allow it.
  • AgentsGuidesLet an AI agent set Rasket up: the skill, the rules file, MCP, and the recipe they share.
  • OAuthGuidesLet another app act for a team: register, authorize with PKCE, exchange, refresh.
  • Single sign-onGuidesOIDC login for your team, a domain proved by DNS, enforcement and break-glass.
  • IntegrationsGuidesVercel, Netlify and Cloudflare, plus Zapier and n8n for workflows without code.
  • SMTPGuidesSend from anything that speaks SMTP: settings, setup guides, limits and replies.
  • ZapierGuidesSend email, add contacts and react to email events from a Zap, with no code.
  • n8nGuidesThe Rasket node and trigger for n8n workflows: install, connect, every operation.
  • EmailsAPI referenceSend, batch, retrieve, list, reschedule, cancel, attachments.
  • DomainsAPI referenceAdd a domain, publish its records, verify it.
  • API keysAPI referenceCreate, list, rename and revoke credentials.
  • WebhooksAPI referencePayloads, signature verification, retries and replay.
  • SuppressionsAPI referenceAddresses we will not send to, and why.
  • LogsAPI referenceEvery request made with this team's credentials.
  • MetricsAPI referenceDelivery, bounce, complaint and engagement counts.
  • TemplatesAPI referenceVersioned email content with typed variables, addressed by ID or alias.
  • ContactsAPI referenceYour audience: contacts, their typed properties, segments and topic choices.
  • SegmentsAPI referenceAudiences defined by a filter, by hand, or both.
  • TopicsAPI referenceWhat contacts subscribe to, and the preference page's list.
  • CampaignsAPI referenceCampaigns, at /broadcasts: one message to a segment, from draft to results.
  • ImportsAPI referenceCSV uploads: column mapping, conflicts and counts.
  • AutomationsAPI referenceWorkflows that run per contact: the graph, its versions, and every run.
  • Custom eventsAPI referenceThe names your product fires, and what starts a workflow.
  • ReceivingAPI referenceMail sent to you: the message, its attachments, its raw source.
  • OAuthAPI referenceClient registration, the token endpoint, and the grants a team has given.
  • TeamAPI referenceThe team a credential belongs to: its plan, sender identity, AI flag and members.
  • BillingAPI referencePlan, usage, invoices and add-ons, and the hosted pages where a customer pays.
  • AI helpersAPI referenceSubject lines, a first draft, and why an email did what it did.

GuidesReceiving

Receiving email

You do not poll for mail. A webhook fires, you read the message it names, and you delete it when you are done. This page is that loop — and the Inbox, where the same mail waits to be answered.

The loop

Subscribe a webhook to email.received, and everything else follows from the payload it delivers.

const api = (path, init = {}) =>
  fetch(`https://api.rasket.com${path}`, {
    ...init,
    headers: {
      Authorization: `Bearer ${process.env.RASKET_API_KEY}`,
      "User-Agent": "acme-billing/1.0",
    },
  });

// 1. check the signature, as with every Rasket event (see the Webhooks reference)
const event = verifySignature(rawBody, headers, process.env.RASKET_WEBHOOK_SECRET);
if (event.type !== "email.received") return;

// 2. route on what the payload already carries — no call needed
const queue = event.data.received_for.includes("billing@inbound.acme.example")
  ? "billing"
  : "support";

// 3. read the parts the payload deliberately leaves out
const id = event.data.email_id;
const message = await (await api(`/emails/receiving/${id}`)).json();
const files = await (await api(`/emails/receiving/${id}/attachments`)).json();

// 4. each part carries a fresh signed link, good for fifteen minutes
for (const file of files.data) {
  if (file.download_url === undefined) continue; // a part we would not store
  await archive(file.filename, await fetch(file.download_url));
}

// 5. give the storage back
await api(`/emails/receiving/${id}`, { method: "DELETE" });

Your Inbox

The same mail is waiting for you in your Inbox, the mail app behind the envelope in the dashboard’s top bar. Messages that answer each other are one conversation: we thread on the In-Reply-To and References headers a mail client sets, and never on the subject line, so two strangers who both write "Invoice" do not land in the same place. A message we accepted but would not store is threaded too, marked with the reason.

A conversation holds both halves — what arrived and what you sent back — and lives as long as the mail it is made of. Delete the last message and the conversation goes with it.

Only the screen was renamed. The API path /emails/receiving is unchanged, and so is every field on it.

Replying

You reply from the same name on your sending domain. A message to support@inbound.acme.example is answered as support@acme.example — the address the person already knows, and the one their mail client can line up with your DNS.

So replying needs a domain you have verified for sending. Your managed receiving address is ours rather than yours, and its reputation is shared, so it receives and never sends. A team that has verified nothing sees the composer switched off and Add a domain to reply in its place; the Domains reference is the path out of that.

Where the next message lands
Mail arrived atYour reply goes out asTheir answer comes back to
support@acme.example, receiving at the domain itselfAcme Support <support@acme.example>The same address. There is nothing separate to show you.
support@inbound.acme.example, receiving at a labelAcme Support <support@acme.example>support@inbound.acme.example
Your managed receiving addresssupport@ one of your verified sending domainsThat domain's own receiving address, if it has one.

The From picker offers any name you have saved at any of your verified sending domains, and nothing else — never an unverified domain, and never the managed address. When the address you pick answers somewhere else, the composer says so underneath it — Replies will go to support@acme.example — so you can answer as sam@acme.example and still have the next message land in support. A reply-to must be an address on a host you receive on; anything else is refused, because a reply-to nobody can answer is worse than none.

  • One Re:, never a stack of them, and we set the headers that keep your answer inside the conversation on their side as well.
  • Reply, reply to everyone, forward, or start something new. All four are in the inbox app — see Inbox.
  • A reply can carry files. Up to ten of them, alongside your text, your mailbox's signature if it has one, and the message you are answering, quoted.

If the domain you reply from does not receive mail and we have no arrival address to fall back on, the reply goes out with no separate replies-go-to at all — so the answer is sent to a domain we do not receive on, and you never see it. Turn receiving on for that domain.

Why the payload is small

The event carries the envelope and the attachment list, and nothing else. That is a decision rather than an omission, and each half of it has a reason worth knowing:

  • No bodies. A webhook is retried until your endpoint accepts it, ten attempts over about sixteen hours. A body that was retried for hours is hours of duplicated content arriving at your endpoint, for a message you may not even want.
  • No download links. A link lives fifteen minutes. One minted at delivery would be dead by the time a retry succeeded, which is a worse failure than no link at all — it looks like it should work.
  • Enough to route. received_for, from, subject and the attachment list are all there, so the common case needs no call.

Route on received_for — the addresses of yours the message was accepted for — and not on to, which is whatever the sender wrote in the header.

Before the loop can run

Be reachable. There are two ways, and they differ only in which address people write to; everything downstream is identical.

  • Your own domain. Turn receiving on for a verified domain in an inbound-capable region and publish the one MX record we hand back. It sits at the domain itself unless you choose otherwise, so anything@acme.example lands with us — but that MX takes the domain's mail from whichever mailbox provider has it today, so set receiving_host to a label such as inbound if another provider already receives for it. anything@inbound.acme.example then lands in the same place. We check first: turning receiving on at a name whose MX already points at another mailbox provider is refused with 409 receiving_mx_in_use, naming that provider, until you choose a subdomain or send confirm_replace_mx: true.
  • The address you already have. Every team is assigned a managed receiving address — anything@<word>.<our host> — when it is created. Anything before the @ reaches you, so you can tag threads without registering anything. It is shown while no domain of yours is verified for receiving; mail sent there still arrives after one is.

Receiving is available in two regions, United States (N. Virginia) and Ireland (Dublin). A verified domain outside them cannot receive at all, and its domain page says so in place of an address rather than offering a toggle that would do nothing.

An address on your domain that no mailbox claims reaches you only if you have marked one of your mailboxes as the catch-all. Mark one and everything unclaimed lands there, so a customer writing to a name you never set up is not silently lost. With none marked, or with unclaimed addresses switched off, that mail is recorded as not delivered and nothing is stored. Inbox has the whole of it, along with who on your team can read which address.

A message larger than 40 MB, attachments included, is refused before it reaches us, so there is no event and no record. We do not hold it, and we do not truncate it.

When the loop gets something odd

A message we accepted but would not store is still recorded, with its bodies null and no attachments, so that "nothing arrived" and "something arrived and we would not keep it" are never the same silence.

Unusual received messages
You seeIt means
dropped_reason: "virus"Scanned and refused. The envelope is kept, the content is not.
dropped_reason: "storage_quota"Your mailbox was full. Delete some mail, or add storage.
dropped_reason: "daily_cap"You had already received your plan's messages for the day.
dropped_reason: "parse_failed"We could not read the MIME structure. The raw source is still downloadable.
dropped_reason: "no_mailbox"No mailbox claims that address, and no catch-all is set to take it.
dropped_reason: "team_blocked"Your account is blocked, so mail is recorded but not stored until that is resolved.
404You deleted the message, a dropped record aged out, or it was never this team's. They are deliberately indistinguishable.

Storage, and getting it back

Your mail is kept until the mailbox is full. There is no retention window on a message you keep: it stays until you delete it. What bounds it is an allowance in bytes, and a daily message cap alongside it. With the mailbox full, the next message is recorded with a dropped_reason rather than stored — never an older one thrown away — so the loop keeps running and you find out from the payload.

What each plan's mailbox holds
PlanInbox storage
Free3 GB
Pro8 GB
Scale15 GB
Enterprise40 GB

Another 100 GB is $15 a month on any plan, the free one included. Add it with POST /billing/addons; it is billed on your subscription and the allowance applies at once.

Every open mailbox adds 5 GB on top, shared or personal, the ones your plan includes included — and 15 GB each once you have more mailboxes than your plan includes. Open another and the allowance goes up with it; close one and it goes back down. Extra addresses on a mailbox add nothing, because they are the same mailbox. Nothing to buy separately — it is the same single allowance the table above shows.

When your inbox reaches 80% of its storage, and again when it is full, the team's admins get an email. One per crossing, and never a second inside 30 days.

DELETE /emails/receiving/{email_id} is how the room comes back. It removes the stored objects as well as the record and returns the bytes to your allowance; there is no undo and no soft delete. A dropped record is the one thing that does age out, on your plan's data retention window — and like a deleted message it goes whole, so it answers 404 rather than coming back with an empty body.

Route API replies into your Inbox

An email you send over the API can be answered in the Inbox like any other conversation. Set reply_to to a name at an address you receive on, and the answer arrives somewhere we can see it.

Routing an API reply by receiving host
You receive atSet on the send
the domain itselfNothing. Your From address already receives.
a label, such as inbound.acme.examplereply_to: "orders@inbound.acme.example"
only your managed receiving addressNothing you can set: it is not an address you send from.

Arriving is all reply_to does. What puts the answer on the right conversation is the In-Reply-To it carries, pointing back at the message you sent — so a reply_to at an address we do not receive on threads nothing, because the answer never reaches us at all.

What a reply costs

A reply is an email. It goes out through the pipeline POST /emails uses, on the transactional meter, and counts as one message on your plan: a thousand replies are a thousand emails.

What a reply counts against
LimitA reply
Your plan's monthly transactional allowanceCounts it. One message, like any other.
Your daily send capCounts it.
Your suppression listApplies. A suppressed address is not written to.
The verified-domain ruleApplies. There is no second send path that skips it.
Ten requests a second, per teamApplies, as it does to a send you make yourself.
Sixty replies an hour, per memberOnly here — a guard against a stuck composer, not a ration on your plan.
A daily ceiling per personal mailboxOnly for mail you send from your own address: 100 a day, or 500 once your account has a payment method. Nothing else counts it.

There is one edge worth knowing before you meet it: a reply whose every recipient is on your suppression list is refused after the message has been counted. The composer checks suppression before it lets you type, so this only happens to an address suppressed in the seconds between.

What you have sent and what your plan allows are on the dashboard's Usage screen, beside every other send.

Mail you send from your own address rather than a shared one is not on that meter at all. You are paying for the seat, not for the message, so a personal mailbox draws on neither your monthly allowance nor your daily cap — it has a daily ceiling of its own: a hundred messages, or five hundred once your account has a payment method. Reaching it is a sign something is sending on your behalf, not a sign you should buy more.

What a personal send counts against
LimitA message from your own mailbox
Your plan's monthly allowanceDoes not count it.
Your daily send capDoes not count it.
100 a day per mailbox, 500 with a payment method on your accountThe whole of what bounds it.
Your suppression listApplies. A hard bounce or a complaint still stops a message.
Someone who unsubscribedStill hears from you. Leaving a mailing list is not asking a person to stop writing back.

Write to someone from your own address on a shared conversation and their answer still comes back to the shared mailbox, not to you. That is deliberate: the conversation is the team's, so whoever picks it up next finds the whole of it — including on the days you are away.

Where to go next

  • The Receiving reference — all seven operations, with the shape of every response.
  • Events — the email.received payload in full, beside every other event.
  • Domains — turning receiving on, and verifying the sending domain a reply needs.