Event tracking API

Selzy supports an event tracking API that allows retrieval of user behavioral events from your backend systems.Event data can later be used for organizing mailing lists, creating contact segments, and building omnichannel automation scenarios.

At the moment, only server events are supported, but we’re working on adding other event types.

Make sure events are configured in your Selzy account, otherwise tracking won’t work.

How to get started with Event Manager

Server events tracking

Send one or more user behavioral events in a single request. Events are tied to an email address and a name, with any additional properties you want to attach.

Method: POST

URL: https://event.selzy.com/v1/events/

Authentication

Every request must include your API key in the Authorization header using the Bearer scheme. You can get this API key in your Selzy account settings. Do not make it publically available.

Authorization: Bearer YOUR_API_KEY

Requests without a valid key return the “401 Unauthorized” error.

Headers

Header Value Required
Content-Type
application/json
Yes
Authorization
Bearer YOUR_API_KEY
Yes

Body

The request body is in JSON format.

{
  "events": [ ]
}

The events parameter is a required array that accepts a list of 1 to 25 event objects.

EventObject

Field Type Required Description
event.name
string Yes Event identifier. Must match the Event name field, set when creating an event configuration in Event manager. Limits
event.email
string Yes User's email address. Must be a valid address using ASCII characters in the local part. Punycode domains are supported. Internationalized addresses (RFC 6530–6532) are not supported.
event.created
string No When the event occurred, in YYYY-MM-DD HH:MM:SS format. Defaults to the time the request is received if omitted.
(custom fields) any No Attach any additional properties. Limits

Example request

curl --request POST \
  --url http://https://event.selzy.com/v1/events/ \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer YOUR_API_KEY' \
  --data '{
    "events": [
      {
        "name": "abandoned_cart",
        "email": "user@example.com",
        "cart_value": 149.99,
        "item_count": 3,
        "currency": "USD",
        "theObj": {
          "arr": [1, "2", "qwerty"],
          "foo": "bar"
        }
      }
    ]
  }'

Responses

Incoming requests are validated in two stages:

  • Stage 1 — authentication, headers, and JSON structure. A failure here rejects the entire batch.
  • Stage 2 — each EventObject within the batch. Invalid events are dropped; the rest go through

200 OK — All events accepted

{
  "success": true
}

Every event in the batch was valid and has been registered.

400 Bad Request — One or more events invalid

{
  "code": "invalid_params",
  "error": "Error ID: 019CE0BE-B4DD-7DA0-8883-692A90D68E7F. {\"invalidEvents\": [...], \"inactiveEvents\": [...]}"
}

This is a partial success scenario. Valid events in the same batch are still registered. Only the flagged ones are dropped.

The error string embeds a JSON payload with two keys:

  • invalidEvents — events that failed schema validation (bad email, name too long, etc.)
  • inactiveEvents — events that exist in the system but are currently disabled or deleted

Log the Error ID — it's a UUID you can hand to support to trace the exact request.

401 Unauthorized

{
  "code": "unauthorized",
  "error": "Error ID: 911B6D1B-ED22-400F-8D9A-A879B8D1B447. Unauthorized."
}

Your API key is missing, malformed, or revoked. Double-check the Authorization header.

500 Internal Server Error

{
  "code": "server_error",
  "error": "Error ID: 019BE0C6-2625-73C1-AB4A-437B4FBD38C9. Sth went wrong."
}

Something failed on our end. Retry with exponential backoff. If it persists, file a bug with the Error ID.

Limits

Constraint Limit
Events per request 25
Properties per event object 25
event.name length 1–40 chars
POST request body 130 KB

Stay within these limits. Requests exceeding the body size limit will be rejected before any events are processed.

What to watch out for

Partial failures are silent to the caller unless you inspect the 400 body. A 400 response doesn't mean your whole batch failed — it means at least one event was bad. Parse the invalidEvents and inactiveEvents arrays out of the error string to know exactly which events didn't land.

event.created is optional but you should always send it. If you omit it, the service timestamps events at ingestion time. That's fine for real-time tracking. If you're replaying historical events or dealing with any buffering in your pipeline, send the actual event timestamp explicitly.

Batch smartly. Grouping events into batches of up to 25 reduces overhead and is the preferred pattern for high-throughput pipelines. Don't send single-event requests if you can avoid it.

Quick-start example

Here's a minimal integration that sends a signup event and handles both success and partial failure:

curl --request POST \
 --url http://eventmanager:8096/v1/events/ \
 --header 'Content-Type: application/json' \
 --header 'Authorization: Bearer YOUR_API_KEY' \
 --data '{
  "events": [
    {
     "name": "signup",
     "email": "newuser@example.com",
     "created": "2026-05-12 10:00:00"
      }
    ]
}'

Expected response on success:

{
  "success": true
}

Partial failure response (for example, an event is disabled in Event Manager): 

{
  "code": "invalid_params",
  "error_id": "019E1FF8-1D95-79AE-B786-FC583BA6E0AD",
  "details": {
    "invalidEvents": [],
    "inactiveEvents": [
      {
        "name": "signup",
        "email": "newuser@example.com"
      }
    ]
  }
}

An event in inactiveEvents means it doesn't exist, is disabled, or has been deleted in Event Manager. It can also mean the event name contains a leading or trailing space. Check your event settings in your Selzy account.

In this article
Server events tracking Responses Limits What to watch out for
Did we answer your question?
0
0

To get more help, contact our Support Team. They are available for all Selzy users 24/7.