Skip to content

Track API

The Track API records one customer event per request. An event is one action that a person took, such as completing an order or starting a trial. JustAI returns 202 once it has durably accepted the event. Events with a userId can start, advance, or end journeys, and they can count as conversions.

Send customer events walks through naming and planning events. This page is the field-by-field reference.

POST https://ingest.justwords.ai/api/track/{org_slug}
X-Api-Key: YOUR_API_KEY
Content-Type: application/json
Header Required Value
X-Api-Key Yes, or send the key in Authorization Your JustAI API key. Authorization: Bearer and HTTP Basic also work. See Authentication.
Content-Type Recommended application/json
X-JustAI-Environment Non-production environments only The environment key, for example staging. Leave it out for Production. See Environments.

Send one JSON object with these fields:

Field Type Required Rules
type string Yes Must be exactly "track".
messageId string Yes The event’s unique ID. Must not be empty.
event string Yes The event name. Must not be empty. JustAI matches names exactly: case-sensitive and not trimmed.
timestamp string Yes When the action happened, in ISO 8601 with Z or a numeric offset. See Timestamps.
userId string or null userId, anonymousId, or both Your ID for the person, the same one you send to Identify. An empty or whitespace-only string counts as absent.
anonymousId string or null userId, anonymousId, or both An ID for a person you have not identified. Same rules as userId.
properties object No Details of the event. Defaults to {}. null or an array returns 400.
context object No Defaults to {}. JustAI saves it with the event. null returns 400.
integrations object No Defaults to {}. JustAI saves it with the event. null returns 400.

JustAI ignores every other top-level field, including sentAt, originalTimestamp, receivedAt, channel, version, writeKey, and projectId. A full Segment or RudderStack track payload works as it is.

Three more rules apply to the fields:

  • JustAI does not trim messageId or event. A value made of spaces passes validation and is stored as sent, so always send a meaningful ID and name.
  • Do not name an event profile_fields_changed or subscription_changed. JustAI uses those names for its own events.
  • Send every ID as a string. A number returns 400.

timestamp uses the same format as Identify: an ISO 8601 date-time string with Z or a numeric offset, such as 2026-10-01T12:05:00Z. A value with no time zone, a space in place of T, a date alone, or an epoch number returns 400. Identify timestamps lists every accepted and rejected form.

Track has no time bounds. It accepts dates before 1970 and dates in the future. Send the time that the action happened, not the time that you send the request.

  • Send the same userId that you send to Identify. Identify removes leading and trailing spaces from userId, but Track stores it exactly as sent, so send user IDs without spaces.
  • Track does not create or update customer profiles. Send profile data with the Identify API.
  • A journey looks up the person by userId. Before you send an event that starts an email journey, send Identify with traits.email for that person.
  • Events with only an anonymousId appear in Events > Custom events. They never start or advance journeys, and they never count as conversions. JustAI does not link them to a profile later, even after an Identify call for the same person.

When a published journey uses an event name, a Track event with that exact name and a non-empty userId can:

  • start the journey, when its entry is Event triggered
  • end a Wait until step
  • trigger an exit

Names match exactly, including case. A journey reacts only to events that JustAI receives after the journey is published. After you publish a journey, wait about a minute before you send a test event. Events that arrive in the first moments after publishing can miss the journey. To check that an event reached a journey, see Confirm that an event reaches a journey.

Journey event pickers read the Events > Custom events list, which shows the event names JustAI received in the last 30 days. Send one test event with the exact name, and build the journey after the name appears in Custom events.

A Track event can also be a journey’s conversion goal, set in the journey’s analytics under Measurement > Key metric. A conversion counts when a person sends the event after entering the journey, within the attribution window. JustAI matches the person by userId.

  • Each event must be under about 1 MB. The size JustAI counts is larger than your request body, especially when values contain many quotes, so keep each event well under 1 MB. A larger event returns 413 with {"error":"Track event is too large"}.
  • An event that starts or advances a journey must keep its properties and IDs under 128 KB, with properties nested no more than 100 levels deep. Its properties must not contain the null character, \u0000. An event that breaks these limits still returns 202 and counts for analytics, but it does not trigger a journey.
Terminal window
curl -X POST "https://ingest.justwords.ai/api/track/$JUSTAI_ORG_SLUG" \
-H "X-Api-Key: $JUSTAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"type": "track",
"messageId": "order-5678-completed",
"userId": "user-1234",
"event": "Order Completed",
"timestamp": "2026-10-01T12:05:00Z",
"properties": {
"order_id": "order-5678",
"total": 49.5,
"currency": "USD"
}
}'
Response
{"message_id":"order-5678-completed","status":"accepted"}
Status Body Meaning
202 {"message_id":"...","status":"accepted"} JustAI durably accepted the event. message_id echoes your messageId.
400 {"error":"..."} The body failed validation. See Errors.
413 {"error":"Track event is too large"} The event is over the size limit of about 1 MB. Remove large values from properties and context.
503 {"error":"Event storage is unavailable"} JustAI could not accept the event at that moment. Retry with the same body and messageId.

Authentication, path, and server errors are the same for all three APIs. See Errors and retries.

A 202 means that JustAI accepted the event. To check that the event reached your journeys and find the run it started, see Confirm that an event reaches a journey.

messageId is the event’s identity. JustAI treats Track events that share a messageId as one event, so a retry does not count twice and does not start a journey twice.

  • The API returns 202 again for a repeated messageId. It does not report duplicates.
  • Reuse a messageId only to retry the same event with the same body.
  • Do not reuse a messageId to correct an event. JustAI can’t edit or delete an accepted event. If you send a corrected event with a new messageId, JustAI records it in addition to the original, and it can start a matching journey again. To remove events, contact your JustAI team.

A 400 from Track contains only the first problem’s message, and the message does not name the field. JustAI checks the fields in this order: type, messageId, userId, anonymousId, event, timestamp, context, integrations, properties, and then the rule that at least one ID is present.

Cause Body
The body is not valid JSON {"error":"Invalid JSON"}
type is missing or is not "track", including a {"batch": [...]} envelope {"error":"Invalid literal value, expected \"track\""}
messageId, event, or timestamp is missing {"error":"Required"}
messageId or event is an empty string {"error":"String must contain at least 1 character(s)"}
timestamp has the wrong format {"error":"Invalid datetime"}
timestamp, messageId, userId, or anonymousId is a number {"error":"Expected string, received number"}
properties, context, or integrations is null {"error":"Expected object, received null"}
properties, context, or integrations is an array, or the body is an array {"error":"Expected object, received array"}
Neither userId nor anonymousId has a value {"error":"At least one of userId or anonymousId is required"}

New event names can take time to appear in Events > Custom events. Journey triggers, waits, and exits do not wait for this list. To see an event in JustAI:

  1. At the bottom of the left sidebar, check the environment shown under your name.

    If it is not the environment that you sent the event to, open the account menu, select Environment, and select Switch next to that environment.

  2. Open Events > Custom events and select Refresh.

    The event name appears in the list.

  3. Select the event name.

    The event page shows Last seen and Recent events, including the user each event came from.

If an accepted event still doesn’t appear after you refresh, contact your JustAI team with its messageId.

Events > Activity lists a Track event only when a published journey uses its name. Use it to confirm that your events reach the journeys your marketing team builds. This list does not have the Custom events delay.

  1. Publish the journey that uses the event, and wait about a minute. Events that arrive in the first moments after publishing can miss the journey.

  2. Send one Track event with the exact event name for a test userId that already has a profile with traits.email.

    The response is 202.

  3. In JustAI, check that the environment you sent the event to is selected, then open Events > Activity.

  4. Enter the test user ID in Search events. To narrow the list, select Filter events and select track-api under Source.

    The event appears with its name under Type and track-api under Source. Status shows processed once your journeys have handled the event. If it shows pending, select Refresh after a moment.

  5. Open Users, search for the test user ID, and open the person. Under Activity, select Events.

    The same event appears in the person’s activity.

If the event does not appear, check that the journey is published, that the event name matches the journey’s event exactly, including case, that the event has a userId, and that it is within the journey size limits. Then send a new test event with a new messageId. If Status shows failed, contact your JustAI team with the event’s messageId.

To see what the journey did for your test person, open the journey from Journeys. A published journey opens on its Live view, with Recent runs beside it. Enter the test user ID in Email or user ID, press Enter, and select the run to see each step it reached.