Skip to content
On this site

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 the segment is created: 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 is never changed. Rename a segment freely; for a different audience, create a new one, so a sent broadcast's report keeps naming the audience it went to.

Membership

A contact is in a segment if the filter matches it or it was added explicitly. 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

POST /segments

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

Body

Body
FieldTypeDescription
name*stringUp 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.
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: an undeclared property, 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.

GET /segments

Every live segment, newest first.

Query parameters

Query parameters
FieldTypeDescription
limitintegerHow many items to return, 1–100. Defaults to 20.
afterstringReturn the page that follows this item ID. Mutually exclusive with before.
beforestringReturn the page that precedes this item ID. Mutually exclusive with after.
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.

GET /segments/{segment}

One segment, with its filter.

Path parameters

Path parameters
FieldTypeDescription
segment*stringThe segment's ID.
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.

PATCH /segments/{segment}

Change the name. The filter is fixed.

Path parameters

Path parameters
FieldTypeDescription
segment*stringThe segment's ID.

Body

Body
FieldTypeDescription
name*stringThe new name.
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"
}'

Response 200

{
  "object": "segment",
  "id": "78261eea-8f8b-4381-83c6-79fa7120f1cf"
}
  • A filter in the body is 422 invalid_parameter rather than silently dropped. A different audience is a new segment, so that a sent broadcast's report keeps naming the audience it went to.

DELETE /segments/{segment}

Retire the segment and free its name.

Path parameters

Path parameters
FieldTypeDescription
segment*stringThe segment's ID.
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 report; a draft that names it cannot be sent until it names another.

GET /segments/{segment}/contacts

The members, evaluated now: the filter's matches plus explicit additions.

Path parameters

Path parameters
FieldTypeDescription
segment*stringThe segment's ID.

Query parameters

Query parameters
FieldTypeDescription
limitintegerHow many items to return, 1–100. Defaults to 20.
afterstringReturn the page that follows this item ID. Mutually exclusive with before.
beforestringReturn the page that precedes this item ID. Mutually exclusive with after.
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.

GET /segments/{segment}/metrics

How many contacts the segment resolves to right now.

Path parameters

Path parameters
FieldTypeDescription
segment*stringThe segment's ID.
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.

POST /segments/preview

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

Body

Body
FieldTypeDescription
filter*objectA filter exactly as POST /segments takes it.
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.