---
title: "Batch wallet trust profiles"
method: POST
path: "/v1/trust/batch"
tags: ["Trust Fact Profiles"]
---

# Batch wallet trust profiles

`POST /v1/trust/batch`

## Request

- Base URL: `https://api.insumermodel.com`
- URL: `https://api.insumermodel.com/v1/trust/batch`
- Auth: one of:
  - API key in header `X-API-Key`
  - API key in header `Authorization`

Batch trust profiles for up to 10 wallets in one request. Each wallet gets an independent ECDSA-signed profile. Partial success supported. 3 credits/wallet standard, 6 with proof="merkle". Authentication: this endpoint accepts EITHER the X-API-Key header OR the Authorization: Wallet header (SIWE envelope from a wallet that holds the Insumer Access pass).

## Request body

- object
  - `wallets` object[], required: 1-10 wallet entries to profile
    - `wallet` string, required: EVM wallet address (required)
    - `solanaWallet` string: Solana wallet address (base58). Adds the 14-check solana dimension for this wallet and evaluates its Solana institutional_stablecoins entries.
    - `xrplWallet` string: XRPL wallet address (classic r-address). Adds the xrpl dimension (RLUSD, USDC, OUSG) for this wallet and evaluates its EURCV on XRPL entry. The base58 checksum is verified; an address that fails it returns 400.
    - `bitcoinWallet` string: Bitcoin address. Adds the bitcoin dimension (native BTC presence check) for this wallet.
    - `tronWallet` string: Tron address (T-prefix, 34 chars). Adds the tron dimension (USDT, USD1, WBTC) for this wallet.
    - `stellarWallet` string: Stellar address (G-prefix, 56 chars). Evaluates the Stellar entries (USDC, BENJI) under institutional_stablecoins for this wallet; the checksum is verified and a malformed address is a 400, never silently skipped.
    - `suiWallet` string: Sui address (0x + 64 hex chars). Evaluates USDC on Sui (institutional_stablecoins) and USDY on Sui (tokenized_treasuries) for this wallet.
  - `proof` 'merkle': Set to 'merkle' for EIP-1186 storage proofs on all wallets. Same coverage as the single endpoint: EVM token rows carry a storage proof when the token's balance slot can be discovered; rows whose balance is computed rather than stored (Aave aTokens, BUIDL) and tokens with non-standard storage layouts are declined with a stated reason; NFT, non-EVM and account rows are declined (account rows with a reason pointing at /v1/attest); a check that was not evaluated carries no proof key at all; the premium is refunded whenever no proof is delivered. 6 credits/wallet.

## Response `200`

Batch trust profiles (may include partial failures)

- object
  - `ok` true
  - `data` object
    - `results` union[]: One entry per wallet — either a trust profile or an error
      - union
        - object
          - `trust` object: Full trust profile (same schema as POST /v1/trust)
            - `id` string
            - `wallet` string
            - `conditionSetVersion` string
            - `dimensions` object
            - `summary` object
            - `profiledAt` string
            - `expiresAt` string
          - `sig` string: ECDSA P-256 signature over this wallet's trust object
          - `kid` string: insumer-trust-v2 (v2 keys) or insumer-attest-v1 (v1 keys); selects the key and the preimage exactly as on POST /v1/trust
          - `pqSig` string: OPTIONAL post-quantum signature over this wallet's trust preimage: base64 ML-DSA-65 (FIPS 204) over the post-quantum domain tag plus the exact classical preimage this entry's kid selects. A kid a verifier does not recognise selects no preimage, so the post-quantum signature is then unverifiable, never refuted, and no other era's preimage may be substituted for it. Additive; sig and kid are unchanged. See the state attestation spec, Section 12 Check 6.
          - `pqKid` string: OPTIONAL post-quantum key identifier (insumer-trust-pq1), resolved in the JWKS as an RFC 9964 AKP / ML-DSA-65 key.
        - object
          - `error` object
            - `wallet` string
            - `message` string
    - `summary` object
      - `requested` integer
      - `succeeded` integer
      - `failed` integer
  - `meta` object
    - `creditsCharged` integer: Total credits charged (successCount × creditsPerWallet). 0 on x402-paid calls.
    - `creditsRemaining` integer, nullable: Credits left on the key after this call. null on x402-paid calls (creditsCharged is 0 there; the call was paid at the transport layer, not from stored credits).
    - `version` string
    - `timestamp` string

## Other responses

- `400`: Bad request (invalid wallets array)
- `401`: Invalid or missing API key
- `402`: Payment required. For API-key callers: insufficient verification credits (standard error envelope). For credential-less callers this is the x402 pay-per-call quote (X402Quote body): the v2 payment payload is in the JSON body and, base64-encoded, in the payment-required response header. Pay the quoted amount in USDC on any listed network (Base, Polygon, Arbitrum, Arc, or Solana) and retry with the PAYMENT-SIGNATURE header (X-PAYMENT is still accepted).
- `413`: Body exceeds the pay-per-call size cap. Returned on x402-paid requests whose JSON body is larger than the cap; API-key and wallet-auth calls are not subject to it.
- `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.
- `503`: Transient service condition on wallet-auth or x402-paid calls (for example the wallet-auth nonce store or payment verification being temporarily unavailable). Retryable after a short delay. Per-wallet data-source failures do not use this status here; they surface as error entries in the partial-success results array. On an Arc (eip155:5042) pay-per-call payment, a 503 can also mean the settlement was submitted but had not confirmed by the server's deadline, or the payment facilitator did not answer. That payment is UNRESOLVED, not refused: the transfer may still land. Retry the exact same request (same body) with the SAME payment header; it resolves to the same payment and cannot charge twice. Do not sign a new authorization. If the payment ultimately failed, the retry returns 402 with a fresh quote and nothing was charged.

---

[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)
