---
title: "Configure merchant token tiers"
method: PUT
path: "/v1/merchants/{id}/tokens"
tags: ["Merchant Setup"]
---

# Configure merchant token tiers

`PUT /v1/merchants/{id}/tokens`

## Request

- Base URL: `https://api.insumermodel.com`
- URL: `https://api.insumermodel.com/v1/merchants/{id}/tokens`
- Auth: API key in header `X-API-Key`

Set up the merchant's own token and/or partner tokens with discount tiers. Max 8 tokens total (own + partner). Must be called by the API key that created the merchant.

## Path parameters

- `id` string, required

## Request body

- object
  - `ownToken` TokenConfig
    - `symbol` string, required
    - `name` string: Optional display name shown in the public directory listing (without it the entry shows a bare symbol).
    - `logo` string: Optional logo URL shown in the public directory listing.
    - `chainId` union, required: Chains supported for merchant token/NFT configuration: all 31 EVM chains (same integer IDs as ChainId) plus Solana ("solana") and XRP Ledger ("xrpl"). Bitcoin, Tron, Stellar, and Sui are not available for merchant registry configuration, though they remain queryable via /v1/attest and /v1/trust.
      - 1 | 56 | 8453 | 43114 | 137 | 42161 | 10 | 88888 | 1868 | 98866 | 146 | 100 | 5000 | 534352 | 59144 | 324 | 81457 | 167000 | 2020 | 42220 | 88 | 204 | 480 | 130 | 57073 | 1329 | 80094 | 33139 | 50 | 4663 | 5042
      - 'solana' | 'xrpl'
    - `contractAddress` string, required: Token address, validated per chain: 0x + 40 hex on EVM chains, or "native" for the chain's own coin (ETH on Ethereum or Base, POL on Polygon); on Solana "native" for SOL or the mint address (base58, 32 to 44 characters); on XRPL "native" for XRP or the issuer r-address, whose base58 checksum is verified. Anything else is a 400.
    - `decimals` integer, required: Token decimals. Required; a missing or non-numeric value is rejected with 400. When a discount is evaluated the token's decimals are read from the chain; this stored value is not used.
    - `currency` string: XRPL trust line currency code (e.g. "USD", "RLUSD"). Required for XRPL trust line tokens. Enter the currency code exactly as the issuer created it. Codes are case-sensitive, and the code is stored as entered. It is validated by the same rule as the `currency` of an attest condition: a 3-character standard code, a token name of 1 to 20 printable ASCII characters, or a 40-character hex code; anything else is a 400, and so is `XRP`, which is the native coin (use contractAddress "native").
    - `tiers` Tier[], required
      - `name` string, required
      - `threshold` number, required
      - `discount` integer, required: Discount percentage: a whole number from 1 to 50, as a JSON number or its digits as a string. A value with a fraction (10.5) is a 400; "10.0" is accepted as 10.
    - `alsoOn` object[]: Optional. The same token on other networks, each as { chainId, contractAddress }: EVM chains and Solana, not the XRP Ledger and not a chain's native coin. The discount check and the verification (verify, ACP, UCP) read every network listed plus the token's own, add the balances exactly, and award the token's tier once, so the token appears once in the breakdown and uses one of the 8 token slots. The store decides which deployments count as the same token; each network's balance is read in that token's own decimals there. A read that fails on any listed network refuses the whole check (503 rpc_failure), never a total from the networks that answered. Leave it out and only chainId and contractAddress are read, as before. A network listed twice, or already listed by another token, is a 400. Not available on an XRP Ledger token.
      - `chainId` union, required: Chains supported for merchant token/NFT configuration: all 31 EVM chains (same integer IDs as ChainId) plus Solana ("solana") and XRP Ledger ("xrpl"). Bitcoin, Tron, Stellar, and Sui are not available for merchant registry configuration, though they remain queryable via /v1/attest and /v1/trust.
        - 1 | 56 | 8453 | 43114 | 137 | 42161 | 10 | 88888 | 1868 | 98866 | 146 | 100 | 5000 | 534352 | 59144 | 324 | 81457 | 167000 | 2020 | 42220 | 88 | 204 | 480 | 130 | 57073 | 1329 | 80094 | 33139 | 50 | 4663 | 5042
        - 'solana' | 'xrpl'
      - `contractAddress` string, required: 0x + 40 hex on EVM chains, or the mint address on Solana.
    - `enabled` boolean: Read on ownToken only. `false` switches the own token off (the same as sending ownToken as null), and the other fields are then not required. `true`, or leaving it out, saves the token switched on. Any other value is a 400; text such as "true" or "false" is not a boolean.
  - `partnerTokens` TokenConfig[]: Partner token configs
    - `symbol` string, required
    - `name` string: Optional display name shown in the public directory listing (without it the entry shows a bare symbol).
    - `logo` string: Optional logo URL shown in the public directory listing.
    - `chainId` union, required: Chains supported for merchant token/NFT configuration: all 31 EVM chains (same integer IDs as ChainId) plus Solana ("solana") and XRP Ledger ("xrpl"). Bitcoin, Tron, Stellar, and Sui are not available for merchant registry configuration, though they remain queryable via /v1/attest and /v1/trust.
      - 1 | 56 | 8453 | 43114 | 137 | 42161 | 10 | 88888 | 1868 | 98866 | 146 | 100 | 5000 | 534352 | 59144 | 324 | 81457 | 167000 | 2020 | 42220 | 88 | 204 | 480 | 130 | 57073 | 1329 | 80094 | 33139 | 50 | 4663 | 5042
      - 'solana' | 'xrpl'
    - `contractAddress` string, required: Token address, validated per chain: 0x + 40 hex on EVM chains, or "native" for the chain's own coin (ETH on Ethereum or Base, POL on Polygon); on Solana "native" for SOL or the mint address (base58, 32 to 44 characters); on XRPL "native" for XRP or the issuer r-address, whose base58 checksum is verified. Anything else is a 400.
    - `decimals` integer, required: Token decimals. Required; a missing or non-numeric value is rejected with 400. When a discount is evaluated the token's decimals are read from the chain; this stored value is not used.
    - `currency` string: XRPL trust line currency code (e.g. "USD", "RLUSD"). Required for XRPL trust line tokens. Enter the currency code exactly as the issuer created it. Codes are case-sensitive, and the code is stored as entered. It is validated by the same rule as the `currency` of an attest condition: a 3-character standard code, a token name of 1 to 20 printable ASCII characters, or a 40-character hex code; anything else is a 400, and so is `XRP`, which is the native coin (use contractAddress "native").
    - `tiers` Tier[], required
      - `name` string, required
      - `threshold` number, required
      - `discount` integer, required: Discount percentage: a whole number from 1 to 50, as a JSON number or its digits as a string. A value with a fraction (10.5) is a 400; "10.0" is accepted as 10.
    - `alsoOn` object[]: Optional. The same token on other networks, each as { chainId, contractAddress }: EVM chains and Solana, not the XRP Ledger and not a chain's native coin. The discount check and the verification (verify, ACP, UCP) read every network listed plus the token's own, add the balances exactly, and award the token's tier once, so the token appears once in the breakdown and uses one of the 8 token slots. The store decides which deployments count as the same token; each network's balance is read in that token's own decimals there. A read that fails on any listed network refuses the whole check (503 rpc_failure), never a total from the networks that answered. Leave it out and only chainId and contractAddress are read, as before. A network listed twice, or already listed by another token, is a 400. Not available on an XRP Ledger token.
      - `chainId` union, required: Chains supported for merchant token/NFT configuration: all 31 EVM chains (same integer IDs as ChainId) plus Solana ("solana") and XRP Ledger ("xrpl"). Bitcoin, Tron, Stellar, and Sui are not available for merchant registry configuration, though they remain queryable via /v1/attest and /v1/trust.
        - 1 | 56 | 8453 | 43114 | 137 | 42161 | 10 | 88888 | 1868 | 98866 | 146 | 100 | 5000 | 534352 | 59144 | 324 | 81457 | 167000 | 2020 | 42220 | 88 | 204 | 480 | 130 | 57073 | 1329 | 80094 | 33139 | 50 | 4663 | 5042
        - 'solana' | 'xrpl'
      - `contractAddress` string, required: 0x + 40 hex on EVM chains, or the mint address on Solana.
    - `enabled` boolean: Read on ownToken only. `false` switches the own token off (the same as sending ownToken as null), and the other fields are then not required. `true`, or leaving it out, saves the token switched on. Any other value is a 400; text such as "true" or "false" is not a boolean.

## Response `200`

Tokens configured

- object
  - `ok` true
  - `data` object
    - `ownToken` object, nullable
      - `symbol` string
      - `tiersConfigured` integer
    - `partnerTokens` object[]
    - `totalTokens` integer
    - `maxTokens` integer
  - `meta` Meta
    - `version` string
    - `timestamp` string, date-time

## Other responses

- `400`: Validation error
- `401`: Invalid or missing API key
- `403`: API key does not own this merchant
- `404`: Merchant not found
- `429`: Rate limit exceeded. API-key requests count against the key's daily limit; every authenticated response carries X-RateLimit-Limit and X-RateLimit-Remaining headers, and a 429 additionally carries Retry-After (seconds until the window resets).
- `500`: Unexpected server error. Safe to retry; no credits are charged on a 500. Router endpoints return the standard error envelope; standalone endpoints (the ones whose 200 is a flat object) return a flat {"error": "..."} object.

---

[API](https://skmtc.dev/insumermodel/apis/insumerapi.md) · [All operations](https://skmtc.dev/insumermodel/apis/insumerapi/llms.txt) · [OpenAPI document](https://skmtc.dev/insumermodel/apis/insumerapi/revisions/91f56fe9e3d8?raw)
