# Making your first requests

Validate a creator code, attribute a transaction, and update it for refunds, chargebacks, or fraud in three API calls.

This integration takes three API calls: validate a creator code, attribute a transaction, and update it for refunds, chargebacks, or fraud.

1. When a player enters a code, verify it is in your program by retrieving member information using that code. To display a list of all available codes to your players, hydrate your client-side application with a list of your members on load.
2. On purchase, provide us a few details about the transaction so the creator can be compensated.
3. After the purchase is complete, update the transaction to handle customer returns, chargebacks, or instances of fraud.

```mermaid
flowchart TD
    A["Player enters a creator code"] --> B["1 · Validate the code<br/>GET /manage/members/:memberCode<br/>public key"]
    B --> C["Player makes a purchase"]
    C --> D["2 · Attribute the transaction<br/>POST /attributions/transactions<br/>private key"]
    D --> E["Creator is credited"]
    E -->|"refund or chargeback"| F["3 · Update the transaction<br/>PATCH /attributions/transactions/:transactionId<br/>private key"]
```

## Get member by code or ID

Send an authenticated request with your public key to the member endpoint. If the code is associated with a creator that is part of your program, you will receive a `200 OK` response including detailed information about that member. If any other status code is received, refer to the response `message` field for detailed information about the issue.

<Aside type="tip">
Remember, it's okay to use and embed public API keys in client-facing code
</Aside>

<ApiMethod method="GET" path="/manage/members/{memberCode}" />
<LinkCard title="View full reference" description="Parameters, responses, and status codes." href="/api/operations/getmemberbycode/" />

Here's how you call that with curl:

```bash
curl -X 'GET' \
  'https://api.nexus.gg/v1/manage/members/samszorz' \
  -H 'accept: application/json' \
  -H 'X-SHARED-SECRET: nexus_pk_your_key_here'
```

The status should be `200 OK` with a JSON response body that looks something like this:

```json
{
  "groupId": "CsRKC8uD0NLtyQ0LOt8Ru",
  "groupName": "Test Group",
  "id": "CsRKC8uD0NLtyQ0LOt8Ru",
  "name": "samzorz",
  "playerId": "dt9NDZHcxwCXgo2fcmY4I",
  "logoImage": "https://cdn.nexus.gg/CsRKC8uD0NLtyQ0LOt8Ru/images/logo-image.jpg",
  "profileImage": "https://cdn.nexus.gg/CsRKC8uD0NLtyQ0LOt8Ru/images/profile-image.jpg",
  "codes": [{
    "code": "samzorz",
    "isPrimary": true,
    "isGenerated": false,
    "isManaged": false
  },
  {
    "code": "4sb0kla",
    "isPrimary": false,
    "isGenerated": true,
    "isManaged": false
  }]
}
```

## Get members

Retrieve all members in your program. This endpoint also uses your public key.

<ApiMethod method="GET" path="/manage/members" />
<LinkCard title="View full reference" description="Parameters, responses, and status codes." href="/api/operations/getmembers/" />

Here's how you call that with curl:

```bash
curl -X 'GET' \
  'https://api.nexus.gg/v1/manage/members' \
  -H 'accept: application/json' \
  -H 'X-SHARED-SECRET: nexus_pk_your_key_here'
```

The status should be `200 OK` with a JSON response body that looks something like this, albeit you may have a different set of members depending on who is in your program:

```json
{
  "groupId": "CsRKC8uD0NLtyQ0LOt8Ru",
  "groupName": "Test Group",
  "currentPage": 1,
  "currentPageSize": 100,
  "totalCount": 134,
  "members": [
    {
      "id": "CsRKC8uD0NLtyQ0LOt8Ru",
      "name": "samzorz",
      "logoImage": "https://cdn.nexus.gg/CsRKC8uD0NLtyQ0LOt8Ru/images/logo-image.jpg",
      "profileImage": "https://cdn.nexus.gg/CsRKC8uD0NLtyQ0LOt8Ru/images/profile-image.jpg",
      "codes": [{
        "code": "samzorz",
        "isPrimary": true,
        "isGenerated": false,
        "isManaged": false
      }]
    },
    ...
  ]
}
```

This endpoint returns paginated results, with a default page size of 100. In the example above, the currentPage is 1 and the currentPageSize is 100, so the creators array will contain only the first 100 creators in your program.

The page and pageSize can be specified using query parameters, so to retrieve the rest of the creators in this program, you would use `https://api.nexus.gg/v1/attributions/creators?page=2` which would result in the following JSON response body

```json
{
  "currentPage": 2,
  "currentPageSize": 100,
  "totalCount": 134,
  "members": [
    {
      "id": "0Con-WN07cuBMdEkr56oo",
      "name": "PopcornFrog",
      "logoImage": "https://cdn.nexus.gg/9jd7RBR_B2BZ0uWO3_lgv/images/logo-image.jpg",
      "profileImage": "https://cdn.nexus.gg/2/images/profile-image.jpg",
      "codes": [{
        "code": "popcornfrog",
        "isPrimary": true,
        "isGenerated": false,
        "isManaged": false
      }]
    },
    ....
  ]
}
```

## Attribute a transaction to a member

Send another authenticated request with your private key to the transactions endpoint. This links a purchase to a member.

A purchase may be attributed to multiple members at one time by providing an array of transactions in the POST body. Subsequent attributions using the same transactionId will be rejected as a `409 CONFLICT`.  When multiple members are attributed to the same transactionId, they will all receive the normal revenue share for that transaction (it will not be split between the members), e.g. if the normal revenue share for a purchase is 10% and it is attributed to three members, all three will receive 10% of the purchase (30% of the subtotal in all). [Group Tiers](/creator-code-api/program-management/group-tiers/), [Scheduled Revenue Shares](/creator-code-api/program-management/scheduling-temporary-revenue-shares/), and [Custom SKU Revenue Shares](/creator-code-api/attributions/custom-sku-revenue-share/) will be used as normal for these purchases. This means that the members attributed to a single purchase may receive different revenue shares. This also means that you can [override the revenue share](/creator-code-api/attributions/making-your-first-requests/#overriding-member-revenue-share) used in any of the member attributions.

Follow these guidelines before you send the request.

### API keys

<Aside type="danger">
Private API keys should only be used server-side and never distributed with a game or client-facing application
</Aside>

### Player data

<Aside type="caution">
We use the playerName field for notifications and reporting. In ecosystems like iOS, these names may have PII like the player's full name. Ensure you don't pass us any PII and use a generic term like "An (game-title) player" instead.
</Aside>

### Currency and totals

By default the totals passed for a transaction will be an integer that represents the smallest unit of that currency.

Using $9.99 as an example, USD would be provided as the currency and a subtotal of 999 cents.

For zero-decimal currencies, still provide integer totals, but without converting to cents. Using ¥500 as an example, JPY would be provided as the currency and a subtotal of 500

#### Supported zero-decimal currencies

```text
 BIF
 BTC
 CLP
 DJF
 GNF
 ISK
 JPY
 KMF
 KRW
 PYG
 RBX
 RWF
 UGX
 VND
 VUV
 XAF
 XOF
 XPF
```

### Taxes

<Aside type="caution">
We highly recommend sending subtotals that are tax-exclusive, i.e. amounts that do not include any added taxes like VAT or GST.
</Aside>

### Metrics

<Aside type="note">
Metrics are optional but highly recommended. More information on the metrics we collect may be found [here](/creator-code-api/attributions/performance-metrics/).
</Aside>

<ApiMethod method="POST" path="/attributions/transactions" />
<LinkCard title="View full reference" description="Parameters, responses, and status codes." href="/api/operations/creatorattribution/" />

Here's how you call that with curl:

```bash
curl -X 'POST' \
  'https://api.nexus.gg/v1/attributions/transactions' \
  -H 'accept: */*' \
  -H 'Content-Type: application/json' \
  -H 'X-SHARED-SECRET: nexus_sk_your_key_here' \
  -d '{
  "playerName": "dustywusty",
  "code": "popcornfrog",
  "currency": "USD",
  "description": "1000 gems",
  "platform": "PC",
  "status": "Normal",
  "subtotal": 999,
  "transactionId": "d290f1ee-6c54-4b01-90e6-d701748f0851",
  "transactionDate": "2017-07-21T17:32:28Z",
  "metrics": {
    "joinDate": "2017-07-22T17:32:28.000Z",
    "conversion": {
      "lastPurchaseDate": "2023-12-14T07:57:18.000Z",
      "totalSpendToDate": {
        "total": 129.99,
        "currency": "USD"
      }
    }
  }
  }'
```

The response status should be `200 OK` with a JSON response body that looks something like this:

```json
{
    "transaction": {
        "currency": "USD",
        "description": "1000 gems",
        "id": "BqtOoyoIHEq39i3uph_nO",
        "platform": "PC",
        "subtotal": 999,
        "transactionDate": "2017-07-21T17:32:28Z",
        "transactionId": "d290f1ee-6c54-4b01-90e6-d701748f0851",
        "transactionStatus": "Normal",
        "memberId": "0Con-WN07cuBMdEkr56oo",
        "code": "popcornfrog",
        "metrics": {
            "joinDate": "2017-07-22T17:32:28.000Z",
            "conversion": {
                "lastPurchaseDate": "2023-12-14T07:57:18.000Z",
                "totalSpendToDate": {
                    "total": 129.99,
                    "currency": "USD"
                }
            }
        }    
    }
}
```

If multiple members should be attributed to the same purchase, include multiple transactions in the same POST body, as an array.

```bash
curl -X 'POST' \
  'https://api.nexus.gg/v1/attributions/transactions' \
  -H 'accept: */*' \
  -H 'Content-Type: application/json' \
  -H 'X-SHARED-SECRET: nexus_sk_your_key_here' \
  -d '[{
  "playerName": "dustywusty",
  "code": "popcornfrog",
  "currency": "USD",
  "description": "1000 gems",
  "platform": "PC",
  "status": "Normal",
  "subtotal": 999,
  "transactionId": "d290f1ee-6c54-4b01-90e6-d701748f0851",
  "transactionDate": "2017-07-21T17:32:28Z",
  "metrics": {
    "joinDate": "2017-07-22T17:32:28.000Z",
    "conversion": {
      "lastPurchaseDate": "2023-12-14T07:57:18.000Z",
      "totalSpendToDate": {
        "total": 129.99,
        "currency": "USD"
      }
    }
  }
  },
  {
  "playerName": "dustywusty",
  "code": "samzorz",
  "currency": "USD",
  "description": "1000 gems",
  "platform": "PC",
  "status": "Normal",
  "subtotal": 999,
  "transactionId": "d290f1ee-6c54-4b01-90e6-d701748f0851",
  "transactionDate": "2017-07-21T17:32:28Z",
  "metrics": {
    "joinDate": "2018-04-12T09:12:08.000Z",
    "conversion": {
      "lastPurchaseDate": "2023-12-14T07:57:18.000Z",
      "totalSpendToDate": {
        "total": 129.99,
        "currency": "USD"
      }
    }
  }
  }]'
```

The status should be `200 OK` with a JSON response body that looks something like this, with an array of transactions this time:

```json
[{
    "transaction": {
        "currency": "USD",
        "description": "1000 gems",
        "id": "BqtOoyoIHEq39i3uph_nO",
        "platform": "PC",
        "subtotal": 999,
        "transactionDate": "2017-07-21T17:32:28Z",
        "transactionId": "d290f1ee-6c54-4b01-90e6-d701748f0851",
        "transactionStatus": "Normal",
        "memberId": "9jd7RBR_B2BZ0uWO3_lgv",
        "metrics": {
            "joinDate": "2017-07-22T17:32:28.000Z",
            "conversion": {
                "lastPurchaseDate": "2023-12-14T07:57:18.000Z",
                "totalSpendToDate": {
                    "total": 129.99,
                    "currency": "USD"
                }
            }
        }    
    }
},
{
    "transaction": {
        "currency": "USD",
        "description": "1000 gems",
        "id": "fAnaN2WVM9rcbXXQD1DHH",
        "platform": "PC",
        "subtotal": 999,
        "transactionDate": "2017-07-21T17:32:28Z",
        "transactionId": "d290f1ee-6c54-4b01-90e6-d701748f0851",
        "transactionStatus": "Normal",
        "memberId": "0Con-WN07cuBMdEkr56oo",
        "metrics": {
            "joinDate": "2017-07-22T17:32:28.000Z",
            "conversion": {
                "lastPurchaseDate": "2023-12-14T07:57:18.000Z",
                "totalSpendToDate": {
                    "total": 129.99,
                    "currency": "USD"
                }
            }
        }    
    }
}]
```

### Persisting a player's code

It is recommended that you persist the choice of code for ease of use in subsequent purchases.  You will need the code for display purposes when the player interacts with your code UI and, preferably, when creating a transaction for the player.

### Overriding member revenue share

There may be times where you need a member to receive a different revenue share on a transaction. The request body for the transactions POST endpoint has an optional property of `memberSharePercent` which, when included, will always be used when calculating the member's revenue share regardless of the settings for the group, the individual member, their tier, or SKU settings.

Using the example above, this is how a transaction would look if you wanted the member to receive 50% of the transaction subtotal.

```bash
curl -X 'POST' \
  'https://api.nexus.gg/v1/attributions/transactions' \
  -H 'accept: */*' \
  -H 'Content-Type: application/json' \
  -H 'X-SHARED-SECRET: nexus_sk_your_key_here' \
  -d '{
  "playerName": "dustywusty",
  "code": "popcornfrog",
  "currency": "USD",
  "description": "1000 gems",
  "status": "Normal",
  "subtotal": 999,
  "transactionId": "d290f1ee-6c54-4b01-90e6-d701748f0851",
  "transactionDate": "2017-07-21T17:32:28Z",
  "metrics": {
    "joinDate": "2017-07-22T17:32:28.000Z",
    "conversion": {
      "lastPurchaseDate": "2023-12-14T07:57:18.000Z",
      "totalSpendToDate": {
        "total": 129.99,
        "currency": "USD"
      }
    }
  },
  "memberSharePercent": 50
  }'
```

### Updating an existing transaction

Update and refund the transaction you just created.

This is another authenticated request with your private key to the `transactions/<transactionId>` endpoint.

<Aside type="danger">
Remember, private API keys should only be used server-side and never distributed with a game or client-facing application
</Aside>

This changes the status of the linked transaction.

<ApiMethod method="PATCH" path="/attributions/transactions/{transactionId}" />
<LinkCard title="View full reference" description="Parameters, responses, and status codes." href="/api/operations/updateattribution/" />

Here's how you call that with curl:

```bash
curl -X 'PATCH' \
  'https://api.nexus.gg/v1/attributions/transactions/d290f1ee-6c54-4b01-90e6-d701748f0851' \
  -H 'accept: */*' \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -H 'X-SHARED-SECRET: nexus_sk_your_key_here' \
  -d 'action=Refund'
```

The response status should be `200 OK` with a JSON response body that looks something like this:

```json
[{
    "transaction": {
        "currency": "USD",
        "description": "1000 gems",
        "id": "BqtOoyoIHEq39i3uph_nO",
        "platform": "PC",
        "subtotal": 999,
        "transactionDate": "2017-07-21T17:32:28Z",
        "transactionId": "d290f1ee-6c54-4b01-90e6-d701748f0851",
        "transactionStatus": "Normal",
        "memberId": "0Con-WN07cuBMdEkr56oo",
        "code": "popcornfrog",
        "metrics": {
            "joinDate": "2017-07-22T17:32:28.000Z",
            "conversion": {
                "lastPurchaseDate": "2023-12-14T07:57:18.000Z",
                "totalSpendToDate": {
                    "total": 129.99,
                    "currency": "USD"
                }
            }
        }    
    }
}]
```

If this transactionId was attributed to multiple members at once, you will instead receive an array of transactions in the response body.

## Retrieving transactions

You can list the transactions attributed to your program. This is an authenticated request with your private key.

<ApiMethod method="GET" path="/attributions/transactions" />
<LinkCard title="View full reference" description="Parameters, responses, and status codes." href="/api/operations/getbulkattributions/" />

### Pagination

By default, cursor pagination will be used and is recommended for better performance. If required, including a `page` in the query parameters (starting at `page=1`) will disable cursor pagination.

<Tabs syncKey="pagination">
<TabItem label="Cursor">
```typescript
const dataSet: Transaction[] = [];
let continueLoop = true;
let cursor: string | null = null;

while (continueLoop) {
  const response = await axios.get(
    `https://api.nexus.gg/v1/attributions/transactions${cursor ? `?cursor=${cursor}` : ""}`,
    {
      headers: {
        "X-SHARED-SECRET": "nexus_sk_your_key_here",
      },
    }
  );

  if (response.status === 200) {
    const data = response.data;
    if (data.transactions.length > 0) {
      dataSet.push(...data.transactions);
    }

    if (data.nextCursor) {
      cursor = data.nextCursor;
    } else {
      continueLoop = false;
    }
  } else {
    continueLoop = false;
  }
}
```
</TabItem>
<TabItem label="Pages">
```typescript
const dataSet: Transaction[] = [];
let continueLoop = true;
let page = 1;

while (continueLoop) {
  const response = await axios.get(
    `https://api.nexus.gg/v1/attributions/transactions?page=${page}`,
    {
      headers: {
        "X-SHARED-SECRET": "nexus_sk_your_key_here",
      },
    }
  );

  if (response.status === 200) {
    const data = response.data;
    if (data.transactions.length > 0) {
      dataSet.push(...data.transactions);
    }

    if (dataSet.length < data.totalCount) {
      page++;
    } else {
      continueLoop = false;
    }
  }
}
```
</TabItem>
</Tabs>

## Experimental features

These are features that have been recently released but have not yet seen large adoption.

### Floating decimal

A new feature lets you pass the currency and decimal total values in full. Using $9.99 as an example, USD would be provided as the currency and a subtotal of `9.99`. For zero-decimal currencies, JPY would be provided as the currency and a subtotal of `500`.

To use this feature, set `useLDCurrency = false` on the body of your attribution requests. `false` here needs to be a Boolean, not a string.

**Request body:**

```json
{
  "code": "dusty",
  "currency": "USD",
  "description": "20,000 Gems",
  "subtotal": 100.01,
  "transactionDate": "2024-10-01T03:43:37.192Z",
  "transactionId": "a8f5887e-031f-4135-98ec-2f5067b44d03",
  "total": 100.01,
  "totalCurrency": "USD",
  "platform": "PC",
  "useLDCurrency": false
}
```

**Response body:**

```json
{
  "transaction": {
    "creatorPaid": false,
    "currency": "USD",
    "description": "20,000 Gems",
    "skuId": null,
    "id": "a6Trf0qPfaYXydY9S_azQ",
    "memberId": "0Con-WN07cuBMdEkr56oo",
    "playerId": "",
    "playerName": "",
    "platform": "PC",
    "subtotal": 10001,
    "total": 10001,
    "totalCurrency": "USD",
    "transactionDate": "2024-10-01T03:43:37.192Z",
    "transactionId": "a8f5887e-031f-4135-98ec-2f5067b44d03",
    "transactionStatus": "Normal",
    "metrics": null,
    "code": "dusty"
  }
}
```

<Aside type="note">
The response body will still deal with cents, as that is how we process internally, but you will not have to worry about the conversion when making attribution requests if you are dealing with an API that returns decimal totals instead of cents.
</Aside>
