# Attribution

> Pixels, server events, conversions and creator codes.

Source: https://www.onlucra.com/docs/api-attribution

Track what creators drive on a brand's own site. A **pixel** records visitors' events, a **conversion** decides which events count, and a link from a creator's video credits them. The [tracking guide](https://www.onlucra.com/docs/tracking) covers installing the pixel in the browser.

Start with `POST /v1/pixels`, then add a conversion for the event you care about, like a purchase.

## Pixels

`POST /v1/pixels` creates one for the domains it may send from:

```json
{
  "name": "Shop",
  "domains": ["https://shop.example.com"],
  "excludedCountries": ["DE"]
}
```

```json
{
  "id": "pxl_0Q2m8VxR4sTnYb7KcLd3Ew",
  "name": "Shop",
  "domains": ["https://shop.example.com"],
  "excludedCountries": ["DE"],
  "status": "verified",
  "lastSeenAt": "2026-10-07T15:04:05.000Z",
  "snippet": "<script>window.lucra=window.lucra||[];lucra.push([\"init\",{siteId:\"pxl_0Q2m8VxR4sTnYb7KcLd3Ew\"}]);</script><script async src=\"https://a.onlucra.com/p.js\"></script>",
  "firstParty": {
    "path": "/lucra",
    "target": "https://a.onlucra.com",
    "snippet": "<script>…</script><script async src=\"/lucra/p.js\"></script>"
  },
  "quality": {
    "events": 1840,
    "consented": 1622,
    "fromServer": 212,
    "withUserData": 240,
    "withClickIds": 610,
    "credited": 388,
    "located": 1835
  },
  "version": 2,
  "createdAt": "2026-10-01T15:04:05.000Z",
  "updatedAt": "2026-10-02T09:12:44.000Z"
}
```

- `domains` are origins with no path, like `https://shop.example.com`.
- `excludedCountries` are two-letter codes; visitors there aren't recorded.
- `status` is `waiting` until the first event arrives, then `verified`; `archived` pixels accept no events.
- `firstParty` is the recommended install: proxy `path` on your site to `target` and use its `snippet`.
- `quality` counts the last 7 days' events.

`PATCH /v1/pixels/:id` renames it, changes `domains` or `excludedCountries`, or archives it with `status: "archived"`. The `pixel.verified` [webhook](https://www.onlucra.com/docs/webhooks) fires on its first event.

A connected Shopify store can install the pixel without code from **Settings → Lucra Pixel** in the app.

## Server events

`POST /v1/pixels/:id/events` (`lucra.pixels.events.create` in the SDK) records an event from the brand's server, so ad blockers and closed tabs can't lose it. It returns `202`:

```json
{
  "name": "purchase",
  "eventId": "order-1042",
  "orderId": "1042",
  "value": 4999,
  "currency": "USD",
  "pageUrl": "https://shop.example.com/thanks",
  "lucraId": "sub_14XA4WGiSOmaVI3B4QLm4Fs",
  "landedAt": "2026-10-05T18:20:00.000Z",
  "user": { "email": "jo@example.com", "phone": "+1 555 010 4477" },
  "clickIds": { "fbc": "fb.1.1759685000000.IwAR2x", "fbp": "fb.1.1759600000000.1234567890" },
  "ipAddress": "203.0.113.7",
  "userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 26_0 like Mac OS X) …"
}
```

```json
{ "eventId": "order-1042", "duplicate": false }
```

| Field                                        | What                                                                                                                       |
| -------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
| `name`                                       | A standard event (`page_view`, `view_content`, `search`, `add_to_cart`, `begin_checkout`, `purchase`, `lead`, `sign_up`, `start_trial`, `subscribe`, `contact`) or your own, in snake_case. |
| `eventId`                                    | Send the browser event's ID to count it once. A repeat returns `duplicate: true` and confirms the browser event.         |
| `occurredAt`                                 | Defaults to now; within the last 7 days.                                                                                   |
| `value`, `currency`                          | In cents, with an ISO 4217 code. Send both or neither.                                                                     |
| `orderId`                                    | Your order's ID.                                                                                                           |
| `pageUrl`                                    | A page on the pixel's domains. Defaults to its first domain.                                                               |
| `consent`                                    | `granted` (default), `denied` or `unknown`. Without `granted`, leave out `lucraId`, `landedAt`, `user`, `clickIds`, `ipAddress` and `userAgent`. |
| `lucraId`                                    | `lucra_id` from the landing URL: the video the visitor came from.                                                          |
| `discountCode`                               | The order's discount code, recorded with the event.                                                                       |
| `landedAt`                                   | When the visitor arrived from the video or code, for attribution windows.                                                  |
| `user`                                       | `email`, `phone`, `firstName`, `lastName`, `city`, `state`, `zip`, `country`, `externalId`. Hashed (SHA-256) on arrival; hashes are kept as sent. |
| `clickIds`                                   | `fbc`, `fbp`, `gclid`, `gbraid`, `wbraid`, `ttclid`, `ttp`, `sccid`, `scid`.                                               |
| `ipAddress`, `userAgent`                     | The visitor's. The IP is kept 13 months.                                                                                   |
| `location`                                   | `country`, `region`, `city`, `postalCode`, like the shipping address.                                                      |
| `actionSource`                               | `website` (default), `app`, `physical_store`, `phone_call`, `chat`, `email`, `system_generated` or `other`.                |
| `properties`                                 | `productId`, `variantId`, `quantity`, `contents` (`{ id, quantity, price }`, up to 100) and `custom` (up to 25 fields).    |

A pixel takes up to 1,200 events a minute; past that you get `429`.

## Pixel events

`GET /v1/pixel-events` lists what the pixels received, newest first. Filter by `pixel`, `conversion`, or `attributed=true` for events from a creator's video. `GET /v1/pixel-events/:id` returns one, with what ad platforms' conversion APIs take:

```json
{
  "id": "pxev_3Hd8kQm1ZrT6yWv2NbLx0Pa",
  "pixel": "pxl_0Q2m8VxR4sTnYb7KcLd3Ew",
  "name": "purchase",
  "occurredAt": "2026-10-07T15:04:05.000Z",
  "receivedAt": "2026-10-07T15:04:05.412Z",
  "sentFrom": "server",
  "actionSource": "website",
  "consent": "granted",
  "value": 4999,
  "currency": "usd",
  "orderId": "1042",
  "pageUrl": "https://shop.example.com/thanks",
  "referrerUrl": null,
  "submission": "sub_14XA4WGiSOmaVI3B4QLm4Fs",
  "landedAt": "2026-10-05T18:20:00.000Z",
  "clickIds": { "fbc": "fb.1.1759685000000.IwAR2x" },
  "user": { "email": "5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8" },
  "ipAddress": "203.0.113.7",
  "userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 26_0 like Mac OS X) …",
  "properties": {},
  "conversions": ["conv_1fK7pQ2wXy9LmN4bVc8RtZa"],
  "source": "paid_ad",
  "creator": "crtr_026UYfiw1Y6OvUpuKWiOpeL",
  "discountCode": null,
  "location": { "country": "US", "region": "California", "city": "Oakland", "postalCode": "94612", "timezone": "America/Los_Angeles", "latitude": 37.8, "longitude": -122.27 },
  "network": { "asn": 7922, "organization": "Comcast" },
  "device": { "type": "mobile", "os": "iOS", "browser": "Safari", "inApp": "tiktok", "language": "en-US" }
}
```

- `sentFrom` is `server` for server events and browser events a server copy confirmed.
- `source` is `paid_ad` (an ad's link) or `direct`; `creator` is who's credited.
- `user` holds SHA-256 hashes, normalized for Meta, TikTok and Google.

## Conversions

A conversion counts the events that matter, like purchases over $20:

```json
{
  "name": "Purchase",
  "eventName": "purchase",
  "pageUrlContains": "/thanks",
  "minValue": { "amount": 2000, "currency": "USD" },
  "attributionWindowDays": 30,
  "payBrowserEvents": false
}
```

```json
{
  "id": "conv_1fK7pQ2wXy9LmN4bVc8RtZa",
  "name": "Purchase",
  "eventName": "purchase",
  "pageUrlContains": "/thanks",
  "minValue": { "amount": 2000, "currency": "usd" },
  "attributionWindowDays": 30,
  "payBrowserEvents": false,
  "status": "active",
  "recorded": 412,
  "attributed": 96,
  "version": 1,
  "createdAt": "2026-10-01T15:04:05.000Z",
  "updatedAt": "2026-10-01T15:04:05.000Z"
}
```

- `eventName` is a standard event or your own.
- `pageUrlContains` and `minValue` narrow it; a minimum value matches only events in its currency.
- `attributionWindowDays` (1–90, default 30) credits the creator when the visitor converts within that many days of landing from their video. Events without a landing time, like server events, are credited too.
- `payBrowserEvents` lets browser-only events pay creators. Off by default, since anyone with the pixel ID can send browser events.
- `recorded` counts matching events; `attributed`, those credited to a creator.

`PATCH /v1/conversions/:id` changes it or archives it; events already recorded keep counting as they did. Each matching event sends `conversion.recorded` with `conversion`, `pixel_event` and, when credited to a video, `submission`.

### Pay per conversion

Add a conversion rule to a program's or a retainer's [pay](https://www.onlucra.com/docs/api-payments#pay):

```json
{
  "rules": [
    { "conversion": "conv_1fK7pQ2wXy9LmN4bVc8RtZa", "amount": 500 },
    { "conversion": "conv_7Rt2LmQ9xWb4NcV1kZp8YsD", "percent": 10 }
  ],
  "cap": 100000,
  "schedule": { "every": "week" }
}
```

- `amount` pays a flat amount in cents per conversion; `percent` pays a share of its value, like an affiliate commission. A `percent` counts only events valued in USD for now.
- Only conversions credited to the creator count: through their video's `lucra_id` link, within the conversion's window. One counts toward every program and retainer of that creator that pays on it.
- Only server-confirmed events pay, unless the conversion has `payBrowserEvents: true`.
- A retainer can pay only on conversions. A program pays them alongside its usual rule.

## Report

`GET /v1/conversions/:id/report?groupBy=creator,country` breaks a conversion down by up to 3 of `creator`, `country`, `region`, `city`, `inApp`, `deviceType`, `source` and `day`. Narrow it with `from`, `to`, and `credited=true` for creators' only.

```json
{
  "data": [
    { "creator": "crtr_026UYfiw1Y6OvUpuKWiOpeL", "country": "US", "conversions": 58, "value": 289942, "currency": "usd" },
    { "creator": null, "country": "CA", "conversions": 21, "value": 104979, "currency": "usd" }
  ]
}
```

- `POST /v1/pixels` (write, SDK `lucra.pixels.create`): Create a pixel
- `POST /v1/pixels/:id/events` (write, SDK `lucra.pixels.events.create`): Send a conversion from the brand's server; 202 once it's recorded for attribution
- `GET /v1/pixels` (read, SDK `lucra.pixels.list`): List pixels
- `GET /v1/pixels/:id` (read, SDK `lucra.pixels.retrieve`): Get a pixel and whether it's verified
- `PATCH /v1/pixels/:id` (write, SDK `lucra.pixels.update`): Rename a pixel, change its domains or excluded countries, or archive it
- `POST /v1/conversions` (write, SDK `lucra.conversions.create`): Create a conversion: the events that count as a sign-up, a purchase or your own goal
- `GET /v1/conversions` (read, SDK `lucra.conversions.list`): List conversions, newest first
- `GET /v1/conversions/:id` (read, SDK `lucra.conversions.retrieve`): Get a conversion and how many events counted as it
- `PATCH /v1/conversions/:id` (write, SDK `lucra.conversions.update`): Change a conversion or archive it; events already recorded keep counting as they did
- `GET /v1/conversions/:id/report` (read, SDK `lucra.conversions.report.retrieve`): Break a conversion down by creator, place, in-app browser, source or day, with counts and value
- `GET /v1/pixel-events` (read, SDK `lucra.pixelEvents.list`): List the events your pixels received, newest first
- `GET /v1/pixel-events/:id` (read, SDK `lucra.pixelEvents.retrieve`): Get one pixel event, with what ad platforms' conversion APIs take
