The payment object
POST /v1/payments
Sign and broadcast a USDC transfer.
Request
Response
201 Created:
GET /v1/payments/{id} or subscribe to payment.confirmed webhooks.
Enforcement layers
In order, before the response is built:- Tally pre-check. The agent must exist in this (account, mode); the wallet must belong to the account; an active grant must exist; the policy (per-tx max, daily cap, recipient/contract allowlist, expiry) must permit the payment.
- Privy enclave. Independently re-validates the per-tx max and allowlists when signing. A compromised Tally server can’t sneak a payment past this check.
status: "failed" on the resulting payment.
Errors
See Errors for the response envelope.
Rate limit
POST /v1/payments uses the stricter payments bucket: 30 requests / 60 seconds per API key. See Rate limits.
GET /v1/payments/{id}
Retrieve a single payment by its Tally id. If the payment is still pending on Tally’s side and has a tx_hash, this call lazily refreshes from the chain — so polling GET /v1/payments/{id} is the canonical way to wait for a confirmation.
Request
Response
200 OK. Same shape as the POST /v1/payments response. status reflects the latest known state — if the chain has confirmed since the last call, status will have flipped to confirmed or failed.
Errors
Patterns
Poll until confirmed
Production: subscribe to webhooks instead
For production workloads, replace the polling loop with a webhook subscription topayment.confirmed and payment.failed. The event carries the same payment shape; verification helper lives in the SDK webhooks page.
Not yet exposed
GET /v1/payments— listing with status/agent/direction filters.POST /v1/payments/{id}/refund— first-class refund handling.