Return discount data in OpenAI ACP or Google UCP format so AI shopping agents can apply token-holder discounts natively. Same on-chain verification, standard protocol output.
Combines signed attestation with protocol-native discount output.
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
Generate discount codes from on-chain token holdings in standard commerce protocol formats. ACP-compatible agents get Stripe coupon objects. UCP-compatible agents get Google commerce extensions. Every response is ECDSA-signed using the same key and verification flow as POST /v1/attest.
Commerce endpoints consume merchant credits (1 per call, $0.04). These belong to the merchant, separate from API key credits used by attest/trust endpoints.
POST /v1/acp/discount or POST /v1/ucp/discount with wallet address and merchantId. The API checks on-chain balances against the merchant's configured tiers.
Response includes an INSR-XXXXX discount code wrapped in the protocol-native format. ACP returns Stripe coupon objects. UCP returns Google commerce extensions.
Merchant backend calls GET /v1/codes/{code} to confirm the code is valid, unexpired, and unused before applying the discount.
Verifies token holdings and returns the result in OpenAI ACP format. Returns Stripe-style coupon objects with applied and rejected arrays. Costs 1 merchant credit per call. Response is ECDSA-signed.
| Parameter | Type | Required | Description |
|---|---|---|---|
merchantId |
string | Required | Firestore merchant document ID |
wallet |
string | Required* | EVM wallet address (0x...). Required unless solanaWallet or xrplWallet is provided. |
solanaWallet |
string | Optional | Solana wallet address. Use instead of wallet for Solana-based merchants. |
xrplWallet |
string | Optional | XRPL wallet address (r-address). Use for XRP Ledger-based merchants. |
items |
array | Optional | Cart items with path and amount fields. Used for item-level discount context. |
curl -X POST \ https://api.insumermodel.com/v1/acp/discount \ -H "Content-Type: application/json" \ -H "x-api-key: YOUR_API_KEY" \ -d '{ "merchantId": "merchant_abc123", "wallet": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045", "items": [ { "path": "$.line_items[0]", "amount": 12000 } ] }'
{
"ok": true,
"data": {
"protocol": "acp",
"version": "2026-01-30",
"discounts": {
"codes": ["INSR-A7B3K"],
"applied": [
{
"id": "INSR-A7B3K",
"code": "INSR-A7B3K",
"coupon": {
"id": "insumer-insr-a7b3k",
"name": "Token Holder Discount (15% off)",
"percent_off": 15
},
"amount": 1800,
"automatic": false,
"method": "across",
"priority": 10,
"allocations": [
{ "path": "$.line_items[0]", "amount": 1800 }
],
"start": "2026-02-27T12:00:00Z",
"end": "2026-02-27T12:30:00Z"
}
],
"rejected": []
},
"verification": {
"code": "INSR-A7B3K",
"expiresAt": "2026-02-27T12:30:00Z",
"breakdown": [{ "symbol": "UNI", "tier": "Gold", "discount": 15, "chain": "Ethereum" }],
"sig": "MEUCIQD...",
"kid": "insumer-attest-v1"
}
},
"meta": { "creditsRemaining": 47, "creditsCharged": 1, "version": "1.0", "timestamp": "2026-02-27T12:00:00.000Z" }
}
When the wallet holds none of the merchant's configured tokens, the response still returns 200. The codes array is empty and rejected contains the reason. A verification code is still generated and signed.
{
"ok": true,
"data": {
"protocol": "acp",
"version": "2026-01-30",
"discounts": {
"codes": [],
"applied": [],
"rejected": [
{
"code": "INSUMER_CHECK",
"reason": "user_ineligible"
}
]
},
"verification": {
"code": "INSR-K9F2L",
"expiresAt": "2026-02-28T00:00:00Z",
"breakdown": [],
"sig": "MEUCIQD...",
"kid": "insumer-attest-v1"
}
},
"meta": { "creditsRemaining": 46, "creditsCharged": 1, "version": "1.0", "timestamp": "2026-02-27T12:00:01.000Z" }
}
The response is still ECDSA-signed. Verify signatures the same way regardless of eligibility. The signed payload includes verified: false so the attestation itself is verifiable proof the check was performed.
Same on-chain verification, Google UCP format. Uses a title string instead of Stripe coupon objects and includes a extension field for protocol identification.
| Parameter | Type | Required | Description |
|---|---|---|---|
merchantId |
string | Required | Firestore merchant document ID |
wallet |
string | Required* | EVM wallet address (0x...). Required unless solanaWallet or xrplWallet is provided. |
solanaWallet |
string | Optional | Solana wallet address. Use instead of wallet for Solana-based merchants. |
xrplWallet |
string | Optional | XRPL wallet address (r-address). Use for XRP Ledger-based merchants. |
items |
array | Optional | Cart items with path and amount fields. Used for item-level discount context. |
curl -X POST \ https://api.insumermodel.com/v1/ucp/discount \ -H "Content-Type: application/json" \ -H "x-api-key: YOUR_API_KEY" \ -d '{ "merchantId": "merchant_abc123", "wallet": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045", "items": [ { "path": "$.line_items[0]", "amount": 12000 } ] }'
{
"ok": true,
"data": {
"protocol": "ucp",
"version": "2026-01-11",
"extension": "dev.ucp.shopping.discount",
"discounts": {
"codes": ["INSR-M9X2P"],
"applied": [
{
"code": "INSR-M9X2P",
"title": "Token Holder Discount \u2014 15% Off",
"amount": 1800,
"automatic": false,
"method": "across",
"priority": 10,
"allocations": [
{ "path": "$.line_items[0]", "amount": 1800 }
]
}
]
},
"verification": {
"code": "INSR-M9X2P",
"expiresAt": "2026-02-27T12:30:00Z",
"sig": "MEUCIQD...",
"kid": "insumer-attest-v1"
}
},
"meta": { "creditsRemaining": 47, "creditsCharged": 1, "version": "1.0", "timestamp": "2026-02-27T12:00:00.000Z" }
}
Public endpoint. No API key required. Validate an INSR-XXXXX discount code. Returns valid or invalid status with discount percentage, merchant, and expiration details.
| Parameter | Type | Required | Description |
|---|---|---|---|
code |
string | Required | Discount code in INSR-XXXXX format |
curl https://api.insumermodel.com/v1/codes/INSR-A7B3K
{
"ok": true,
"data": {
"valid": true,
"code": "INSR-A7B3K",
"merchantId": "merchant_abc123",
"discountPercent": 15,
"expiresAt": "2026-02-28T00:00:00Z",
"createdAt": "2026-02-27T12:00:00Z"
},
"meta": { "version": "1.0", "timestamp": "2026-02-27T12:00:05.000Z" }
}
{
"ok": true,
"data": {
"valid": false,
"code": "INSR-A7B3K",
"reason": "expired"
},
"meta": { "version": "1.0", "timestamp": "2026-02-27T12:35:00.000Z" }
}
Possible reason values: not_found, expired, already_used
| Feature | ACP | UCP |
|---|---|---|
| Protocol | OpenAI | |
| Format | Stripe coupon objects | Title + extension |
| Version | 2026-01-30 |
2026-01-11 |
| Discount shape | coupon.percent_off |
title string |
| Start/end times | Yes | No |
| Extension field | No | dev.ucp.shopping.discount |
Both share: same on-chain verification, same ECDSA signature, same INSR-XXXXX discount codes, same 1 credit cost per call.
AsterPay KYA uses POST /v1/attest for ERC-8183 agent trust scoring with 4 conditions in a single call. DJD Agent Score integrates wallet verification into its agent trust scoring architecture in the Coinbase x402 ecosystem. Fork either as a starting point for ACP or UCP commerce integration.
See how this endpoint fits the full API → API Topology