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 referenceCustom events

Custom events

The things that happen in your product — a trial started, a plan upgraded. You declare the name once, fire it against a contact, and an automation triggering on that name enrols them.

Definitions and sends

A definition is a name your team owns, created with POST /events and addressed afterwards by ID or by that name. A send is one occurrence: POST /events/send records it against exactly one contact and enrols them into every enabled automation whose trigger names it.

The two are separately permissioned on purpose. Declaring, listing, changing and deleting a definition needs a full-access key. Sending accepts a key restricted to sending as well, because firing an event is how an integration starts a workflow and is no more powerful than POST /emails — so a key you gave your billing service can report that a trial started without also being able to invent event names or read the ones you have.

Names

Lower-case letters, digits, ., _ and -, starting with a letter, at most 100 characters, and unique among your live definitions. A name can never be shaped like a UUID, which is what lets {identifier} take either without ambiguity.

The rasket: prefix is reserved for the platform's own triggers — rasket:contact.created, rasket:topic.subscribed, the rasket:email.* family and rasket:segment.entered. You can trigger an automation on those; you cannot declare one. A name carrying the prefix is 422 validation_error.

Deleting a definition is soft and frees the name. An automation version still naming it simply never fires again.

Payloads

A send may carry a payload of key/value pairs, at most 16 KB of JSON. When the definition declares a schema, every declared key present in the payload has to be its type; a declared key that is absent or null passes, and undeclared keys pass untouched.

Event schema types
TypeAccepts
stringAny string.
numberA finite JSON number.
booleantrue or false.
dateAn ISO 8601 calendar date (2026-09-11) or a zoned instant (2026-09-11T12:00:00Z) naming a day that exists.

A value that disagrees is 422 validation_error, with one entry in errors[] per key so you can see all of them at once. A PATCH replaces the schema rather than merging into it.

What a send guarantees

  • 202, not 200: the event is durable the moment the call returns, and the runs it enrols start on the next tick.
  • There is no Idempotency-Key here. Two calls are two events and two runs — retry only a call that never answered.
  • One send is exactly one run per matching automation, however many times it is redelivered internally.
  • An unknown event name, or a contact this team does not have, is 404 not_found. Exactly one of contact_id and email must be given; neither or both is 422.

Endpoints

Create an event

POST /events

Declare a name your integrations can fire and your workflows can trigger on.

Body

  • namestringRequired

    Lower-case letters, digits, ., _ and -, starting with a letter, at most 100 characters. Unique among your live events.

  • schemaobject | null

    A flat map from payload key to type: string, number, boolean or date. At most 50 keys. A payload sent under this event is checked against it.

Request

curl -X POST "https://api.rasket.com/events" \
  -H "Authorization: Bearer $RASKET_API_KEY" \
  -H "User-Agent: acme-billing/1.0" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "trial.started",
  "schema": {
    "plan": "string",
    "seats": "number"
  }
}'

Response 201

{
  "object": "event",
  "id": "0199d2f1-4c4e-7a20-9c31-6f2b8a0e5f01"
}
  • Names under the reserved rasket: prefix are the platform's own triggers — rasket:contact.created and its siblings — and are 422 validation_error here.
  • A name already held by one of your live events is 422 validation_error.
  • Declaring a schema is optional. Without one, any payload is accepted.

List events

GET /events

Every event you have declared, 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

    A case-insensitive substring of the event's name, at most 200 characters. % and _ match literally; a blank term is 422 invalid_parameter.

Request

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

Response 200

{
  "object": "list",
  "has_more": false,
  "data": [
    {
      "id": "0199d2f1-4c4e-7a20-9c31-6f2b8a0e5f01",
      "name": "trial.started",
      "schema": {
        "plan": "string",
        "seats": "number"
      },
      "created_at": "2026-09-11T12:00:00.000Z",
      "updated_at": "2026-09-11T12:00:00.000Z"
    }
  ]
}
  • Requires a full-access key. A key restricted to sending may fire events, not list them.

Send an event

POST /events/send

Fire one event for one contact. This is what starts a workflow.

Body

  • eventstringRequired

    The name of a live event of yours.

  • contact_idstring

    The contact this happened to. Exactly one of contact_id or email.

  • emailstring

    The contact's address, instead of an ID. Exactly one of the two.

  • payloadobject

    Key/value pairs to carry with the event, at most 16 KB of JSON. Checked against the event's schema when it declares one.

Request

curl -X POST "https://api.rasket.com/events/send" \
  -H "Authorization: Bearer $RASKET_API_KEY" \
  -H "User-Agent: acme-billing/1.0" \
  -H "Content-Type: application/json" \
  -d '{
  "event": "trial.started",
  "contact_id": "0199d2f1-4c4e-7a20-9c31-6f2b8a0e5f02",
  "payload": {
    "plan": "pro",
    "seats": 12
  }
}'

Response 202

{
  "object": "event",
  "event": "trial.started"
}
  • **202, not 200.** The event is durable the moment this returns; the runs it enrols start on the next tick.
  • This route takes no Idempotency-Key. Two calls are two events and two runs — retry it only when the first call never answered.
  • A key restricted to sending may call this, which is the point: firing an event is no more powerful than sending an email.
  • An unknown event name, or a contact this team does not have, is 404 not_found.

Retrieve an event

GET /events/{identifier}

By ID or by name.

Path parameters

  • identifierstringRequired

    The event's ID, or its name. A name can never be shaped like an ID.

Request

curl -X GET "https://api.rasket.com/events/{identifier}" \
  -H "Authorization: Bearer $RASKET_API_KEY" \
  -H "User-Agent: acme-billing/1.0"

Response 200

{
  "object": "event",
  "id": "0199d2f1-4c4e-7a20-9c31-6f2b8a0e5f01",
  "name": "trial.started",
  "schema": {
    "plan": "string",
    "seats": "number"
  },
  "created_at": "2026-09-11T12:00:00.000Z",
  "updated_at": "2026-09-11T12:00:00.000Z"
}
  • schema is null, not absent, when the event declares none.
  • An event that belongs to another team, or that has been deleted, is 404 not_found.

Update an event

PATCH /events/{identifier}

Replace the payload schema, or clear it.

Path parameters

  • identifierstringRequired

    The event's ID, or its name. A name can never be shaped like an ID.

Body

  • schemaobject | nullRequired

    A flat map from payload key to type: string, number, boolean or date. At most 50 keys. A payload sent under this event is checked against it.

Request

curl -X PATCH "https://api.rasket.com/events/{identifier}" \
  -H "Authorization: Bearer $RASKET_API_KEY" \
  -H "User-Agent: acme-billing/1.0" \
  -H "Content-Type: application/json" \
  -d '{
  "schema": {
    "plan": "string",
    "seats": "number",
    "trial_ends_at": "date"
  }
}'

Response 200

{
  "object": "event",
  "id": "0199d2f1-4c4e-7a20-9c31-6f2b8a0e5f01"
}
  • schema is required, because it is the only field a PATCH can change. Send null to clear it.
  • The schema is replaced, not merged. A key you leave out is no longer declared.
  • An event's name is immutable, so a published workflow never loses the trigger it names.

Delete an event

DELETE /events/{identifier}

Soft-deletes and frees the name.

Path parameters

  • identifierstringRequired

    The event's ID, or its name. A name can never be shaped like an ID.

Request

curl -X DELETE "https://api.rasket.com/events/{identifier}" \
  -H "Authorization: Bearer $RASKET_API_KEY" \
  -H "User-Agent: acme-billing/1.0"

Response 200

{
  "object": "event",
  "id": "0199d2f1-4c4e-7a20-9c31-6f2b8a0e5f01",
  "deleted": true
}
  • A published workflow version still naming it simply never fires again. Runs already in flight are untouched.
  • The name is free to declare again afterwards.