> ## Documentation Index
> Fetch the complete documentation index at: https://docs.immutable.com/llms.txt
> Use this file to discover all available pages before exploring further.

# REST API

> Send events directly from your backend, game server, or payment webhook. No browser or client-side library required.

<Warning>
  The REST API is currently in **alpha**. APIs and behavior may change between releases.
</Warning>

<Info>
  **Who is this for?** Backend engineers and game server developers who need to send events from server-side code, such as purchase confirmations, server-authoritative game events, or login handlers.
</Info>

The Immutable REST API sends events to the Immutable attribution pipeline over HTTP. It uses the same event schemas as the [Tracking Pixel](/docs/products/audience/tracking-pixel) and [Web SDK](/docs/products/audience/web-sdk). Because events originate from your server, they are authoritative and cannot be dropped by ad blockers or manipulated client-side, making the REST API the recommended source for purchase confirmations and other high-value events. Send a JSON payload with the event type, name, and properties, and it flows into the same pipeline as all other surfaces.

## When to Use the REST API

| You want to...                                                 | Use this                                                 |
| -------------------------------------------------------------- | -------------------------------------------------------- |
| Passively capture page views and clicks on a marketing site    | [Tracking Pixel](/docs/products/audience/tracking-pixel) |
| Instrument a web app with typed, explicit events               | [Web SDK](/docs/products/audience/web-sdk)               |
| Send events from your game server, backend, or webhook handler | **REST API**                                             |
| Send purchase confirmations or server-verified identity events | **REST API**                                             |

## What You Need

* An [Immutable Hub](https://hub.immutable.com) account with a project ([get started here](/docs/products/hub/getting-started))
* A publishable key from your project settings ([API keys guide](/docs/products/hub/api-keys))

## Quick Start

```bash theme={null}
curl -X POST https://api.immutable.com/v1/audience/messages \
  -H "Content-Type: application/json" \
  -H "x-immutable-publishable-key: YOUR_PUBLISHABLE_KEY" \
  -d '{
    "messages": [{
      "type": "track",
      "messageId": "550e8400-e29b-41d4-a716-446655440000",
      "eventTimestamp": "2026-04-08T12:00:00Z",
      "eventName": "purchase",
      "userId": "user-123",
      "surface": "web",
      "properties": {
        "currency": "USD",
        "value": 9.99,
        "itemId": "sword_01"
      },
      "context": {
        "library": "my-studio-backend",
        "libraryVersion": "1.0.0"
      }
    }]
  }'
```

**Response:**

```json theme={null}
{
  "success": true,
  "accepted": 1,
  "rejected": 0
}
```

## Authentication

All requests require a publishable key in the `x-immutable-publishable-key` header. The base URL is `https://api.immutable.com`. Manage your keys in [Immutable Hub](https://hub.immutable.com). See the [API Keys guide](/docs/products/hub/api-keys) for how to create one.

## Consent

You are responsible for obtaining and recording user consent before sending tracking events. The REST API does not enforce consent on your behalf. Only send what the user has consented to.

The same three-tier model (`none` / `anonymous` / `full`) applies as with the Tracking Pixel and Web SDK. See the [Data Dictionary → Consent Model](/docs/products/audience/data-dictionary#consent-model) for what each level allows. In brief: at `none` send nothing, at `anonymous` omit `userId` and PII, at `full` send everything.

### Recording Consent

Call this when a user accepts or declines tracking:

```bash theme={null}
curl -X PUT https://api.immutable.com/v1/audience/tracking-consent \
  -H "Content-Type: application/json" \
  -H "x-immutable-publishable-key: YOUR_PUBLISHABLE_KEY" \
  -d '{
    "anonymousId": "anon-device-abc123",
    "status": "full",
    "source": "cookie-banner-v1"
  }'
```

Response: `204 No Content`

| Field         | Type   | Required | Description                                                                     |
| ------------- | ------ | -------- | ------------------------------------------------------------------------------- |
| `anonymousId` | string | Yes      | The anonymous ID used in your events. Max 256 chars.                            |
| `status`      | string | Yes      | `none`, `anonymous`, or `full`                                                  |
| `source`      | string | Yes      | Where the consent decision originated (e.g. `cookie-banner-v1`). Max 128 chars. |

### Reading Consent

Retrieve a stored consent preference at session start:

```bash theme={null}
curl "https://api.immutable.com/v1/audience/tracking-consent?anonymousId=anon-device-abc123" \
  -H "x-immutable-publishable-key: YOUR_PUBLISHABLE_KEY"
```

```json theme={null}
{ "status": "full" }
```

If no consent has been recorded, the response is `{ "status": "not_set" }`. Treat `not_set` the same as `none`.

## Deleting User Data

To handle a GDPR Right to Erasure request, call this endpoint from your backend with the user's `anonymousId` **or** `userId`, not both.

```bash theme={null}
# By anonymous ID
curl -X DELETE "https://api.immutable.com/v1/audience/data?anonymousId=anon-device-abc123" \
  -H "x-immutable-publishable-key: YOUR_PUBLISHABLE_KEY"

# By user ID
curl -X DELETE "https://api.immutable.com/v1/audience/data?userId=user-123" \
  -H "x-immutable-publishable-key: YOUR_PUBLISHABLE_KEY"
```

Response: `202 Accepted`

| Field                         | Where        | Required | Description                                 |
| ----------------------------- | ------------ | -------- | ------------------------------------------- |
| `x-immutable-publishable-key` | Header       | Yes      | Your publishable key                        |
| `anonymousId`                 | Query string | One of   | The anonymous device or session ID to erase |
| `userId`                      | Query string | One of   | The canonical user ID to erase              |

Deletion is processed asynchronously. All tracking data and consent records associated with the identity, including any linked identities, are removed or anonymised across all storage layers.

## API Reference

### Endpoints

| Method | Path                                           | Purpose                             |
| ------ | ---------------------------------------------- | ----------------------------------- |
| POST   | `/v1/audience/messages`                        | Ingest up to 100 events per request |
| GET    | `/v1/audience/tracking-consent?anonymousId=`   | Read stored consent status          |
| PUT    | `/v1/audience/tracking-consent`                | Record a consent decision           |
| DELETE | `/v1/audience/data?anonymousId=` or `?userId=` | GDPR erasure request                |

### Sending Events

**Headers:**

| Header                        | Required | Value                |
| ----------------------------- | -------- | -------------------- |
| `Content-Type`                | Yes      | `application/json`   |
| `x-immutable-publishable-key` | Yes      | Your publishable key |

**Response:**

```json theme={null}
{
  "success": true,
  "accepted": 2,
  "rejected": 0
}
```

The endpoint returns `200 OK` even if some messages fail validation. Invalid messages are silently skipped. Check the `rejected` count to detect failures. A `400` means the entire request failed (invalid key or malformed body).

### Message Schema

| Field            | Type              | Required | Description                                                                                                                                      |
| ---------------- | ----------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| `type`           | string            | Yes      | `track`, `identify`, `alias`, `page`, or `screen`                                                                                                |
| `messageId`      | string (UUID)     | Yes      | Unique per message, used for deduplication                                                                                                       |
| `eventTimestamp` | string (ISO 8601) | Yes      | When the event occurred, not when you send it. Must include a timezone offset (e.g. `2026-04-08T12:00:00Z`). Up to 30 days in the past accepted. |
| `context`        | object            | Yes      | Must include `library` (your system name) and `libraryVersion`                                                                                   |
| `userId`         | string            | —        | Your canonical user ID. Required on most types unless `anonymousId` is set.                                                                      |
| `anonymousId`    | string            | —        | Anonymous device or session ID. Required if `userId` is absent.                                                                                  |
| `surface`        | string            | —        | `web`, `pixel`, `unity`, or `unreal`                                                                                                             |
| `test`           | boolean           | —        | Marks the event as test traffic. Use during development or QA to separate test events from production data.                                      |

Most string fields accept up to 256 characters. `pageUrl`, `pagePath`, and `pageReferrer` accept up to 2048.

<Accordion title="Optional fields inside the context object">
  Use these to pass environment metadata alongside the required `library` and `libraryVersion`. Include whichever are relevant. All are optional.

  | Field             | Description                                               |
  | ----------------- | --------------------------------------------------------- |
  | `userAgent`       | Browser or client user agent                              |
  | `browserLanguage` | Browser language from `navigator.language` (e.g. `en-US`) |
  | `locale`          | App or game locale setting (e.g. `en-US`)                 |
  | `timezone`        | e.g. `America/New_York`                                   |
  | `screen`          | Screen resolution (e.g. `1920x1080`)                      |
  | `pageUrl`         | Full page URL                                             |
  | `pagePath`        | URL path only                                             |
  | `pageReferrer`    | Referrer URL                                              |
  | `pageTitle`       | Page title                                                |

  ```json theme={null}
  "context": {
    "library": "my-studio-backend",
    "libraryVersion": "1.0.0",
    "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
    "timezone": "America/New_York",
    "pageUrl": "https://mygame.com/shop",
    "pageTitle": "Shop"
  }
  ```
</Accordion>

### Event Types

<AccordionGroup>
  <Accordion title="track">
    Record a named event. The most common message type.

    **Also required:** `eventName`, plus `userId` or `anonymousId`

    ```json theme={null}
    {
      "type": "track",
      "messageId": "550e8400-e29b-41d4-a716-446655440001",
      "eventTimestamp": "2026-04-08T12:00:00Z",
      "eventName": "purchase",
      "userId": "user-123",
      "surface": "web",
      "properties": { "currency": "USD", "value": 9.99, "itemId": "sword_01" },
      "context": { "library": "my-studio-backend", "libraryVersion": "1.0.0" }
    }
    ```

    Use any `eventName`. [Predefined events](/docs/products/audience/data-dictionary#predefined-events) have defined property schemas. See the Data Dictionary for the full list. Custom event names are also supported.
  </Accordion>

  <Accordion title="identify">
    Associates a user ID with their activity and traits. Send when a user logs in, creates an account, or updates their profile.

    **Also required:** `userId` or `anonymousId`

    ```json theme={null}
    {
      "type": "identify",
      "messageId": "550e8400-e29b-41d4-a716-446655440004",
      "eventTimestamp": "2026-04-08T12:00:00Z",
      "userId": "user-123",
      "identityType": "passport",
      "traits": { "name": "Player One", "email": "player@example.com" },
      "context": { "library": "my-studio-backend", "libraryVersion": "1.0.0" }
    }
    ```

    **`identityType` values:** `passport`, `steam`, `epic`, `google`, `apple`, `discord`, `email`, `custom`
  </Accordion>

  <Accordion title="alias">
    Link two account IDs that belong to the same player. Use when a player connects a second account with a different provider, for example a Steam ID linked to a Passport account.

    **Also required:** `fromId`, `toId` (must be different). `from` is the account being linked. `to` is the player's canonical account.

    ```json theme={null}
    {
      "type": "alias",
      "messageId": "550e8400-e29b-41d4-a716-446655440005",
      "eventTimestamp": "2026-04-08T12:00:00Z",
      "fromId": "76561198000000001",
      "fromType": "steam",
      "toId": "user-123",
      "toType": "passport",
      "context": { "library": "my-studio-backend", "libraryVersion": "1.0.0" }
    }
    ```
  </Accordion>

  <Accordion title="page">
    Record a page view. Useful for server-side rendering where you capture page loads on the server.

    **Also required:** `userId` or `anonymousId`

    ```json theme={null}
    {
      "type": "page",
      "messageId": "550e8400-e29b-41d4-a716-446655440006",
      "eventTimestamp": "2026-04-08T12:00:00Z",
      "userId": "user-123",
      "properties": { "section": "shop" },
      "context": {
        "library": "my-studio-backend",
        "libraryVersion": "1.0.0",
        "pageUrl": "https://mygame.com/shop",
        "pageTitle": "Shop"
      }
    }
    ```
  </Accordion>

  <Accordion title="screen">
    Record a screen view in a game client or app. Same schema as `page`.

    ```json theme={null}
    {
      "type": "screen",
      "messageId": "550e8400-e29b-41d4-a716-446655440007",
      "eventTimestamp": "2026-04-08T12:00:00Z",
      "userId": "user-123",
      "properties": { "screenName": "main-menu" },
      "context": { "library": "my-game-server", "libraryVersion": "1.2.3" }
    }
    ```
  </Accordion>
</AccordionGroup>

For predefined event names and their property schemas (`purchase`, `progression`, `resource`, `sign_up`, and more), see the [Data Dictionary](/docs/products/audience/data-dictionary#predefined-events).

### Error Responses

| Status | Meaning                                                    |
| ------ | ---------------------------------------------------------- |
| `200`  | Request accepted. Check `accepted` and `rejected` counts.  |
| `400`  | Malformed request body or key format invalid.              |
| `401`  | Publishable key not recognised. Check your key is correct. |
| `500`  | Server error. Retry with exponential back-off.             |

## Next Steps

<CardGroup cols={2}>
  <Card title="Attribution" icon="route" href="/docs/products/audience/attribution">
    How tracking data powers player attribution and Hub reports
  </Card>

  <Card title="Data Dictionary" icon="book" href="/docs/products/audience/data-dictionary">
    Full reference of event schemas and consent levels
  </Card>

  <Card title="Tracking Pixel" icon="crosshairs" href="/docs/products/audience/tracking-pixel">
    Passive tracking snippet for marketing sites and landing pages
  </Card>

  <Card title="Web SDK" icon="code" href="/docs/products/audience/web-sdk">
    Typed SDK for web games, marketing sites, and SPAs
  </Card>

  <Card title="Unity SDK" icon="unity" href="/docs/products/audience/unity-sdk">
    In-game tracking for Unity desktop builds
  </Card>

  <Card title="Conversion Postbacks" icon="share-from-square" href="/docs/products/audience/conversion-postbacks">
    Send attributed conversions back to ad networks to improve campaign optimisation
  </Card>

  <Card title="API Keys" icon="key" href="/docs/products/hub/api-keys">
    Manage your publishable and secret keys
  </Card>
</CardGroup>
