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.

API referenceReceiving

Receiving

The mail sent to your team: the message, its attachments, its raw source, and the one call that deletes all three.

A received message is its own resource

It is never an emails row. The two have separate ID spaces and separate reads: GET /emails/{email_id} will not find a received message, and GET /emails/receiving/{email_id} will not find one you sent. Nor does POST /emails/{id}/share accept a received ID — sharing inbound mail is not something this release does, and it answers 404.

  • created_at is when the message was received, not when we wrote the record.
  • Route on received_for, the addresses of yours the message was accepted for. to is whatever the sender wrote, and a sender can write anything.
  • html and text are stored exactly as decoded and are never sanitised at rest. Sanitise before you render them.

The received figure on Metrics is the count of messages the mail provider accepted from you for sending. It has nothing to do with inbound mail.

When a message has no content

A message we accepted but would not store is still recorded, with a dropped_reason, html and text null, and no attachments. The record exists so you can tell "nothing arrived" from "something arrived and we would not keep it", which are very different problems.

Why a message was not stored
dropped_reasonMeans
storage_quotaYour mailbox was full. Delete some mail, or add storage.
daily_capYou had already received your plan's messages for the day.
virusThe message was scanned and refused. We do not store it.
parse_failedWe could not read the MIME structure. The raw source is still downloadable.
no_mailboxNo mailbox claims that address, and no catch-all is set to take it.
team_blockedSending and receiving are paused on the project. We emailed its admins why, and how to ask us to look again.

A message you keep has no retention window: it is held until you delete it, or until the mailbox is full and the next message is the one dropped. A dropped record is the exception — it ages out on your plan's data retention window, and like a deleted message it is removed whole, so it answers 404 rather than coming back emptied.

The attachments listed inside a message carry no link — minting one per part on every read of every message would be work nobody asked for. Read …/{email_id}/attachments when you want the bytes, and each part comes back with a download_url valid for fifteen minutes.

  • A part we refused to store is listed with its size and no download_url and no expires_at. Check for the field rather than assuming it.
  • A download takes no Authorization header: the signed link is the credential, so a browser can follow it without an API key ever reaching one.
  • Bytes are always served as a download, and a content type outside our allowlist — text/html and image/svg+xml among them — is handed over as application/octet-stream.

The Inbox does not move any of this

Received mail is also a conversation in the dashboard, and a member can answer it there. None of that reaches this resource: /emails/receiving keeps its paths, its shapes and its permissions, the email.received payload keeps its fields, and no thread resource was added. A reply is an ordinary send and appears on /emails like any other. Replying in the guide is the whole of it.

Endpoints

List received emails

GET /emails/receiving

Every message sent to this team, newest first.

Query parameters

  • limitinteger

    How many items to return, 1–100. Defaults to 20.

  • afterstring

    Return the page that follows this item ID. Mutually exclusive with before.

  • beforestring

    Return the page that precedes this item ID. Mutually exclusive with after.

  • searchstring

    Case-insensitive substring of the subject, the sender's address or name, or any recipient. % and _ match literally. 1–200 characters.

  • start_datestring

    ISO 8601, inclusive. Messages received before this are excluded.

  • end_datestring

    ISO 8601, inclusive. Messages received after this are excluded.

Request

curl -X GET "https://api.rasket.com/emails/receiving?limit=20" \
  -H "Authorization: Bearer $RASKET_API_KEY" \
  -H "User-Agent: acme-billing/1.0"

Response 200

{
  "object": "list",
  "has_more": false,
  "data": [
    {
      "id": "4ef9a417-02e9-4d39-ad75-9611e0fcc33c",
      "to": ["support@inbound.acme.example"],
      "from": "Ronald Williams <ronald.williams@example.com>",
      "subject": "Order #1042 arrived damaged",
      "message_id": "<CAF1042.damaged@mail.example.com>",
      "bcc": [],
      "cc": ["billing@example.com"],
      "reply_to": [],
      "dropped_reason": null,
      "created_at": "2026-09-09T10:16:44.902Z",
      "attachments": [
        {
          "id": "660e8400-e29b-41d4-a716-446655440000",
          "filename": "damage-report.pdf",
          "content_type": "application/pdf",
          "content_disposition": "attachment",
          "size": 20481
        }
      ]
    }
  ]
}
  • Cursors are received-email IDs. A row carries no html, text, headers or received_for; retrieve the message for those.
  • A message we recorded but would not store carries a dropped_reason and an empty attachments array.

Retrieve a received email

GET /emails/receiving/{email_id}

One message, with its headers, bodies and attachment list.

Path parameters

  • email_idstringRequired

    The ID of the received email.

Request

curl -X GET "https://api.rasket.com/emails/receiving/4ef9a417-02e9-4d39-ad75-9611e0fcc33c" \
  -H "Authorization: Bearer $RASKET_API_KEY" \
  -H "User-Agent: acme-billing/1.0"

Response 200

{
  "object": "email",
  "id": "4ef9a417-02e9-4d39-ad75-9611e0fcc33c",
  "to": ["support@inbound.acme.example"],
  "from": "Ronald Williams <ronald.williams@example.com>",
  "subject": "Order #1042 arrived damaged",
  "message_id": "<CAF1042.damaged@mail.example.com>",
  "bcc": [],
  "cc": ["billing@example.com"],
  "reply_to": [],
  "received_for": ["support@inbound.acme.example"],
  "html": "<p>The box was crushed on one side.</p>",
  "text": "The box was crushed on one side.",
  "headers": {
    "X-Mailer": "Apple Mail (2.3774)"
  },
  "dropped_reason": null,
  "created_at": "2026-09-09T10:16:44.902Z",
  "attachments": [
    {
      "id": "660e8400-e29b-41d4-a716-446655440000",
      "filename": "damage-report.pdf",
      "content_type": "application/pdf",
      "content_disposition": "attachment",
      "size": 20481
    }
  ]
}
  • created_at is when the message was **received**, not when we wrote the record.
  • Route on received_for — the addresses of yours the message was accepted for — rather than on to, which is whatever the sender wrote.
  • subject and message_id are empty strings when the message carried no such header.
  • html and text are never sanitised at rest. Sanitise before you render them.
  • The raw source is not included. …/raw/download serves it as a file.
  • A message you keep has no retention window; it is held until you delete it. A dropped record does age out, and like a deleted message it goes whole and answers 404 — there is no emptied record.

List the attachments of a received email

GET /emails/receiving/{email_id}/attachments

Each with a signed link to its bytes.

Path parameters

  • email_idstringRequired

    The ID of the received email.

Query parameters

  • limitinteger

    How many items to return, 1–100. Defaults to 20.

  • afterstring

    Return the page that follows this item ID. Mutually exclusive with before.

  • beforestring

    Return the page that precedes this item ID. Mutually exclusive with after.

Request

curl -X GET "https://api.rasket.com/emails/receiving/4ef9a417-02e9-4d39-ad75-9611e0fcc33c/attachments" \
  -H "Authorization: Bearer $RASKET_API_KEY" \
  -H "User-Agent: acme-billing/1.0"

Response 200

{
  "object": "list",
  "has_more": false,
  "data": [
    {
      "id": "660e8400-e29b-41d4-a716-446655440000",
      "filename": "damage-report.pdf",
      "content_type": "application/pdf",
      "content_disposition": "attachment",
      "size": 20481,
      "download_url": "https://api.rasket.com/emails/receiving/4ef9a417-02e9-4d39-ad75-9611e0fcc33c/attachments/660e8400-e29b-41d4-a716-446655440000/download?expires=1789200000&token=1f0c…",
      "expires_at": "2026-09-09T10:31:44.902Z"
    }
  ]
}
  • Cursors are attachment IDs; the page is in the order the parts appeared in the message.
  • A part we refused to store is listed with its size and **no** download_url and **no** expires_at. Check for the field before following it.
  • download_url is valid for fifteen minutes. Mint a fresh one by reading the attachment again rather than storing the link.

Retrieve one attachment of a received email

GET /emails/receiving/{email_id}/attachments/{attachment_id}

One part, with a fresh signed link.

Path parameters

  • email_idstringRequired

    The ID of the received email.

  • attachment_idstringRequired

    The ID of the attachment.

Request

curl -X GET "https://api.rasket.com/emails/receiving/4ef9a417-02e9-4d39-ad75-9611e0fcc33c/attachments/5f2c9a1b-7e3d-4c8a-9b1f-2e6d0a4c8b73" \
  -H "Authorization: Bearer $RASKET_API_KEY" \
  -H "User-Agent: acme-billing/1.0"

Response 200

{
  "object": "attachment",
  "id": "660e8400-e29b-41d4-a716-446655440000",
  "filename": "damage-report.pdf",
  "content_type": "application/pdf",
  "content_disposition": "attachment",
  "size": 20481,
  "download_url": "https://api.rasket.com/emails/receiving/4ef9a417-02e9-4d39-ad75-9611e0fcc33c/attachments/660e8400-e29b-41d4-a716-446655440000/download?expires=1789200000&token=1f0c…",
  "expires_at": "2026-09-09T10:31:44.902Z"
}
  • content_id is present only for a part that carried a Content-ID; resolve cid: references in the HTML body against it.

Download a received attachment

GET /emails/receiving/{email_id}/attachments/{attachment_id}/download

Follow the signed link and get the bytes.

Path parameters

  • email_idstringRequired

    The ID of the received email.

  • attachment_idstringRequired

    The ID of the attachment.

Query parameters

  • expiresintegerRequired

    Part of the signature. Copy the whole download_url; do not build this yourself.

  • tokenstringRequired

    The link's signature, valid for fifteen minutes and for this object only.

Request

curl -X GET "https://api.rasket.com/emails/receiving/4ef9a417-02e9-4d39-ad75-9611e0fcc33c/attachments/5f2c9a1b-7e3d-4c8a-9b1f-2e6d0a4c8b73/download?expires=1789200000&token=1f0c9d3b8a72e5461c0d" \
  -H "User-Agent: acme-billing/1.0"
  • This route takes no Authorization header: the link carries its own signed authorization so a browser can follow it.
  • A User-Agent is still required, as it is on every other route.
  • Every refusal is a 404 with the same message — a bad signature, an expired link, an object that has been deleted, an ID from another team. The link is the credential, so which one it was is not something its holder has proven they may know.
  • The response is the file itself, not JSON. It is always served as a download, and a type outside our allowlist — text/html and image/svg+xml first among them — is handed over as application/octet-stream.

Download the raw message

GET /emails/receiving/{email_id}/raw/download

The message exactly as it reached us, as `raw.eml`.

Path parameters

  • email_idstringRequired

    The ID of the received email.

Query parameters

  • expiresintegerRequired

    Part of the signature. Copy the whole download_url; do not build this yourself.

  • tokenstringRequired

    The link's signature, valid for fifteen minutes and for this object only.

Request

curl -X GET "https://api.rasket.com/emails/receiving/4ef9a417-02e9-4d39-ad75-9611e0fcc33c/raw/download?expires=1789200000&token=1f0c9d3b8a72e5461c0d" \
  -H "User-Agent: acme-billing/1.0"
  • The raw source is deliberately not part of the message body: it can be as large as the whole message, and a reader who wants it wants a file.
  • This route takes no Authorization header: the link carries its own signed authorization so a browser can follow it.
  • A User-Agent is still required, as it is on every other route.
  • Every refusal is a 404 with the same message — a bad signature, an expired link, an object that has been deleted, an ID from another team. The link is the credential, so which one it was is not something its holder has proven they may know.
  • The response is the file itself, not JSON. It is always served as a download, and a type outside our allowlist — text/html and image/svg+xml first among them — is handed over as application/octet-stream.

Delete a received email

DELETE /emails/receiving/{email_id}

Remove the message and give the storage back.

Path parameters

  • email_idstringRequired

    The ID of the received email.

Request

curl -X DELETE "https://api.rasket.com/emails/receiving/4ef9a417-02e9-4d39-ad75-9611e0fcc33c" \
  -H "Authorization: Bearer $RASKET_API_KEY" \
  -H "User-Agent: acme-billing/1.0"

Response 200

{
  "object": "email",
  "id": "4ef9a417-02e9-4d39-ad75-9611e0fcc33c",
  "deleted": true
}
  • Permanent, and there is no soft delete: the stored objects go with the record.
  • The bytes return to this team's inbox storage allowance. It is the only way to make room short of buying more.
  • This is the one receiving operation a restricted sending_access key can never reach — as, in fact, none of them can.