Skip to content

Customer timeline

Everything a store did with one customer, newest first, plus what plugins recorded about them: orders, returns, the emails the store sent, abandoned checkouts, live chat conversations and support tickets, and the events your plugin and others posted. One list, one shape, one call.

The scopes

  • customer-events:read lists a customer's timeline. A session token carries it only for a dashboard user who may read customers, the same way customer:read works.
  • customer-events:create records your plugin's own events. It is plugin-bound: no dashboard permission stands behind it, so every session token carries it once the store has granted it.

Reading the timeline

HTTP
GET /v1/customers/{customerId}/events?limit=50&types=order,plugin HTTP/1.1
Host: api.myorbitcommerce.net
Authorization: Bearer <access-token>
ParameterPurpose
limit1 to 100 events a page, 50 by default.
typesA comma list of the kinds wanted: order, return, email, checkout, chat, ticket, plugin. Every kind when left out. plugin covers what every plugin recorded.
beforeOnly events before this instant (ISO 8601). Pass the previous page's meta.nextBefore to read on.

The customer must belong to the store (404 otherwise). The answer, in the data field of the standard response envelope, is { items, meta: { limit, nextBefore } }; nextBefore is null on the last page. Every event has the same shape:

JSON
{
  "id": "0f3c8b2a-1d4e-4a6b-9c2f-7e5a1b2c3d4e",
  "type": "order.placed",
  "occurredAt": "2026-10-01T10:00:00.000Z",
  "title": "Order #1001",
  "summary": "paid, processing",
  "link": "/orders/0f3c8b2a-1d4e-4a6b-9c2f-7e5a1b2c3d4e/detail",
  "data": {
    "orderNumber": "1001",
    "total": 12.5,
    "currency": "GBP",
    "status": "processing",
    "paymentStatus": "paid"
  }
}
TypeWhat it isdata
order.placedAn order the customer placedorderNumber, total, currency, status, paymentStatus
return.requestedA return they asked forreturnNumber, status, orderId
email.sentAn email the store sent themtemplate, status, openedAt, clickedAt
checkout.abandonedA checkout they lefttotal, currency
chat.startedA live chat conversation they startedstatus, lastMessageAt
ticket.openedA support ticket they openednumber, status
plugin.<pluginId>.<type>What a plugin recorded, with plugin: { pluginId } beside itWhatever that plugin attached

link is a path in the store dashboard where there is one, null otherwise. id is the id of the order, return, email, checkout, conversation, ticket or event itself, so it is stable across pages.

Recording your own events

HTTP
POST /v1/customers/{customerId}/events HTTP/1.1
Host: api.myorbitcommerce.net
Authorization: Bearer <access-token>
Content-Type: application/json

{
  "type": "deal.won",
  "title": "Deal won",
  "summary": "Acme renewal, 12,000 a year",
  "route": "/deals/42",
  "occurredAt": "2026-10-06T09:00:00.000Z",
  "externalId": "deal-42-won",
  "data": { "dealId": "d-1" }
}
FieldPurpose
typeYour name for the event: lower-case dotted segments such as deal.won, each starting with a letter and then letters, digits, _ or -, up to 60 characters. It may not start with plugin., which Orbit adds: listed as plugin.<pluginId>.<type>. Required.
titleOne line, up to 255 characters. Required.
summaryThe detail under it, up to 2000 characters.
routeWhere inside your plugin page a click lands, as a path such as /deals/42. Listed as the event's link, /plugins/<pluginId>?route=%2Fdeals%2F42 (the route URL-encoded).
occurredAtWhen it happened (ISO 8601). Now when left out.
externalIdYour own id for the event, up to 100 characters, unique within your plugin for the store (not per customer). A second post with the same id records nothing and answers the first, even under another customer, so a retried webhook handler never records twice.
dataAn object your plugin wants back with the event, up to 4000 characters as JSON.

The answer is { created, event }; created is false when externalId matched. Other plugins holding customer-events:read see your events too, so record what a person would want to see on the customer's page, not a log.

Limits

  • Reading counts as a read on this API (600 a minute per install); recording is held to 120 a minute.
  • The timeline reads the store's live data each time and is not a search. Narrow with types when you only need some kinds, and page with before.
  • When a store deletes a customer, their timeline answers 404 and takes no new events.