Menu

Merchant Onboarding

Create merchants, verify domain ownership, configure discount tiers, buy credits with USDC, and publish to the directory. All via API. No dashboard needed.

Configures merchants for the verification and commerce endpoints.

Building this in Claude Code? Install the wallet auth skill and Claude will write correct, signature-verifying integration code on the first try.

smithery skill add douglasborthwick/insumer-skill

View on Smithery · GitHub repo

What this does

Register merchants, prove domain ownership, set up token and NFT discount tiers, and make them discoverable in the public directory. Designed for AI agents that onboard businesses autonomously.

Zero to first discount

  1. Get a free API key (use the form below) — or if you’re an AI agent, buy a key autonomously with USDC via POST /v1/keys/buy (no email needed)
  2. Test an attestation: POST /v1/attest with any wallet and condition
  3. Create a merchant: POST /v1/merchants with your company name
  4. Configure token tiers: PUT /v1/merchants/:id/tokens with at least one tier
  5. Generate a discount: POST /v1/acp/discount with a wallet that qualifies

Domain verification and directory publishing are optional. You can generate discounts as soon as tokens are configured.

Onboarding flow

1

Create

POST /v1/merchants with companyName and companyId

2

Verify Domain

POST then PUT /v1/merchants/:id/domain-verification

3

Configure Tokens

PUT /v1/merchants/:id/tokens with tiers

4

Configure NFTs

PUT /v1/merchants/:id/nfts (optional)

5

Update Settings

PUT /v1/merchants/:id/settings (discountMode, cap, USDC)

6

Publish

POST /v1/merchants/:id/directory

Endpoint reference

POST /v1/merchants

Create Merchant

Creates a new merchant account. Returns 100 free credits and enables API access immediately.

ParameterTypeDescription
companyNamestring requiredBusiness name. Max 100 characters.
companyIdstring requiredUnique slug. 2-50 characters, alphanumeric, dash, or underscore.
locationstring optionalBusiness location. Max 200 characters.
Request
curl -X POST https://api.insumermodel.com/v1/merchants \
  -H "Content-Type: application/json" \
  -H "x-api-key: YOUR_API_KEY" \
  -d '{
    "companyName": "Acme Coffee",
    "companyId": "acme-coffee",
    "location": "New York, NY"
  }'
Response
{
  "ok": true,
  "data": {
    "id": "abc123",
    "companyName": "Acme Coffee",
    "credits": 100,
    "apiAccessEnabled": true
  },
  "meta": { "version": "1.0", "timestamp": "2026-02-27T12:00:00.000Z" }
}
POST /v1/merchants/:id/domain-verification

Request Verification Token

Generates a verification token and returns instructions for DNS, meta tag, and file-based domain verification.

ParameterTypeDescription
domainstring requiredDomain to verify. No protocol prefix (e.g. acme.com not https://acme.com).
Request
curl -X POST https://api.insumermodel.com/v1/merchants/abc123/domain-verification \
  -H "Content-Type: application/json" \
  -H "x-api-key: YOUR_API_KEY" \
  -d '{
    "domain": "acme.com"
  }'
Response
{
  "ok": true,
  "data": {
    "domain": "acme.com",
    "token": "abc123xyz",
    "methods": {
      "dns": {
        "type": "TXT",
        "host": "acme.com",
        "value": "abc123xyz",
        "instructions": "Add a TXT record..."
      },
      "meta": {
        "tag": "<meta name=\"insumer-verification\" content=\"abc123xyz\">",
        "instructions": "Add this meta tag inside <head>"
      },
      "file": {
        "path": "/insumer-verify.txt",
        "content": "abc123xyz",
        "instructions": "Host file at /insumer-verify.txt"
      }
    }
  },
  "meta": { "version": "1.0", "timestamp": "2026-02-27T12:00:00.000Z" }
}
PUT /v1/merchants/:id/domain-verification

Trigger Verification

Checks whether the verification token is present at the domain. Rate limited to 5 attempts per hour.

No request body. Send an empty PUT.

Request
curl -X PUT https://api.insumermodel.com/v1/merchants/abc123/domain-verification \
  -H "x-api-key: YOUR_API_KEY"
Response (verified)
{
  "ok": true,
  "data": {
    "verified": true,
    "domain": "acme.com",
    "method": "dns"
  },
  "meta": { "version": "1.0", "timestamp": "2026-02-27T12:00:00.000Z" }
}

// Response (not verified):
{
  "ok": true,
  "data": {
    "verified": false,
    "message": "Token not found",
    "attemptsRemaining": 4
  },
  "meta": { "version": "1.0", "timestamp": "2026-02-27T12:00:00.000Z" }
}
PUT /v1/merchants/:id/tokens

Configure Tokens

Sets the merchant's own token and partner token discount tiers. Maximum 8 tokens total. Tiers must be in ascending threshold order with discounts between 1% and 50%.

ParameterTypeDescription
ownTokenobject optionalMerchant's own token: symbol, chainId (number, "solana", or "xrpl"), contractAddress, decimals, tiers array of {name, threshold, discount}. For XRPL trust line tokens, include currency (hex-padded currency code) and use the issuer r-address as contractAddress. For native XRP, use contractAddress: "native".
partnerTokensarray optionalPartner tokens. Same structure as ownToken. Combined total max 8.
Request
curl -X PUT https://api.insumermodel.com/v1/merchants/abc123/tokens \
  -H "Content-Type: application/json" \
  -H "x-api-key: YOUR_API_KEY" \
  -d '{
    "ownToken": {
      "symbol": "ACME",
      "chainId": 1,
      "contractAddress": "0x1234...abcd",
      "decimals": 18,
      "tiers": [
        { "name": "Bronze", "threshold": 100, "discount": 5 },
        { "name": "Silver", "threshold": 500, "discount": 10 },
        { "name": "Gold", "threshold": 1000, "discount": 15 }
      ]
    },
    "partnerTokens": [{
      "symbol": "USDC",
      "chainId": 1,
      "contractAddress": "0xA0b8...eB48",
      "decimals": 6,
      "tiers": [
        { "name": "Holder", "threshold": 100, "discount": 3 }
      ]
    }]
  }'
Response
{
  "ok": true,
  "data": {
    "ownToken": {
      "symbol": "ACME",
      "tiersConfigured": 3
    },
    "partnerTokens": [
      { "symbol": "USDC", "tiersConfigured": 1 }
    ],
    "totalTokens": 2,
    "maxTokens": 8
  },
  "meta": { "version": "1.0", "timestamp": "2026-02-27T12:00:00.000Z" }
}
PUT /v1/merchants/:id/nfts

Configure NFTs

Sets NFT collection discounts. Maximum 4 collections with discounts between 1% and 50%.

ParameterTypeDescription
nftCollectionsarray requiredArray of {name, contractAddress, chainId, discount}. Max 4 collections. chainId accepts a number, "solana", or "xrpl". For XRPL NFTs, use the issuer r-address as contractAddress and optionally include taxon.
Request
curl -X PUT https://api.insumermodel.com/v1/merchants/abc123/nfts \
  -H "Content-Type: application/json" \
  -H "x-api-key: YOUR_API_KEY" \
  -d '{
    "nftCollections": [{
      "name": "Acme Members",
      "contractAddress": "0x5678...efgh",
      "chainId": 1,
      "discount": 20
    }]
  }'
Response
{
  "ok": true,
  "data": {
    "nftCollections": [
      {
        "name": "Acme Members",
        "chainId": 1,
        "discount": 20
      }
    ],
    "totalCollections": 1,
    "maxCollections": 4
  },
  "meta": { "version": "1.0", "timestamp": "2026-02-27T12:00:00.000Z" }
}
PUT /v1/merchants/:id/settings

Update Settings

Updates merchant discount mode, cap, and USDC payment configuration. All parameters are optional.

ParameterTypeDescription
discountModestring optional"highest" (best single discount) or "stack" (sum all qualifying discounts).
discountCapnumber optionalMaximum total discount percentage. 1 to 100.
usdcPaymentobject optional{enabled, evmAddress, solanaAddress, preferredChainId}. All sub-fields optional.
Request
curl -X PUT https://api.insumermodel.com/v1/merchants/abc123/settings \
  -H "Content-Type: application/json" \
  -H "x-api-key: YOUR_API_KEY" \
  -d '{
    "discountMode": "highest",
    "discountCap": 25,
    "usdcPayment": {
      "enabled": true,
      "evmAddress": "0x47aD...14E9",
      "preferredChainId": 8453
    }
  }'
Response
{
  "ok": true,
  "data": {
    "discountMode": "highest",
    "discountCap": 25,
    "usdcPayment": {
      "enabled": true
    }
  },
  "meta": { "version": "1.0", "timestamp": "2026-02-27T12:00:00.000Z" }
}
POST /v1/merchants/:id/credits

Buy Credits with USDC

Submit a USDC transaction hash to purchase verification credits. Volume discounts: $5–$99 = $0.04/call (25 credits/$1), $100–$499 = $0.03 (33/$1, 25% off), $500+ = $0.02 (50/$1, 50% off). USDC sent on unsupported chains cannot be recovered. Non-refundable.

ParameterTypeDescription
txHashstring requiredUSDC transaction hash.
chainIdnumber | "solana" requiredChain ID (e.g. 1, 8453) or "solana". Supported: ETH, Base, Polygon, Arbitrum, Optimism, BNB, Avalanche, Solana.
amountnumber requiredUSDC amount. Minimum 5.
updateWalletboolean optionalSet to true to change the registered sender wallet.

Sender verification: The first purchase registers the sender wallet to the API key. Subsequent purchases must come from the same sender. To change the registered wallet, include "updateWallet": true—the verified transfer proves ownership.

See platform wallet addresses and supported chains →

Request
curl -X POST https://api.insumermodel.com/v1/merchants/abc123/credits \
  -H "Content-Type: application/json" \
  -H "x-api-key: YOUR_API_KEY" \
  -d '{
    "txHash": "0xabc...def",
    "chainId": 8453,
    "amount": 10
  }'
Response
{
  "ok": true,
  "data": {
    "creditsAdded": 250,
    "totalCredits": 350,
    "usdcPaid": "10",
    "chainName": "Base"
  },
  "meta": { "version": "1.0", "timestamp": "2026-02-27T12:00:00.000Z" }
}
POST /v1/merchants/:id/directory

Publish to Directory

Publishes the merchant to the public directory, making it discoverable by wallets and agents. No request body needed.

Request
curl -X POST https://api.insumermodel.com/v1/merchants/abc123/directory \
  -H "x-api-key: YOUR_API_KEY"
Response
{
  "ok": true,
  "data": {
    "id": "abc123",
    "published": true,
    "tokensListed": 2,
    "nftCollectionsListed": 1
  },
  "meta": { "version": "1.0", "timestamp": "2026-02-27T12:00:00.000Z" }
}
GET /v1/merchants/:id/status

Get Merchant Status

Returns the full private details of a merchant, including credit balance, directory listing status, token configuration, and discount settings.

Request
curl https://api.insumermodel.com/v1/merchants/abc123/status \
  -H "x-api-key: YOUR_API_KEY"
Response
{
  "ok": true,
  "data": {
    "id": "abc123",
    "companyName": "Acme Coffee",
    "location": "San Francisco, CA",
    "credits": 350,
    "apiAccessEnabled": true,
    "createdAt": "2026-02-20T10:00:00.000Z",
    "discountMode": "highest",
    "discountCap": 25,
    "listedInDirectory": true,
    "ownToken": {
      "symbol": "ACME",
      "chainId": 1,
      "tiers": [/* ... */]
    },
    "partnerTokens": [/* ... */],
    "nftCollections": [/* ... */],
    "usdcPayment": { "enabled": true },
    "verification": { "status": "verified", "domain": "acme.com" }
  },
  "meta": { "version": "1.0", "timestamp": "2026-02-27T12:00:00.000Z" }
}

See how this endpoint fits the full API → API Topology