Agent payments quickstart
Pay for one Tomba request with the InFlow CLI, then see what the payment exchange looks like on the wire. Prices and billing rules are on Tomba for AI agents.
Before you begin
You need an InFlow account in the production environment with a USDC or USDT balance. You don't need a Tomba account or API key.
Pay for a request with the InFlow CLI
-
Install the InFlow CLI. On macOS and Linux:
CodeOn Windows, in PowerShell:
CodeBoth commands download and run an installer script. To read the script before you run it, open the URL in a browser.
-
Sign in to InFlow. The client name appears on the approval page that opens in your browser.
Code -
Pay for a request:
CodeThe CLI reads the
402challenge, creates the payment, waits until InFlow reports it ready, sends the request again with the credential, and prints the result. Tomba's response is inbody, andoutcomeispaidwhen the payment settled. If InFlow asks you to approve the payment, approve it while the command waits.Without
--interval, the command returns after creating the payment, with atransaction_idand theinflow mpp fetchcommand that completes the request.
Other endpoints work the same way. Use the query parameters of the matching Tomba API endpoint:
Code
Approve payments automatically
By default InFlow holds every MPP charge for manual approval. The payment sits in
Approvals as Pending approval until you click
the green tick, which is why the commands above pass --interval 5 --max-attempts 180 —
the CLI is polling for up to fifteen minutes while it waits for you. An unattended agent
just stalls.
A policy removes the wait. Create one at app.inflowpay.ai/policies/add:
| Field | Value |
|---|---|
| Policy Type | MPP |
| Policy Action | Approve Requests |
| Currency | The currency you pay in — USDC or USDT |
| Budget | Total the policy may approve in one period, for example 10 |
| Threshold | Optional cap on a single payment. Must not exceed the budget |
| Period | Once, Daily, Monthly or Yearly |
| Reserved | Sets the budget aside from your available balance. Once periods only |
| Seller | All Sellers, or A Specific Seller to limit the policy to Tomba |
| Expires | Optional. The policy stops matching new requests after this time |
Tomba's seller id, if you scope the policy to this service alone:
Code
Once it is active, charges are approved as they arrive and inflow mpp pay returns
without polling.
A policy matches on currency. One written for USDT does not approve a USDC
challenge, and the payment waits for manual approval again — see
Choose a currency.
A Once period never resets, so the policy stops approving when its budget is spent
and payments silently queue again. Check Spent against Budget on the policy if
an agent starts waiting. Use Daily or Monthly for a standing allowance.
Create the policy from the API
The dashboard form maps onto POST /v1/policies. Only type and action are required:
Code
It answers 200 with the created policy:
Code
action is one of APPROVE, DECLINE or REVIEW; period one of ONCE, DAILY,
MONTHLY or YEARLY; currency one of USDC, USDT or PYUSD. Omit sellerId to
apply the policy to every seller.
budget, threshold, currency and period only take effect when action is
APPROVE. Send them with REVIEW or DECLINE and they are dropped without an
error — the request still returns 200, and the policy it creates has no spending
limit at all. Read the policy back after creating it and check the fields you sent
are present.
The seller you send as sellerId is returned as requesterId. A policy with no
requesterId applies to every seller.
List what you have with GET /v1/policies, read one with GET /v1/policies/{policyId},
and remove one with DELETE /v1/policies/{policyId}/delete.
Choose a currency
Every endpoint offers one challenge in USDC and one in USDT. Check what the endpoint offers and what your account can pay with:
Code
Then pay in the currency you hold:
Code
Without --currency, the CLI doesn't check which currency your balance
holds. If it takes the challenge in the other currency, the payment fails
for lack of funds.
What the exchange looks like
Call an endpoint without a credential to see the challenges:
Code
The response has status 402 and one WWW-Authenticate header that lists a Payment challenge per currency, separated by commas (values shortened here):
Code
requestis base64url-encoded JSON with the terms, for example{"amount":"0.00312","currency":"USDC","methodDetails":{"rail":"balance"},"recipient":"…"}.opaquebinds the challenge to the endpoint you called.expiresis the time after which the challenge, and any credential issued for it, is no longer accepted.
The body repeats the price and the CLI commands, and adds agent_instructions and agent_memory fields written for LLM agents:
Code
A paid response has Tomba's status and body, plus these headers:
| Header | Value |
|---|---|
Payment-Receipt | Proof of payment, as base64url-encoded JSON. Only on charged responses. |
X-Payment-Charged | true if the request was charged, false if it wasn't. See Billing. |
| Rate limit headers | Forwarded from the Tomba API; see Rate limits. |
X-Request-ID | Correlation id for this response. Quote it in a support request. Echoes an inbound one. |
Pay without the CLI
To pay from your own code, make the same calls the CLI makes. Authenticate to InFlow with your account's API key in the X-API-KEY header.
-
Send the request and read the
WWW-Authenticateheader of the402response. Split it into itsPaymentchallenges, and choose the one whose decodedrequesthas the currency you hold. -
Create a transaction for that challenge. Send the challenge's parameters as a JSON object, with every value unchanged:
Code -
The response has a
state. While it'spending, waitretryAfterSecondsseconds and poll the transaction until the state isready. Afailedorexpiredstate ends the attempt.Code -
Send the original request again with the
credentialfrom the ready transaction:Code
Use with AI agents has this flow as a Python helper, and a JavaScript version built on InFlow's buyer SDK.