# Trakroom Integration API

API version: v1. Reviewed against the Trakroom source on September 16, 2026.

This reference covers every endpoint used by the Trakroom Zapier integration, including compatibility steps retained for existing Zaps. It also documents subscription listing and the additional events available to custom webhook clients.

## Authentication and access

Base URL: `https://trakroom.com/api/v1`

Use the platform URL, even if your store has a custom domain. Requests and responses use JSON. Send `Content-Type: application/json` for POST requests.

1. Sign in to Trakroom at https://trakroom.com/login using an emailed magic link or a configured Google account.
2. Open https://trakroom.com/dashboard/settings/integrations as the store owner or a store admin.
3. Create an API key, name it for its purpose, and copy it immediately. The full secret is shown only once.
4. Send the key in the `Authorization: Bearer YOUR_API_KEY` header on every API request.

Website sign-in and API authentication are separate: do not send a magic link, website cookie, password, or Google token as the API key. Keys do not have a scheduled expiry; revoke them in Integrations when no longer needed. Revoking a key also stops webhook delivery for subscriptions tied to it. Each key is scoped to one store. A client cannot select another tenant by passing an ID.

Access depends on the store's effective **Zapier & API** entitlement, including administrator overrides. An upgrade message on the Integrations page means the feature is unavailable to that store. An existing key can still authenticate with `/me` after entitlement removal; creating hooks, searching, creating coupons, and delivering events require the entitlement. Listing/deleting subscriptions and fetching samples require a valid key but do not separately check the plan.

```bash
curl 'https://trakroom.com/api/v1/me' \
  -H 'Authorization: Bearer YOUR_API_KEY'
```

The placeholder is not a working credential. Keep actual keys out of shared logs, screenshots, wiki pages, and URLs.

## Endpoint index

| Method | Path | Purpose | Zapier use |
| --- | --- | --- | --- |
| GET | /me | Identify the connected store | Test authentication |
| POST | /hooks | Subscribe to an event | Turn on a Zap |
| GET | /hooks | List store subscriptions | Diagnostics/custom clients |
| DELETE | /hooks/{id} | Disable a subscription | Turn off a Zap |
| GET | /samples/{event} | Retrieve recent real example records | Test trigger |
| GET | /orders | Find orders | Zapier search |
| GET | /products | Find products | Zapier search |
| POST | /coupons | Create a product coupon | Zapier action |

Paths in this table are relative to the base URL. There is no pagination cursor for these endpoints. Search and sample responses are bare arrays; subscription listing is an object containing an array.

## GET /me

No parameters. Returns `200` with the store associated with the API key.

```json
{
  "id": "11111111-1111-4111-8111-111111111111",
  "storeName": "Example Beats",
  "subdomain": "example-beats",
  "storeUrl": "https://example-beats.trakroom.com",
  "status": "active",
  "keyName": "Zapier",
  "events": [
    { "id": "order.paid", "label": "New sale", "description": "A checkout completed." }
  ]
}
```

`id` is the tenant UUID. The other top-level values are strings. `events` contains objects with string `id`, `label`, and `description` for all supported API events; the shortened example above shows one entry. This is not a list of currently selectable Zapier steps. Zapier uses `storeName` as the account connection label. Returns `404` if the key's tenant no longer exists.

## POST /hooks

Creates or reactivates an event subscription. Returns `201`.

| JSON field | Type | Required | Meaning |
| --- | --- | --- | --- |
| event | string | Yes | An event ID from the event reference below |
| targetUrl | string | Yes | Public HTTPS callback URL supplied by the receiver |
| source | string | No | Client label; defaults to zapier, stored up to 40 characters |

`hookUrl` or `url` is accepted as an alias when `targetUrl` is absent. Use `targetUrl` for new clients. Local/private network destinations are rejected. The destination is checked again when sending each event. Redirects are not followed.

```bash
curl 'https://trakroom.com/api/v1/hooks' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"event":"order.paid","targetUrl":"https://hooks.example.com/trakroom/unique-secret-path","source":"custom"}'
```

Use your receiver's actual URL; the example is illustrative. Zapier supplies its own callback automatically.

```json
{
  "id": "22222222-2222-4222-8222-222222222222",
  "event": "order.paid",
  "targetUrl": "https://hooks.example.com/trakroom/unique-secret-path"
}
```

All response fields are strings; `id` is the subscription UUID used for deletion. Repeating the same store/event/URL combination reuses that subscription, resets its failure state and associates it with the calling key. Different URLs allow multiple Zaps for the same event. Unknown events, missing URLs, invalid destinations, or subscription creation failures return `400`; missing entitlement returns `403`.

## GET /hooks

No parameters. Returns `200` with all subscriptions for the key's store, including disabled subscriptions and subscriptions created using other keys for the same store.

```json
{
  "subscriptions": [
    {
      "id": "22222222-2222-4222-8222-222222222222",
      "event": "order.paid",
      "targetUrl": "https://hooks.example.com/trakroom/unique-secret-path",
      "source": "custom",
      "createdAt": "2026-09-16T10:00:00.000Z",
      "lastDeliveredAt": null,
      "active": true,
      "disabledReason": null
    }
  ]
}
```

`active` is boolean. `createdAt` is an ISO timestamp. `lastDeliveredAt` and `disabledReason` are nullable strings. Other fields are strings. An empty store returns `{"subscriptions":[]}`. `active` reflects whether the subscription was disabled; it does not prove that its key is still valid or its store remains entitled.

## DELETE /hooks/{id}

Supply the subscription UUID as `id`. No request body. Deletes the subscription belonging to the authenticated store and returns `204` with **no response body**. A missing or already disabled subscription also returns `204`. A key cannot disable another store's subscription.

```bash
curl -X DELETE 'https://trakroom.com/api/v1/hooks/22222222-2222-4222-8222-222222222222' \
  -H 'Authorization: Bearer YOUR_API_KEY'
```

## GET /samples/{event}

`event` is a supported event ID, for example `free_download.created`. Optional query parameter `limit` defaults to `3` and is bounded to `1–10`.

Returns `200` with an array of recent real store records in that event's payload shape, newest first. An empty store returns `[]`. No fabricated records are inserted by this endpoint. See the event reference for full example objects. Zapier's bundled sample objects are illustrative fixtures, separate from this endpoint's real records.

```bash
curl 'https://trakroom.com/api/v1/samples/free_download.created?limit=3' \
  -H 'Authorization: Bearer YOUR_API_KEY'
```

An unknown event returns `404`. These records are suitable for field mapping, not a durable delivery log or a full historical export. For state-based events such as refunds, the current record must satisfy that event's criteria. The endpoint does not send a webhook or run a Zap action.

## GET /orders

At least one query parameter is required:

| Query parameter | Type | Meaning |
| --- | --- | --- |
| email | string | Exact buyer email match, case insensitive |
| orderId | string | Exact order UUID |

When both are provided, matches use **OR**, not AND. An invalid order UUID alone returns an empty array. Returns `200` with at most five orders, newest created first, using the `order.paid` payload structure below. Only paid, free, refunded, or canceled orders are returned; pending/failed orders are excluded. Check the returned `status` rather than assuming every search result is paid. No results returns `[]`. Missing both parameters returns `400`; missing entitlement returns `403`.

```bash
curl 'https://trakroom.com/api/v1/orders?email=buyer%40example.com' \
  -H 'Authorization: Bearer YOUR_API_KEY'
```

## GET /products

Required query parameter `query` is a nonempty title fragment or exact URL slug. It is trimmed and capped at 120 characters. Title matching is case insensitive; slugs match the lowercased query exactly. `%` and `_` are treated as literal search text.

Returns `200` with up to five products, most recently updated first. Deleted products are excluded. Drafts are included; `published` is true only when `releaseState` is `public`. Each result uses the product payload below plus boolean `published`. No matches returns `[]`. Missing query returns `400`; missing entitlement returns `403`.

```bash
curl 'https://trakroom.com/api/v1/products?query=midnight-drive' \
  -H 'Authorization: Bearer YOUR_API_KEY'
```

## POST /coupons

Creates a real, active discount code for the authenticated store. Returns `201`. This endpoint changes store data; test it in a dedicated test store.

| JSON field | Type | Rule |
| --- | --- | --- |
| productId | string | Optional product UUID from Find Product; restricts the coupon to that product. Omit for all products. |
| licenseCodes | string[] | Optional active license codes. Restricts the coupon to those licenses; omit for all licenses. Default codes include `mp3`, `wav`, `stems`, `unlimited`, and `exclusive`. |
| type | string | Required: percent or fixed |
| percentOff | integer | Required for percent: 1–100 |
| amountOffCents | integer | For fixed: positive amount in USD cents; takes precedence over amountOff |
| amountOff | number | Alternative for fixed: USD dollars, rounded to cents |
| code | string | Optional chosen code; normalized to uppercase with whitespace changed to hyphens; 3–40 letters, digits, underscores or hyphens |
| codePrefix | string | Used only when code is omitted; uppercase letters/digits, at most 12 characters after cleaning |
| maxRedemptions | integer | Optional positive whole number; omitted means unlimited |
| expiresAt | string | Optional future date/time; use ISO 8601 with a timezone |
| expiresInDays | integer | Optional 1–3650; used only when expiresAt is absent |

With no expiry field, the coupon does not expire. With no chosen code, Trakroom generates a six-character code, optionally prefixed with `PREFIX-`.

```bash
curl 'https://trakroom.com/api/v1/coupons' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"productId":"9a8b7c6d-0000-4000-8000-000000000000","licenseCodes":["wav","stems","unlimited"],"type":"percent","percentOff":20,"codePrefix":"THANKS","maxRedemptions":1,"expiresInDays":7}'
```

```json
{
  "id": "33333333-3333-4333-8333-333333333333",
  "code": "THANKS-7K2QXA",
  "type": "percent",
  "percentOff": 20,
  "amountOffCents": null,
  "amountOffUsd": null,
  "discountLabel": "20% off",
  "productId": "9a8b7c6d-0000-4000-8000-000000000000",
  "productTitle": "Midnight Drive",
  "licenseCodes": ["wav", "stems", "unlimited"],
  "appliesTo": "Midnight Drive · wav, stems, unlimited",
  "maxRedemptions": 1,
  "expiresAt": "2026-09-23T10:00:00.000Z",
  "active": true,
  "createdAt": "2026-09-16T10:00:00.000Z"
}
```

`percentOff`, `amountOffCents`, `amountOffUsd`, and `maxRedemptions` are nullable numbers. The irrelevant discount type's amount is null. `active` is boolean; other fields are strings. `expiresAt` is an empty string when no expiry is set. Validation errors return `400`, entitlement failures `403`, and duplicate chosen codes or exhausted generated-code collision attempts `409`.

There is no idempotency-key support. Retrying a request with an automatically generated code can create another coupon. For recovery after an ambiguous timeout, use a chosen code and inspect the dashboard before retrying; duplicate codes return `409`, not the original object.

## Errors and rate limits

Normal API errors use `{"error":"A human-readable explanation."}`. Unexpected infrastructure/server failures may return a different body; do not assume every response is JSON.

| Status | Meaning | Suggested response |
| --- | --- | --- |
| 400 | Invalid request or hook destination | Correct the input; read error text |
| 401 | Missing, invalid or revoked API key | Create/reconnect a valid key |
| 403 | Zapier & API entitlement unavailable | Check the store's plan/overrides |
| 404 | Unknown sample event or missing tenant | Check event spelling or account |
| 409 | Coupon code conflict | Choose another code or inspect an earlier attempt |
| 429 | More than 120 requests per minute for this key | Wait for Retry-After seconds |
| 5xx | Unexpected service failure | Capture status/time and contact support; retry reads with backoff |

The `401` response includes `WWW-Authenticate: Bearer realm="Trakroom API"`. `429` includes `Retry-After` in seconds. Rate limiting is per key. Avoid logging the Authorization header or full callback URL. When reporting a failure, include the UTC time, HTTP method/path, status, safe error text, and Zap run ID if applicable.

## Webhook delivery contract

Trakroom sends an HTTPS POST to the subscribed URL:

```json
{
  "event": "free_download.created",
  "occurredAt": "2026-09-16T10:00:00.000Z",
  "data": {
    "id": "44444444-4444-4444-8444-444444444444",
    "email": "listener@example.com",
    "mailingListOptIn": false
  }
}
```

This envelope example abbreviates `data`; full event examples follow below. `occurredAt` records envelope creation time. Entity timestamps such as `createdAt` or `soldAt` refer to the source record. Zapier unwraps `data` into one trigger record. Test-trigger results use the same builders as live deliveries. `id` is a stable string suitable for deduplication; its source differs by event (an exclusive sale uses the order-item ID). Receivers should tolerate additional fields and deduplicate by event plus record ID. Delivery order and exactly-once processing are not guaranteed.

Headers include `Content-Type: application/json`, `User-Agent: Trakroom-Webhooks/1.0`, and `X-Trakroom-Event`. An `X-Trakroom-Signature` header is generated with an internal signing secret when configured. The public API does not issue per-subscription verification secrets, and the Zapier adapter does not validate that header. Do not treat the header's presence alone as proof of authenticity. Custom receivers should use a private, unguessable callback URL, protect it like a credential, and validate received data. Never share Trakroom's internal signing secret.

Return a `2xx` response promptly. Each attempt times out after eight seconds. `410 Gone` immediately disables the subscription. Other HTTP errors and network failures increment a consecutive failure count; 15 consecutive failures disable the subscription. A successful delivery resets the count.

There is currently no durable retry queue or automatic replay of failed events. The next event may still be delivered while the subscription remains active. Re-enabling a Zap does not backfill missed records. Plan removal or key revocation stops delivery. Compare the dashboard's records with the destination if you suspect a gap; avoid blindly replaying actions that send messages or create records.

## Zapier step availability

Version 1.3.0 offers **New Sale**, **New Free Download**, **Find Order**, **Find Product**, and **Create Product Coupon** for new Zaps. Existing Zaps retain compatibility with hidden **New Exclusive Sale** and **New Published Product** steps. The other events below are supported by the webhook API, but are not registered as selectable steps in this Zapier version.

Do not confuse an implemented API endpoint with a published Zapier action. Publishing/version availability is managed separately on Zapier.

## Event payload reference

All IDs are strings. Timestamps are ISO 8601 strings, or empty when unavailable. Missing descriptive text generally uses an empty string. Money fields ending in `Cents` are integer USD cents and fields ending in `Usd` are USD dollars. For orders, `amountCharged` is the integer minor-unit amount charged in `currency`; use that pair together. Do not interpret `amountCharged` as dollars. Arrays and booleans remain native JSON types.

The examples below are fictitious fixtures from the integration, not customer data. They show the complete fields of each sample. Names, IDs, timestamps and URLs are illustrative. Numerical product metadata may be null when unset. Removed related records may leave empty text or null IDs. The samples endpoint returns an array of these objects; webhook delivery places one object inside `data`.

### order.paid

Triggers when a checkout completes and the buyer gets their files.

```json
{
  "id": "4c9f0a1e-0000-4000-8000-000000000000",
  "orderId": "4c9f0a1e-0000-4000-8000-000000000000",
  "createdAt": "2026-08-30T15:04:05.000Z",
  "status": "paid",
  "email": "buyer@example.com",
  "buyerName": "Ada Obi",
  "buyerArtistName": "ADA",
  "amountCents": 4999,
  "amountUsd": 49.99,
  "amountCharged": 4999,
  "currency": "USD",
  "amountFormatted": "$49.99",
  "provider": "stripe",
  "couponCode": "",
  "purchaseCountry": "NG",
  "itemCount": 1,
  "firstProductId": "9a8b7c6d-0000-4000-8000-000000000000",
  "firstProductTitle": "Midnight Drive",
  "firstLicenseCode": "wav",
  "productTitles": "Midnight Drive",
  "items": [{
    "productId": "9a8b7c6d-0000-4000-8000-000000000000",
    "title": "Midnight Drive",
    "productType": "beat",
    "producer": "Ransom",
    "licenseType": "wav",
    "licenseName": "WAV License",
    "variantName": "",
    "deliveryType": "mp3,wav",
    "priceCents": 4999,
    "priceUsd": 49.99,
    "productUrl": "https://ransom.trakroom.com/beats/midnight-drive"
  }],
  "storeName": "Ransom Beats",
  "storeUrl": "https://ransom.trakroom.com",
  "dashboardUrl": "https://trakroom.com/dashboard/orders"
}
```

### free_download.created

Triggers when someone claims a free download and leaves their email address.

```json
{
  "id": "7b1c2d3e-0000-4000-8000-000000000000",
  "createdAt": "2026-08-30T15:04:05.000Z",
  "email": "listener@example.com",
  "name": "Sam",
  "country": "US",
  "region": "CA",
  "city": "Los Angeles",
  "mailingListOptIn": true,
  "completedRequirements": [
    "Follow on Instagram"
  ],
  "productId": "9a8b7c6d-0000-4000-8000-000000000000",
  "productTitle": "Midnight Drive",
  "productType": "beat",
  "producer": "Ransom",
  "productUrl": "https://ransom.trakroom.com/beats/midnight-drive",
  "storeName": "Ransom Beats",
  "dashboardUrl": "https://trakroom.com/dashboard/free-downloads"
}
```

### product.sold_exclusive

Triggers when a buyer purchases exclusive rights to a beat.

```json
{
  "id": "2a3b4c5d-0000-4000-8000-000000000000",
  "soldAt": "2026-09-14T12:00:00.000Z",
  "orderId": "4c9f0a1e-0000-4000-8000-000000000000",
  "productId": "9a8b7c6d-0000-4000-8000-000000000000",
  "title": "Midnight Drive",
  "productType": "beat",
  "producer": "Ransom",
  "licenseName": "Exclusive License",
  "priceCents": 150000,
  "priceUsd": 1500,
  "buyerEmail": "buyer@example.com",
  "buyerName": "Ada Obi",
  "buyerArtistName": "ADA",
  "artworkUrl": "https://cdn.example.com/artwork/midnight-drive.jpg",
  "storeName": "Ransom Beats",
  "dashboardUrl": "https://trakroom.com/dashboard/orders"
}
```

### product.published

Triggers when a beat, kit or other product goes live on the storefront — including scheduled releases when their date arrives.

```json
{
  "id": "9a8b7c6d-0000-4000-8000-000000000000",
  "publishedAt": "2026-08-30T15:04:05.000Z",
  "createdAt": "2026-08-20T10:00:00.000Z",
  "title": "Midnight Drive",
  "slug": "midnight-drive",
  "producer": "Ransom",
  "description": "Dark afroswing with live keys.",
  "productType": "beat",
  "releaseState": "public",
  "scheduledPublishAt": "",
  "bpm": 104,
  "musicalKey": "F minor",
  "genre": "Afrobeats",
  "tags": [
    "afroswing",
    "dark"
  ],
  "moods": [
    "moody"
  ],
  "priceMp3Usd": 29.99,
  "priceWavUsd": 49.99,
  "priceStemsUsd": 99.99,
  "priceExclusiveUsd": 299.99,
  "freeDownloadEnabled": true,
  "artworkUrl": "https://cdn.example.com/artwork/midnight-drive.jpg",
  "previewUrl": "https://cdn.example.com/preview/midnight-drive.mp3",
  "productUrl": "https://ransom.trakroom.com/beats/midnight-drive",
  "storeName": "Ransom Beats",
  "dashboardUrl": "https://trakroom.com/dashboard/products/9a8b7c6d"
}
```

### product.created

Triggers when a new beat, kit or other product is uploaded and named — including drafts that are not live yet.

```json
{
  "id": "5d1e2f3a-0000-4000-8000-000000000000",
  "createdAt": "2026-09-14T10:00:00.000Z",
  "title": "Midnight Drive",
  "slug": "midnight-drive",
  "producer": "Ransom",
  "description": "Dark afroswing with live keys.",
  "productType": "beat",
  "releaseState": "draft",
  "scheduledPublishAt": "",
  "bpm": 92.5,
  "musicalKey": "F minor",
  "genre": "Afrobeats",
  "tags": [
    "afroswing",
    "dark"
  ],
  "moods": [
    "moody"
  ],
  "priceMp3Usd": 29.99,
  "priceWavUsd": 49.99,
  "priceStemsUsd": 99.99,
  "priceExclusiveUsd": 299.99,
  "freeDownloadEnabled": true,
  "artworkUrl": "https://cdn.example.com/artwork/midnight-drive.jpg",
  "previewUrl": "https://cdn.example.com/preview/midnight-drive.mp3",
  "productUrl": "https://ransom.trakroom.com/beats/midnight-drive",
  "storeName": "Ransom Beats",
  "dashboardUrl": "https://trakroom.com/dashboard/products/5d1e2f3a-0000-4000-8000-000000000000"
}
```

### order.refunded

Triggers when a sale is refunded — by the payment provider or recorded by hand — and the buyer loses access to the files.

```json
{
  "id": "4c9f0a1e-0000-4000-8000-000000000000",
  "orderId": "4c9f0a1e-0000-4000-8000-000000000000",
  "createdAt": "2026-08-30T15:04:05.000Z",
  "status": "refunded",
  "email": "buyer@example.com",
  "buyerName": "Ada Obi",
  "buyerArtistName": "ADA",
  "amountCents": 4999,
  "amountUsd": 49.99,
  "amountCharged": 4999,
  "currency": "USD",
  "amountFormatted": "$49.99",
  "provider": "paypal",
  "couponCode": "",
  "purchaseCountry": "NG",
  "itemCount": 1,
  "firstProductId": "9a8b7c6d-0000-4000-8000-000000000000",
  "firstProductTitle": "Midnight Drive",
  "firstLicenseCode": "wav",
  "productTitles": "Midnight Drive",
  "items": [{
    "productId": "9a8b7c6d-0000-4000-8000-000000000000",
    "title": "Midnight Drive",
    "productType": "beat",
    "producer": "Ransom",
    "licenseType": "wav",
    "licenseName": "WAV License",
    "variantName": "",
    "deliveryType": "mp3,wav",
    "priceCents": 4999,
    "priceUsd": 49.99,
    "productUrl": "https://ransom.trakroom.com/beats/midnight-drive"
  }],
  "storeName": "Ransom Beats",
  "storeUrl": "https://ransom.trakroom.com",
  "dashboardUrl": "https://trakroom.com/dashboard/orders",
  "refundSource": "payment_provider",
  "providerStatus": "refunded"
}
```

### beat_request.created

Triggers when a visitor asks for a beat the storefront does not have yet.

```json
{
  "id": "2f3e4d5c-0000-4000-8000-000000000000",
  "createdAt": "2026-08-30T15:04:05.000Z",
  "status": "open",
  "requestedTitle": "That beat from the IG reel",
  "referenceUrl": "https://youtube.com/watch?v=example",
  "referenceSource": "youtube",
  "note": "Need it around 140bpm if possible",
  "requesterName": "Kofi",
  "requesterEmail": "kofi@example.com",
  "pagePath": "/beats/midnight-drive",
  "storeName": "Ransom Beats",
  "dashboardUrl": "https://trakroom.com/dashboard/requests"
}
```

### offer.created

Triggers when a buyer opens a negotiation on an exclusive or a licence.

```json
{
  "id": "5d6e7f80-0000-4000-8000-000000000000",
  "createdAt": "2026-08-30T15:04:05.000Z",
  "status": "pending",
  "customerEmail": "artist@example.com",
  "customerName": "Ada Obi",
  "customerArtistName": "ADA",
  "licenseCode": "exclusive",
  "licenseName": "Exclusive Rights",
  "amountCents": 250000,
  "amountUsd": 2500,
  "currency": "USD",
  "amountFormatted": "$2,500.00",
  "message": "Can we do 2.5k for the exclusive?",
  "expiresAt": "2026-09-06T15:04:05.000Z",
  "productId": "9a8b7c6d-0000-4000-8000-000000000000",
  "productTitle": "Midnight Drive",
  "productType": "beat",
  "productUrl": "https://ransom.trakroom.com/beats/midnight-drive",
  "storeName": "Ransom Beats",
  "dashboardUrl": "https://trakroom.com/dashboard/offers"
}
```

### offer.updated

Triggers when a negotiation moves on: an offer is countered, accepted, declined, withdrawn or cancelled.

```json
{
  "id": "6e7f8a9b-0000-4000-8000-000000000000",
  "offerId": "3d4e5f6a-0000-4000-8000-000000000000",
  "createdAt": "2026-09-12T09:00:00.000Z",
  "offerCreatedAt": "2026-09-12T09:00:00.000Z",
  "updatedAt": "2026-09-14T13:00:00.000Z",
  "status": "countered",
  "fromStatus": "pending",
  "toStatus": "countered",
  "changedBy": "producer",
  "eventMessage": "I can do $1,200 for full exclusive rights.",
  "customerEmail": "buyer@example.com",
  "customerName": "Ada Obi",
  "customerArtistName": "ADA",
  "licenseCode": "exclusive",
  "licenseName": "Exclusive License",
  "amountCents": 80000,
  "amountUsd": 800,
  "currency": "USD",
  "amountFormatted": "$800.00",
  "counterAmountCents": 120000,
  "counterAmountFormatted": "$1,200.00",
  "producerMessage": "I can do $1,200 for full exclusive rights.",
  "message": "Would you take $800?",
  "expiresAt": "2026-09-21T13:00:00.000Z",
  "productId": "9a8b7c6d-0000-4000-8000-000000000000",
  "productTitle": "Midnight Drive",
  "productType": "beat",
  "productUrl": "https://ransom.trakroom.com/beats/midnight-drive",
  "storeName": "Ransom Beats",
  "dashboardUrl": "https://trakroom.com/dashboard/offers"
}
```

### message.received

Triggers when a customer messages your store, from the contact form or a direct message.

```json
{
  "id": "7b2c4d5e-0000-4000-8000-000000000000",
  "createdAt": "2026-09-14T11:30:00.000Z",
  "channel": "direct_message",
  "customerName": "Ada Obi",
  "customerEmail": "ada@example.com",
  "subject": "Conversation with Ransom Beats",
  "message": "Hi! Is the exclusive for Midnight Drive still available?",
  "conversationId": "8c3d5e6f-0000-4000-8000-000000000000",
  "storeName": "Ransom Beats",
  "dashboardUrl": "https://trakroom.com/dashboard/messages"
}
```

### course.enrolled

Triggers when someone enrolls in one of your hosted courses.

```json
{
  "id": "1f2e3d4c-0000-4000-8000-000000000000",
  "enrolledAt": "2026-09-14T14:00:00.000Z",
  "accessStatus": "active",
  "courseId": "0a1b2c3d-0000-4000-8000-000000000000",
  "courseTitle": "Mixing Afrobeats Drums",
  "courseUrl": "https://ransom.trakroom.com/courses/mixing-afrobeats-drums",
  "instructorName": "Ransom",
  "studentName": "Ada Obi",
  "studentEmail": "ada@example.com",
  "orderId": "4c9f0a1e-0000-4000-8000-000000000000",
  "storeName": "Ransom Beats",
  "dashboardUrl": "https://trakroom.com/dashboard/courses/0a1b2c3d-0000-4000-8000-000000000000"
}
```

### course.question_created

Triggers when a student asks a question on a course lesson. Name and email are blank when the student asked anonymously.

```json
{
  "id": "9c8b7a6d-0000-4000-8000-000000000000",
  "createdAt": "2026-09-14T15:00:00.000Z",
  "question": "What compressor settings did you use on the kick?",
  "status": "open",
  "courseId": "0a1b2c3d-0000-4000-8000-000000000000",
  "courseTitle": "Mixing Afrobeats Drums",
  "courseUrl": "https://ransom.trakroom.com/courses/mixing-afrobeats-drums",
  "lessonTitle": "Kick and bass balance",
  "anonymous": false,
  "studentName": "Ada Obi",
  "studentEmail": "ada@example.com",
  "storeName": "Ransom Beats",
  "dashboardUrl": "https://trakroom.com/dashboard/courses/0a1b2c3d-0000-4000-8000-000000000000/questions"
}
```

### Order line items

Each object in the order payload's `items` array contains the following fields. Prices are before any interpretation by your downstream app; do not sum line prices as a substitute for the actual charged order amount.

For convenience, order payloads also provide `firstProductId`, `firstProductTitle`, and `firstLicenseCode`. Map `firstProductId` directly when a checkout contains one product. For a multi-product checkout, loop over `items` and use each line's `productId` instead.

```json
{
  "productId": "9a8b7c6d-0000-4000-8000-000000000000",
  "title": "Midnight Drive",
  "productType": "beat",
  "producer": "Example Producer",
  "licenseType": "wav",
  "licenseName": "WAV License",
  "variantName": "",
  "deliveryType": "wav",
  "priceCents": 4999,
  "priceUsd": 49.99,
  "productUrl": "https://example-beats.trakroom.com/beats/midnight-drive"
}
```

### Product search result

The `/products` search adds `published` to the base product object:

```json
{
  "id": "9a8b7c6d-0000-4000-8000-000000000000",
  "createdAt": "2026-08-20T10:00:00.000Z",
  "title": "Midnight Drive",
  "slug": "midnight-drive",
  "producer": "Ransom",
  "description": "Dark afroswing with live keys.",
  "productType": "beat",
  "releaseState": "public",
  "scheduledPublishAt": "",
  "bpm": 104,
  "musicalKey": "F minor",
  "genre": "Afrobeats",
  "tags": [
    "afroswing",
    "dark"
  ],
  "moods": [
    "moody"
  ],
  "priceMp3Usd": 29.99,
  "priceWavUsd": 49.99,
  "priceStemsUsd": 99.99,
  "priceExclusiveUsd": 299.99,
  "freeDownloadEnabled": true,
  "artworkUrl": "https://cdn.example.com/artwork/midnight-drive.jpg",
  "previewUrl": "https://cdn.example.com/preview/midnight-drive.mp3",
  "productUrl": "https://ransom.trakroom.com/beats/midnight-drive",
  "storeName": "Ransom Beats",
  "dashboardUrl": "https://trakroom.com/dashboard/products/9a8b7c6d-0000-4000-8000-000000000000",
  "published": true
}
```
