> ## Documentation Index
> Fetch the complete documentation index at: https://docs.chipipay.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Endpoints

> All Gift Cards API endpoints — create, validate, redeem, bulk, status.

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

***

## POST /gifts

Create a redeemable gift code. Credits are held from your org balance.

**Auth:** `Authorization: Bearer sk_...` or `x-api-key: pk_...`

**Cost:** No per-call fee. Credits held = `amount × maxRedeems + gas estimate`.

<CodeGroup>
  ```bash Request theme={null}
  curl -X POST https://api.chipipay.com/v1/gifts \
    -H "Authorization: Bearer sk_prod_YOUR_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "code": "WELCOME5",
      "name": "Welcome Bonus",
      "amount": 5,
      "token": "USDC",
      "chain": "STARKNET",
      "type": "GIFT_CARD",
      "maxRedeems": 100,
      "maxRedeemsPerUser": 1,
      "startsAt": "2026-01-01T00:00:00Z",
      "isActive": true
    }'
  ```

  ```json Response (201) theme={null}
  {
    "id": "a9bf75ca-de8b-489a-bdb0-88767bd7a47a",
    "code": "WELCOME5",
    "name": "Welcome Bonus",
    "amount": "5",
    "token": "USDC",
    "chain": "STARKNET",
    "type": "GIFT_CARD",
    "maxRedeems": 100,
    "maxRedeemsPerUser": 1,
    "totalRedeems": 0,
    "startsAt": "2026-01-01T00:00:00.000Z",
    "expiresAt": null,
    "isActive": true,
    "cctpFast": true,
    "holdLedgerEntryId": null,
    "totalHeldUsd": null,
    "totalRedeemedUsd": null,
    "recipientEmail": null,
    "campaignName": null
  }
  ```
</CodeGroup>

| Field               | Type    | Default       | Description                                               |
| ------------------- | ------- | ------------- | --------------------------------------------------------- |
| `code`              | string  | Required      | Unique gift code. Auto-generated if using bulk.           |
| `name`              | string  | Required      | Human-readable name.                                      |
| `amount`            | number  | Required      | USDC amount per redemption.                               |
| `token`             | string  | `"USDC"`      | Only USDC supported.                                      |
| `chain`             | string  | `"STARKNET"`  | Source chain for credits.                                 |
| `type`              | string  | `"GIFT_CARD"` | GIFT\_CARD, PROMOTIONAL, REFERRAL, LOYALTY, COMPENSATION. |
| `maxRedeems`        | number  | Required      | Total redemption limit across all users.                  |
| `maxRedeemsPerUser` | number  | Required      | Max redeems per wallet address.                           |
| `startsAt`          | string  | Required      | ISO 8601 date when the code becomes active.               |
| `expiresAt`         | string  | null          | Optional expiration date.                                 |
| `isActive`          | boolean | Required      | Can be toggled to disable the code.                       |

<Note>
  `cctpFast` (fast vs standard CCTP for Solana redeems) is **not configurable on single-create** today. The Gift row defaults to `cctpFast: true` server-side. To override, use `POST /gifts/bulk` (which does accept `cctpFast` in the request body) or the dashboard's bulk-airdrop flow.
</Note>

***

## POST /gifts/bulk

Create multiple gift codes + send claim emails. One gift per recipient.

**Auth:** `Authorization: Bearer sk_...` or `x-api-key: pk_...`

**Max:** 500 recipients per batch.

<CodeGroup>
  ```bash Request theme={null}
  curl -X POST https://api.chipipay.com/v1/gifts/bulk \
    -H "Authorization: Bearer sk_prod_YOUR_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "name": "May Airdrop",
      "amount": 5,
      "token": "USDC",
      "chain": "STARKNET",
      "type": "GIFT_CARD",
      "cctpFast": true,
      "recipients": [
        {"email": "alice@example.com"},
        {"email": "bob@example.com", "code": "BOB_SPECIAL"}
      ]
    }'
  ```

  ```json Response (201) theme={null}
  {
    "created": 2,
    "campaignName": "May Airdrop",
    "totalHeldUsd": 10.01,
    "gifts": [
      {"code": "A1B2C3D4", "email": "alice@example.com", "claimUrl": "https://dashboard.chipipay.com/claim/A1B2C3D4"},
      {"code": "BOB_SPECIAL", "email": "bob@example.com", "claimUrl": "https://dashboard.chipipay.com/claim/BOB_SPECIAL"}
    ]
  }
  ```
</CodeGroup>

Each recipient receives an email with a "Claim Your Gift" button linking to the claim page. Codes are auto-generated (8-char uppercase) unless you provide a custom code.

***

## GET /gifts/claim/:code

Validate a gift code. **No auth required** — the code is the credential.

Used by the claim page to show "You received \$5 USDC from Org Name" before the user enters their wallet.

```bash theme={null}
curl https://api.chipipay.com/v1/gifts/claim/WELCOME5
```

```json Response (200) theme={null}
{
  "valid": true,
  "gift": {
    "code": "WELCOME5",
    "name": "Welcome Bonus",
    "amount": "5",
    "token": "USDC",
    "chain": "STARKNET"
  },
  "orgName": "My App"
}
```

Invalid codes return:

```json theme={null}
{"valid": false, "reason": "Gift has expired"}
{"valid": false, "reason": "Gift redemption limit reached"}
{"valid": false, "reason": "Gift not found"}
```

Returns `{ "valid": false, "reason": "Gift has expired" }` if the code is invalid.

***

## POST /gifts/claim/:code/redeem

Redeem a gift code — sends USDC to the provided wallet address. **No auth required.**

<CodeGroup>
  ```bash Starknet (instant) theme={null}
  curl -X POST https://api.chipipay.com/v1/gifts/claim/WELCOME5/redeem \
    -H "Content-Type: application/json" \
    -d '{"walletAddress": "0x...", "chain": "starknet"}'
  ```

  ```bash Solana (CCTP, ~24 sec) theme={null}
  curl -X POST https://api.chipipay.com/v1/gifts/claim/WELCOME5/redeem \
    -H "Content-Type: application/json" \
    -d '{"walletAddress": "FZQq...", "chain": "solana"}'
  ```
</CodeGroup>

| Chain      | Response                           | Time     |
| ---------- | ---------------------------------- | -------- |
| `starknet` | 201 — instant, tx hash in response | \~3 sec  |
| `solana`   | 202 — CCTP bridge, poll status     | \~24 sec |

**Starknet response (201):**

```json theme={null}
{
  "giftRedeem": {
    "id": "...",
    "status": "SUCCESS",
    "transactionHash": "0x...",
    "walletAddress": "0x...",
    "amount": "5"
  }
}
```

**Solana response (202):**

```json theme={null}
{
  "redeemId": "...",
  "status": "BRIDGING",
  "destinationChain": "solana",
  "cctpBurnTxHash": "0x...",
  "estimatedSeconds": 24
}
```

***

## GET /gifts/claim/:code/status/:redeemId

Poll cross-chain redeem status. **No auth required.**

```bash theme={null}
curl https://api.chipipay.com/v1/gifts/claim/WELCOME5/status/REDEEM_ID
```

```json theme={null}
{
  "id": "...",
  "status": "SUCCESS",
  "destinationChain": "solana",
  "cctpBurnTxHash": "0x...",
  "receiveChainTxHash": "3xxK3y...",
  "amount": 5
}
```

Status flow: `PENDING → BRIDGING → ATTESTED → SUCCESS`

If `FAILED`: the Starknet burn tx is in `cctpBurnTxHash` — the funds may still be recoverable.

***

## GET /gifts

List all gift codes for your org.

**Auth:** Required (sk\_/pk\_)

```bash theme={null}
curl https://api.chipipay.com/v1/gifts \
  -H "Authorization: Bearer sk_prod_YOUR_KEY"
```

***

## PATCH /gifts/:id

Update a gift (toggle active, change name, expiry).

**Auth:** Required (sk\_/pk\_)

***

## DELETE /gifts/:id

Delete a gift and release held credits.

**Auth:** Required (sk\_/pk\_)

***

## Error handling

| HTTP Status | Meaning                                           |
| ----------- | ------------------------------------------------- |
| 201         | Gift created / Starknet redeem success            |
| 202         | Cross-chain redeem initiated (poll status)        |
| 400         | Invalid code, limit reached, insufficient credits |
| 404         | Gift or redeem not found                          |
| 500         | Server error (check manager wallet balance)       |
