---
title: "Every successful mint on a contract by NimbusMint users from your app, one row each"
description: "GET /mints"
canonical: "https://docs.nimbusmint.bot/api/operations/getmints/"
---
> Index: https://docs.nimbusmint.bot/llms.txt

# Every successful mint on a contract by NimbusMint users from your app, one row each

`GET https://api.nimbusmint.bot/partner/v1/mints`

The rows behind `/hits`: one row per hit (a mint task booked through
your app that completed successfully on this contract in the
window, timed by when it completed), with the user's full identity,
the wallet it minted from and the confirmed transaction. These are
your users' personal data: mask them yourself before showing them to
anyone else.

Rows are ordered oldest first by `completed_at` (ties in a stable
order). Pages hold at most `limit` rows; when `next_cursor` is not
null, pass it as `cursor` with the same other parameters to get the
next page. A task that completes later always sorts after the rows
already served, so you can keep a cursor and resume from it. The
cursor is opaque; do not build or edit one.

`contract`, `since`, `until` and `chain_id` behave exactly as on
`/hits`. Not cached. Requires scope `read:hits`.

## Authentication

- `privateKey`: `Authorization: Bearer nmk_live_<id>_<secret>`: `<id>` is 12 characters (the key id shown to you is `nmk_<id>`), `<secret>` 64 hex characters. The full token is shown once, when the key is issued; we store only a hash of it and cannot show it again. The key works only from the addresses on its IP allowlist (public IPv4 /24 or narrower, IPv6 /48 or narrower, at most 16 entries). It expires on its `expires_at` (at most one year after issue), and a revoked key stops working within 10 seconds. Keep it on your servers; never put it in a client.

## Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `contract` | query | string | yes | Contract address, 0x-prefixed, any case. Example `0x000000000000000000000000000000000000dead`. |
| `since` | query | string (date-time) | yes | Window start (inclusive), RFC 3339, floored to the minute. Example `2026-10-08T15:00:00Z`. |
| `until` | query | string (date-time) | no | Window end (exclusive), RFC 3339, floored to the minute. Defaults to now; a future time is clamped to now. The window may span at most 31 days unless your agreement sets another limit (`window_too_large`). |
| `chain_id` | query | integer | no | Only this chain. Omitted, every chain. Minimum 1. Example `33139`. |
| `limit` | query | integer | no | Rows per page. Default `100`. Range 1 to 500. |
| `cursor` | query | string | no | The `next_cursor` of the previous page. Omitted, the first page. |

## Responses

### 200

One page of hits.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `contract` | string | yes | The contract, lowercased. |
| `since` | string (date-time) | yes |  |
| `until` | string (date-time) | yes |  |
| `mints` | object[] | yes |  |
| `mints[].task_id` | string | yes | The NimbusMint mint task id. |
| `mints[].user_id` | string | yes | The NimbusMint account id. Today it equals the Discord id. |
| `mints[].discord_id` | string | yes | The user's Discord id; empty if the account record is missing. |
| `mints[].discord_username` | string | yes | The user's Discord username as last seen at login; empty if unknown. |
| `mints[].wallet` | string | yes | The address that minted, lowercase; empty for tasks that did not record one. |
| `mints[].chain_id` | integer | yes |  |
| `mints[].contract` | string | yes | The contract, lowercased. |
| `mints[].tx_hash` | string | yes | The transaction hash on the task when it completed (the landed hash when one was recorded, otherwise the submitted one). May be empty. |
| `mints[].quantity` | integer | yes | Tokens the task was booked to mint (a hit is the task, whatever its quantity). |
| `mints[].completed_at` | string (date-time) | yes | When the receipt was confirmed, RFC 3339 with up to millisecond precision (trailing zeros trimmed, so the width varies). |
| `next_cursor` | string \| null | yes | Pass as `cursor` for the next page; null on the last page. |
| `generated_at` | string (date-time) | yes |  |

Example `mints` (A page with more to come):

```json
{
  "contract": "0x000000000000000000000000000000000000dead",
  "since": "2026-10-08T15:00:00Z",
  "until": "2026-10-08T18:42:00Z",
  "mints": [
    {
      "task_id": "7d1f0c9e-4b8a-4f43-9a51-2f7c0b9d1e22",
      "user_id": "100000000000000001",
      "discord_id": "100000000000000001",
      "discord_username": "alice",
      "wallet": "0x1111111111111111111111111111111111111111",
      "chain_id": 33139,
      "contract": "0x000000000000000000000000000000000000dead",
      "tx_hash": "0x5c4e0f0a8b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e",
      "quantity": 2,
      "completed_at": "2026-10-08T15:00:01.234Z"
    }
  ],
  "next_cursor": "MTc1OTkzNTYwMTIzNC42NmZmMDAwMDAwMDAwMDAwMDAwMDAwMDE",
  "generated_at": "2026-10-08T18:42:07Z"
}
```

### 400

The query is invalid (`invalid_request`) or the window is longer than allowed (`window_too_large`).

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `code` | string | yes | One of: `invalid_key`, `ip_not_allowed`, `scope_missing`, `rate_limited`, `ip_trust_unconfigured`, `tenant_api_disabled`, `invalid_request`, `window_too_large`, `not_found`, `internal`. |
| `message` | string | yes |  |

Example `window`:

```json
{
  "code": "window_too_large",
  "message": "the window may span at most 31 days"
}
```

### 401

The key is missing, malformed, unknown, expired or revoked, or its partner is disabled. Always `invalid_key`.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `code` | string | yes | One of: `invalid_key`, `ip_not_allowed`, `scope_missing`, `rate_limited`, `ip_trust_unconfigured`, `tenant_api_disabled`, `invalid_request`, `window_too_large`, `not_found`, `internal`. |
| `message` | string | yes |  |

Example `invalid`:

```json
{
  "code": "invalid_key",
  "message": "missing, invalid, expired or revoked key"
}
```

### 403

The calling address is not on the key's allowlist (`ip_not_allowed`), or the key lacks the route's scope (`scope_missing`).

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `code` | string | yes | One of: `invalid_key`, `ip_not_allowed`, `scope_missing`, `rate_limited`, `ip_trust_unconfigured`, `tenant_api_disabled`, `invalid_request`, `window_too_large`, `not_found`, `internal`. |
| `message` | string | yes |  |

Example `ip`:

```json
{
  "code": "ip_not_allowed",
  "message": "this address may not use this key"
}
```

### 429

The key's rate limit, or the API's overall limit, is exceeded (`rate_limited`).

Headers:

- `Retry-After`: Seconds to wait before retrying.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `code` | string | yes | One of: `invalid_key`, `ip_not_allowed`, `scope_missing`, `rate_limited`, `ip_trust_unconfigured`, `tenant_api_disabled`, `invalid_request`, `window_too_large`, `not_found`, `internal`. |
| `message` | string | yes |  |

Example `limited`:

```json
{
  "code": "rate_limited",
  "message": "rate limit exceeded"
}
```

### 503

The API is switched off (`tenant_api_disabled`), not configured (`ip_trust_unconfigured`) or temporarily unable to answer (`internal`). Retry later; `Retry-After` is sent when a retry is expected to succeed soon.

Headers:

- `Retry-After`: Seconds to wait before retrying.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `code` | string | yes | One of: `invalid_key`, `ip_not_allowed`, `scope_missing`, `rate_limited`, `ip_trust_unconfigured`, `tenant_api_disabled`, `invalid_request`, `window_too_large`, `not_found`, `internal`. |
| `message` | string | yes |  |

Example `disabled`:

```json
{
  "code": "tenant_api_disabled",
  "message": "the partner API is disabled"
}
```

## Errors

| Status | `code` | Meaning |
| --- | --- | --- |
| 400 | `window_too_large` | The query is invalid (`invalid_request`) or the window is longer than allowed (`window_too_large`). |
| 400 | `invalid_request` | The query is invalid (`invalid_request`) or the window is longer than allowed (`window_too_large`). |
| 401 | `invalid_key` | The key is missing, malformed, unknown, expired or revoked, or its partner is disabled. Always `invalid_key`. |
| 403 | `ip_not_allowed` | The calling address is not on the key's allowlist (`ip_not_allowed`), or the key lacks the route's scope (`scope_missing`). |
| 403 | `scope_missing` | The calling address is not on the key's allowlist (`ip_not_allowed`), or the key lacks the route's scope (`scope_missing`). |
| 429 | `rate_limited` | The key's rate limit, or the API's overall limit, is exceeded (`rate_limited`). |
| 503 | `tenant_api_disabled` | The API is switched off (`tenant_api_disabled`), not configured (`ip_trust_unconfigured`) or temporarily unable to answer (`internal`). Retry later; `Retry-After` is sent when a retry is expected to succeed soon. |
| 503 | `ip_trust_unconfigured` | The API is switched off (`tenant_api_disabled`), not configured (`ip_trust_unconfigured`) or temporarily unable to answer (`internal`). Retry later; `Retry-After` is sent when a retry is expected to succeed soon. |
| 503 | `internal` | The API is switched off (`tenant_api_disabled`), not configured (`ip_trust_unconfigured`) or temporarily unable to answer (`internal`). Retry later; `Retry-After` is sent when a retry is expected to succeed soon. |

What to do about each: [Errors](https://docs.nimbusmint.bot/errors.md).

## Example request

### curl

```sh
curl -G "https://api.nimbusmint.bot/partner/v1/mints" \
  -H "Authorization: Bearer $NIMBUS_PRIVATE_KEY" \
  --data-urlencode "contract=0x000000000000000000000000000000000000dead" \
  --data-urlencode "since=2026-10-08T15:00:00Z"
```

### Node

```js
// Node 18+ (built-in fetch). Keep the key on your server.
const url = new URL('https://api.nimbusmint.bot/partner/v1/mints');
url.search = new URLSearchParams({
  contract: '0x000000000000000000000000000000000000dead',
  since: '2026-10-08T15:00:00Z',
});
const res = await fetch(url, {
  headers: { Authorization: `Bearer ${process.env.NIMBUS_PRIVATE_KEY}` },
});
console.log(res.status, await res.json());
```

### Python

```python
import os
import requests

res = requests.get(
    "https://api.nimbusmint.bot/partner/v1/mints",
    headers={"Authorization": f"Bearer {os.environ['NIMBUS_PRIVATE_KEY']}"},
    params={
        "contract": "0x000000000000000000000000000000000000dead",
        "since": "2026-10-08T15:00:00Z",
    },
    timeout=10,
)
print(res.status_code, res.json())
```
