Skip to content

Segment-compatible ingest ​

Aletheia takes Segment's tracking calls (identify, track, and batch of them) at /segment/v1, so the events a product already sends to Segment can feed velocity rules and automatic workflow triggers without a second integration: a Segment destination forwards them, or a service that speaks Segment's HTTP API sends them straight to Aletheia.

Sending ​

RouteBody
POST /segment/v1/trackOne track message
POST /segment/v1/identifyOne identify message
POST /segment/v1/batch{ "batch": [...], "sentAt"? }, up to 1 000 messages of any type

Requests carry a service user's token (Authorization: Bearer <token>) whose role holds events:write and subjects:write, such as the integration role; a body may be up to 1 MB. In Segment, add a Webhooks (Actions) destination (or a Destination Function) that posts the events to https://<api>/segment/v1/batch with that header. Segment's write-key authentication (HTTP Basic) is not taken: a library that sends it, such as analytics-node, needs a proxy that swaps it for the token.

What a message becomes ​

  • identify: the subject whose external id is the userId (as POST /decide and POST /subjects know it), created when the tenant has none, its traits merged into the subject's data as a JSON merge patch. Creating or changing it is audited (subject.created, subject.updated) and starts the subject.created workflows.
  • track: an event for that subject, created when missing:
Aletheia eventFrom the Segment message
typeevent, lowercased, other characters as _: Order Completed is order_completed
idempotencyKeysegment:<messageId>: a message Segment sends again is a duplicate
occurredAttimestamp, corrected by how far the sender's clock was off (sentAt against the arrival)
attributesproperties
amountThe first of revenue, total, amount, value that holds a number (amountProperties)
currencyproperties.currency, when it is three letters
ip, deviceIdcontext.ip, context.device.id
emailAn email in context.traits.email or properties.email
  • page, screen, group, alias: acknowledged and ignored.
  • A message with an anonymousId and no userId is ignored, unless the tenant keeps anonymous visitors as subjects (anon:<anonymousId>).

The events are stored as POST /events stores them: the same checks of occurredAt (at most a day ahead, not before 2000, no older than the tenant keeps events), the same velocity keys and event keys, and the same automatic workflow triggers.

The answer ​

Every request answers 200 with success, so Segment does not send it again; what could not be taken up is listed with why:

json
{
  "success": true,
  "accepted": 41,
  "duplicates": 2,
  "ignored": 6,
  "subjectsCreated": 3,
  "subjectsUpdated": 1,
  "rejected": [{ "index": 17, "messageId": "ajs-…", "reason": "messageId is required for track" }]
}

A message is rejected for no userId or anonymousId, a track without messageId or with an event name that leaves nothing, a time that is not a date or that ingestion refuses, or a userId naming a subject of another kind. A body that is not Segment's (no batch list, more than 1 000 messages) answers 400, and a token without the permissions 403.

Settings ​

settings.segment (PUT /tenants/me/settings) sets how messages map:

SettingDefaultWhat it does
subjectKinduserThe kind of the subjects identify and track create
anonymousignoresubject keeps a subject anon:<anonymousId> per visitor
amountProperties["revenue", "total", "amount", "value"]The properties the amount is read from, the first with a number

Released under the Apache-2.0 License.