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.
  • Sending newslettersGuidesUse a campaign, or include an unsubscribe link.
  • 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.
  • Sign-up formsGuidesPop-ups and embedded forms on your site, and the rules that pick one.
  • Website trackingGuidesrasket.js on your own site: the snippet, consent, three events and the check.
  • TemplatesGuidesFifty-seven starters sorted by goal, and how to keep a campaign as a template.
  • 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.
  • Mail appsGuidesComing soon: your Rasket address in Apple Mail, Outlook and the Gmail app.
  • Inbox APIGuidesOpen, read and answer support conversations from your app, with the same key.
  • Support inbox in your appGuidesA Contact us form that opens a conversation your team answers, in five minutes.
  • Replies to your emailsGuidesOne field on a send, and the customer's reply opens a conversation.
  • Let an agent triageGuidesAn AI agent reads, notes and drafts over MCP; a person sends.
  • 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.
  • IntegrationsGuidesEvery integration and its status, and Rasket on Vercel, Netlify and Cloudflare.
  • 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.
  • VercelGuidesAdd Rasket on Vercel: a Sending key in each project as RASKET_API_KEY, no copying.
  • WordPressGuidesThe Rasket plugin: every email your site sends, through Rasket, with a safe fallback.
  • NotionGuidesTurn a Notion database of people into contacts in a segment, once or every hour.
  • Migrating to RasketGuidesBring contacts, unsubscribes, lists and templates from Mailchimp, Klaviyo and more.
  • PipedreamGuidesRasket actions and instant sources for Pipedream workflows and Connect apps.
  • FramerGuidesThe Rasket plugin: sign-up forms on a Framer site, and Framer forms into contacts.
  • MakeGuidesComing soon: send email and react to email events from a Make scenario.
  • monday.comGuidesTurn board items into contacts and send a template when a board changes.
  • ClickUpGuidesReady-made Zapier and Make automations between ClickUp tasks and Rasket.
  • SlackGuidesEmail alerts in the Slack channels you choose, and /rasket for numbers and look-ups.
  • Google SheetsGuidesComing soon: turn a sheet tab of people into contacts in a segment.
  • AirtableGuidesComing soon: turn an Airtable table of people into contacts in a segment.
  • ShopifyGuidesRasket for Shopify: customers with their consent, store events and ready-made flows.
  • SMS quickstartGuidesSend your first text to a US or Canadian phone.
  • Get a numberGuidesToll-free or local numbers, and the registration carriers require.
  • Consent and STOPGuidesWho you may text, the proof you keep, and replies like STOP.
  • SMS campaignsGuidesText a segment, at a local time, priced before you send.
  • Texts in automationsGuidesThe Send SMS step, and what happens to a contact without a phone.
  • SMS webhooksGuidesThe six sms events and what each one carries.
  • SMS pricingGuidesTexts included in each plan, the price per message, and number fees.
  • 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.
  • AutopilotAPI referenceStore campaigns Autopilot drafts for you, each waiting for a yes or a skip.
  • 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.
  • InboxAPI referenceChannels, conversations, messages, notes and search in your support inbox.
  • SMSAPI referenceSend, schedule and cancel texts, numbers, test phones and SMS consent.

API referenceSegments

Segments

An audience. A segment is a filter over your contacts, a list of contacts added by hand, or both — and it is what a broadcast is sent to.

The filter

A filter is a tree of all, any and not groups over conditions. A condition is either { field, op, value } or { topic, subscription }. Groups nest three deep and a filter holds at most twenty conditions.

{
  "any": [
    {
      "all": [
        {
          "field": "properties.plan",
          "op": "eq",
          "value": "trial"
        },
        {
          "field": "created_at",
          "op": "gte",
          "value": "2026-09-01T00:00:00Z"
        }
      ]
    },
    {
      "topic": "b6d24b8e-af0b-4c3c-be0c-359bbd97381e",
      "subscription": "opt_in"
    }
  ]
}
Filter fields and the operators each accepts
FieldTypeOperators
emailstringeq, neq, contains, in
first_namestringeq, neq, contains, exists, in
last_namestringeq, neq, contains, exists, in
unsubscribedbooleaneq
created_atdategt, gte, lt, lte
properties.<key>the property's typeStrings as first_name; numbers eq, neq, gt, gte, lt, lte, in, exists
  • The filter is checked when it is saved: a property that is not declared, or an operator that does not suit its type, is 422 validation_error with one entry in errors[] per condition.
  • A filter can be changed with PATCH, and is checked the same way. The change applies from then on, scheduled broadcasts included; it is refused while a broadcast to the segment is queued or sending, so one send never reaches two audiences.

Membership

A contact is in a segment if the filter matches it or it was added explicitly, unless it was removed from the segment by hand: a removed contact stays out while the filter matches it, until it is added back. Membership is evaluated when it is read and when a broadcast is sent — never stored — so a contact who starts matching is in from that moment, and one who stops matching is out, unless they were added by hand. Deleted contacts are never members.

Endpoints

Create a segment

POST /segments

Name an audience, optionally defined by a filter over your contacts.

Body

  • namestringRequired

    Up to 200 characters, unique among live segments.

  • filterobject | null

    { all | any | not: [ … ] } over { field, op, value } and { topic, subscription } conditions. Omit it for a segment with explicit membership only.

Request

curl -X POST "https://api.rasket.com/segments" \
  -H "Authorization: Bearer $RASKET_API_KEY" \
  -H "User-Agent: acme-billing/1.0" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "Trial accounts",
  "filter": {
    "all": [
      {
        "field": "properties.plan",
        "op": "eq",
        "value": "trial"
      },
      {
        "field": "created_at",
        "op": "gte",
        "value": "2026-09-01T00:00:00Z"
      }
    ]
  }
}'

Response 201

{
  "object": "segment",
  "id": "78261eea-8f8b-4381-83c6-79fa7120f1cf"
}
  • The filter is checked against your contact properties when the segment is created: a property that does not exist yet, or an operator that does not suit its type, is 422 validation_error with one errors[] entry per condition.
  • Membership is evaluated when it is read and when a broadcast is sent, never stored — a contact that starts matching is in the segment from that moment.

List segments

GET /segments

Every live segment, 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.

Request

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

Response 200

{
  "object": "list",
  "has_more": false,
  "data": [
    {
      "id": "78261eea-8f8b-4381-83c6-79fa7120f1cf",
      "name": "Trial accounts",
      "created_at": "2026-09-08T22:22:17.595Z"
    }
  ]
}
  • List items carry no filter; retrieve a segment for it.

Retrieve a segment

GET /segments/{segment}

One segment, with its filter.

Path parameters

  • segmentstringRequired

    The segment's ID.

Request

curl -X GET "https://api.rasket.com/segments/78261eea-8f8b-4381-83c6-79fa7120f1cf" \
  -H "Authorization: Bearer $RASKET_API_KEY" \
  -H "User-Agent: acme-billing/1.0"

Response 200

{
  "object": "segment",
  "id": "78261eea-8f8b-4381-83c6-79fa7120f1cf",
  "name": "Trial accounts",
  "filter": {
    "all": [
      {
        "field": "properties.plan",
        "op": "eq",
        "value": "trial"
      },
      {
        "field": "created_at",
        "op": "gte",
        "value": "2026-09-01T00:00:00Z"
      }
    ]
  },
  "created_at": "2026-09-08T22:22:17.595Z"
}
  • filter is null for a segment with explicit membership only.

Update a segment

PATCH /segments/{segment}

Change the name, and the filter when one is sent.

Path parameters

  • segmentstringRequired

    The segment's ID.

Body

  • namestringRequired

    The name: the new one, or the current one to keep it.

  • filterobject | null

    A new filter, checked as on create. null leaves only the people added by hand. Leave it out to keep the filter.

Request

curl -X PATCH "https://api.rasket.com/segments/78261eea-8f8b-4381-83c6-79fa7120f1cf" \
  -H "Authorization: Bearer $RASKET_API_KEY" \
  -H "User-Agent: acme-billing/1.0" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "Trials, September",
  "filter": {
    "all": [
      {
        "field": "properties.plan",
        "op": "eq",
        "value": "trial"
      },
      {
        "field": "created_at",
        "op": "gte",
        "value": "2026-09-01T00:00:00Z"
      }
    ]
  }
}'

Response 200

{
  "object": "segment",
  "id": "78261eea-8f8b-4381-83c6-79fa7120f1cf"
}
  • People added to the segment or removed from it by hand stay that way when the filter changes.
  • A filter change is 422 validation_error while a broadcast to the segment is queued or sending, so one send never reaches two audiences. A scheduled broadcast goes to the new filter. Sending the current filter with a new name is a rename.
  • A sent broadcast's recipients are recorded when it is sent, so its report still lists who it went to after the filter changes.

Delete a segment

DELETE /segments/{segment}

Retire the segment and free its name.

Path parameters

  • segmentstringRequired

    The segment's ID.

Request

curl -X DELETE "https://api.rasket.com/segments/78261eea-8f8b-4381-83c6-79fa7120f1cf" \
  -H "Authorization: Bearer $RASKET_API_KEY" \
  -H "User-Agent: acme-billing/1.0"

Response 200

{
  "object": "segment",
  "id": "78261eea-8f8b-4381-83c6-79fa7120f1cf",
  "deleted": true
}
  • The segment is 404 from that moment. Past broadcasts that went to it keep their recipients; a draft that names it cannot be sent until it names another.

List a segment's contacts

GET /segments/{segment}/contacts

The members, evaluated now: the filter's matches, less contacts removed by hand, plus explicit additions.

Path parameters

  • segmentstringRequired

    The segment's ID.

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/segments/78261eea-8f8b-4381-83c6-79fa7120f1cf/contacts" \
  -H "Authorization: Bearer $RASKET_API_KEY" \
  -H "User-Agent: acme-billing/1.0"

Response 200

{
  "object": "list",
  "has_more": false,
  "data": [
    {
      "id": "e169aa45-1ecf-4183-9955-b1499d5701d3",
      "email": "ronald.williams@example.com",
      "first_name": "Ronald",
      "last_name": "Williams",
      "created_at": "2026-09-08T22:22:17.595Z",
      "unsubscribed": false
    }
  ]
}
  • This is the audience a broadcast to the segment would resolve, before subscription, suppression and unsubscribe filtering. Deleted contacts are never listed.

Add contacts to a segment

POST /segments/{segment}/contacts/batch/add

Put up to 100 contacts in the segment at once.

Path parameters

  • segmentstringRequired

    The segment's ID.

Body

  • contact_idsstring[]Required

    1 to 100 contact IDs.

Request

curl -X POST "https://api.rasket.com/segments/78261eea-8f8b-4381-83c6-79fa7120f1cf/contacts/batch/add" \
  -H "Authorization: Bearer $RASKET_API_KEY" \
  -H "User-Agent: acme-billing/1.0" \
  -H "Content-Type: application/json" \
  -d '{
  "contact_ids": ["e169aa45-1ecf-4183-9955-b1499d5701d3"]
}'

Response 200

{
  "object": "segment_contacts",
  "segment_id": "78261eea-8f8b-4381-83c6-79fa7120f1cf",
  "added": 1
}
  • A contact that was removed from the segment before is back in, even if the filter does not match it. Contacts already in the segment are counted and left as they are.
  • All-or-nothing: an ID that names no contact is 422 invalid_parameter at its index, and nothing is written.

Remove contacts from a segment

POST /segments/{segment}/contacts/batch/remove

Take up to 100 contacts out of the segment at once.

Path parameters

  • segmentstringRequired

    The segment's ID.

Body

  • contact_idsstring[]Required

    1 to 100 contact IDs.

Request

curl -X POST "https://api.rasket.com/segments/78261eea-8f8b-4381-83c6-79fa7120f1cf/contacts/batch/remove" \
  -H "Authorization: Bearer $RASKET_API_KEY" \
  -H "User-Agent: acme-billing/1.0" \
  -H "Content-Type: application/json" \
  -d '{
  "contact_ids": ["e169aa45-1ecf-4183-9955-b1499d5701d3"]
}'

Response 200

{
  "object": "segment_contacts",
  "segment_id": "78261eea-8f8b-4381-83c6-79fa7120f1cf",
  "removed": 1
}
  • A removed contact stays out even while the segment's filter matches it, until it is added back. The contacts and their consent are untouched.
  • All-or-nothing: an ID that names no contact is 422 invalid_parameter at its index, and nothing is written.

Retrieve a segment's size

GET /segments/{segment}/metrics

How many contacts the segment resolves to right now.

Path parameters

  • segmentstringRequired

    The segment's ID.

Request

curl -X GET "https://api.rasket.com/segments/78261eea-8f8b-4381-83c6-79fa7120f1cf/metrics" \
  -H "Authorization: Bearer $RASKET_API_KEY" \
  -H "User-Agent: acme-billing/1.0"

Response 200

{
  "object": "segment_metrics",
  "segment_id": "78261eea-8f8b-4381-83c6-79fa7120f1cf",
  "contacts": 1240,
  "subscribed": 1197,
  "unsubscribed": 43
}
  • One pass over the same membership /contacts lists, split on the global unsubscribe.

Preview a segment

POST /segments/preview

How many contacts a filter matches right now, without creating a segment.

Body

  • filterobjectRequired

    A filter exactly as POST /segments takes it.

  • segment_idstring

    A saved segment whose filter this one would replace: the count is then what that segment would hold, with the people added and removed by hand.

Request

curl -X POST "https://api.rasket.com/segments/preview" \
  -H "Authorization: Bearer $RASKET_API_KEY" \
  -H "User-Agent: acme-billing/1.0" \
  -H "Content-Type: application/json" \
  -d '{
  "filter": {
    "all": [
      {
        "field": "properties.plan",
        "op": "eq",
        "value": "trial"
      },
      {
        "field": "created_at",
        "op": "gte",
        "value": "2026-09-01T00:00:00Z"
      }
    ]
  }
}'

Response 200

{
  "object": "segment_preview",
  "contacts": 1284
}
  • Nothing is stored. A filter POST /segments would refuse is 422 validation_error here, with the same errors[] paths.