# Track a purchase

Send a transaction to Nexus after a successful purchase to attribute revenue to the validated creator.

After a player completes a purchase while supporting a creator, send the transaction to Nexus from your backend so it can be attributed and reported. Authenticate with your **program-scoped** private key.

<Aside type="caution">
You should only call this after a purchase is confirmed. In most integrations this is triggered from the backend after the payment provider sends a "success" event.
</Aside>

## Required fields

| Field             | Type           | Notes                                                    |
| ----------------- | -------------- | -------------------------------------------------------- |
| `code`            | string         | A previously validated creator code                      |
| `transactionId`   | string         | Must be unique. Use a receipt or order id from your PSP  |
| `subtotal`        | integer        | Pass minor units (USD 9.99 → 999)                        |
| `currency`        | enum           | ISO code (`USD`, `EUR`, `JPY`, …)                        |
| `description`     | string         | SKU or product descriptor                                |
| `transactionDate` | RFC3339 string | Timestamp of purchase in ISO format                      |

## Recommended fields

| Field        | Type   | Notes                                                                |
| ------------ | ------ | -------------------------------------------------------------------- |
| `playerId`   | string | Strongly recommended. Ties purchases to the same player. Pseudonymize (GUID or hashed id); no PII. |
| `playerName` | string | Optional, may also be pseudonymized. Shown to creators if present.   |
| `metrics`    | object | Optional but **crucial** for program analytics (see below).          |

<Aside type="note">
Send `playerId` even though the API does not require it. `metrics` describes a single purchase, while `playerId` is what ties purchases to the same person over time. Without it Nexus cannot separate a repeat buyer from a new one, and the conversion and reactivation outcomes never resolve.

It only needs to be unique and stable for each player, not the id you use internally. If you treat that id as PII, send a hash or a GUID instead, as long as the same player always gets the same value. Nexus never needs the real one. See [Performance metrics](/creator-code-api/attributions/performance-metrics/) for what Nexus derives from it.
</Aside>

## Request example (curl)

<ApiMethod method="POST" path="/attributions/transactions" />

<LinkCard title="View full reference" description="Parameters, responses, and status codes." href="/api/operations/creatorattribution/" />

```bash
curl -X POST "$NEXUS_BASE_URL/attributions/transactions" \
  -H "Content-Type: application/json" \
  -H "X-SHARED-SECRET: $NEXUS_PRIVATE_KEY" \
  -d '{
    "code": "thesearing",
    "subtotal": 199,
    "currency": "USD",
    "description": "bundle_100_gems",
    "transactionId": "order-123",
    "transactionDate": "2025-10-16T13:01:44.000Z",
    "playerId": "6f10c7f4-psd-123",
    "playerName": "CoolGuy1",
    "metrics": {
      "joinDate": "2017-07-22T17:32:28Z",
      "conversion": {
        "lastPurchaseDate": "2025-01-22T17:32:28Z",
        "totalSpendToDate": {
          "total": 12999,
          "currency": "USD"
        }
      }
    }
  }'
```

The response is `200 OK` and indicates the attribution was accepted.

## About metrics

Metrics are optional in the request but **crucial for reporting**. They power insights such as:

* new player acquisition
* reactivation of churned players
* conversion from free to paid users
* long-term creator influence (LTV impact)
* SKU-based revenue share analytics

If you have access to this data at time of purchase, include it. Otherwise you can add fields later once available.

`playerId` is not part of `metrics`, but every outcome above depends on it. Nexus counts a player as [Converted](/creator-code-api/attributions/performance-metrics/#converted) at most once ever, and treats a later gap as a [Repeat Reactivation](/creator-code-api/attributions/performance-metrics/#repeat-reactivation) only by checking that player's own history. Both need a stable identifier to attach that history to, so send `metrics` and `playerId` together or the reporting they feed stays incomplete.
