---
title: "Submit a transaction for signing"
method: POST
path: "/v1/agents/{agent_id}/transactions"
tags: ["Transactions"]
---

# Submit a transaction for signing

`POST /v1/agents/{agent_id}/transactions`

## Request

- Base URL: `https://api.1claw.co`
- URL: `https://api.1claw.co/v1/agents/{agent_id}/transactions`
- Auth: HTTP bearer

Replay protection: send an optional **Idempotency-Key** header (e.g. UUID or opaque string).
Duplicate requests with the same key within 24 hours return the cached transaction response
(no second sign/broadcast). Omit the header for non-idempotent submissions.

## Path parameters

- `agent_id` string, uuid, required

## Headers

- `Idempotency-Key` string

## Request body

- SubmitTransactionRequest
  - `to` string, required: Destination address (0x-prefixed)
  - `value` string, required: Value in ETH
  - `chain` string, required: Chain name or numeric ID
  - `data` string: Hex-encoded calldata
  - `signing_key_path` string: Vault path to signing key. Auto-resolves per-chain signing key if provisioned, otherwise keys/{chain}-signer.
  - `nonce` integer
  - `gas_price` string
  - `gas_limit` integer
  - `max_fee_per_gas` string
  - `max_priority_fee_per_gas` string
  - `simulate_first` boolean
  - `mode` 'eoa' | 'smart_account': Transaction mode
  - `gasless` boolean: Whether to submit as a gasless (sponsored) transaction
  - `destination_tag` integer: Non-EVM (XRP): destination tag for exchange deposits
  - `memo` string: Non-EVM (XRP, Solana): optional memo
  - `fee_rate_sat_per_vbyte` integer: Non-EVM (Bitcoin): override the fetched fee rate (sat/vByte)
  - `fee_limit_sun` integer: Non-EVM (Tron): TRC-20 energy fee limit in sun
  - `token_mint` string: Non-EVM (Solana SPL / Tron TRC-20): token mint or contract address; omit for native transfer
  - `token_decimals` integer: Non-EVM (Solana, Tron): token decimals (default 6)
  - `ttl` integer: Non-EVM (Cardano): transaction time-to-live (absolute slot)
  - `xrpl_tx_json` object: Raw XRPL transaction JSON for full transaction type coverage. When present (and chain is XRP), the handler uses the xrpl-rust binary codec to encode and sign the transaction as-is. Supports all XRPL transaction types: Payment, TrustSet, OfferCreate, OfferCancel, AccountSet, EscrowCreate, NFTokenMint, AMMCreate, and 20+ more. Account, Sequence, Fee, LastLedgerSequence, and SigningPubKey are auto-filled when absent.
  - `approval_id` string, uuid: Optional pending approval ID. When consensus policies match, clients resubmit with this field set to bypass the 202 gate after the approval has been executed.
  - `raw_transaction` string: Pre-built raw transaction as a base64-encoded byte string. When provided, the handler decodes and deep-inspects the transaction for policy evaluation before signing. Supported for non-EVM chains where the client constructs the transaction payload.
  - `tron_transaction` object: Pre-built Tron transaction JSON object. When provided, the handler signs the transaction as-is using the Tron protobuf format. Enables full Tron transaction type coverage beyond simple TRX/TRC-20 transfers.

## Response `200`

Transaction previously created with same Idempotency-Key (replay-safe response)

- TransactionResponse
  - `id` string, uuid
  - `agent_id` string, uuid
  - `chain` string
  - `chain_id` integer
  - `to` string
  - `value_wei` string
  - `status` 'pending' | 'signed' | 'sign_only' | 'broadcast' | 'confirmed' | 'reverted' | 'dropped' | 'failed' | 'simulation_failed': `broadcast` means the RPC accepted the raw transaction; it does not mean the transaction mined. The receipt reconciler resolves it to `confirmed`, `reverted` or `dropped` once the chain answers. `reverted` mined and failed on-chain (nonce consumed, gas paid); `dropped` never mined and never will (the sender's nonce has moved past it), so no value moved and no gas was paid. Non-EVM chains reach `confirmed`/`reverted` but never `dropped`, because the absence of a transaction there cannot be distinguished from a node having pruned it.
  - `signed_tx` string, nullable: Raw signed transaction hex. On GET list and GET by id, this property is omitted by default (absent from the response). Pass `include_signed_tx=true` on those endpoints to include it. Always present on the initial POST submit response.
  - `tx_hash` string
  - `error_message` string
  - `created_at` string, date-time
  - `signed_at` string, date-time
  - `simulation_id` string
  - `simulation_status` string
  - `tenderly_dashboard_url` string, uri
  - `max_fee_per_gas` string
  - `max_priority_fee_per_gas` string
  - `from_address` string: Sender, learned from the chain by the receipt reconciler.
  - `block_number` integer: Block (EVM), slot (Solana) or ledger index (XRP) the transaction settled in. Absent until it settles.
  - `confirmed_at` string, date-time: When settlement was observed. Absent for a `dropped` transaction, which never settled.
  - `reconciled_at` string, date-time: Last time the reconciler asked the chain about this transaction. Set while `status` is still `broadcast` means we looked and could not tell yet, as distinct from nobody having looked.

## Other responses

- `201`: Transaction signed (and optionally broadcast)
- `202`: Transaction held for human approval (graduated tx_approval_policy). Do not resubmit: when the approval is approved the server signs (and broadcasts) the stored request itself. Poll `GET /v1/approvals/{approval_id}` or the transaction. There is no request field for resuming; a `resume_tx_id` in the body is ignored. (The self-custody `POST /v1/agents/{agent_id}/tss/prepare` is the exception: it does take `resume_tx_id`, because the agent co-signs.)
- `402`: x402 payment required
- `403`: Insufficient permissions
- `409`: Idempotency-Key in use by another in-flight request; retry later.
- `422`: Simulation reverted (when simulate_first is true)

---

[API](https://skmtc.dev/1claw/apis/1claw-api.md) · [All operations](https://skmtc.dev/1claw/apis/1claw-api/llms.txt) · [OpenAPI document](https://skmtc.dev/1claw/apis/1claw-api/revisions/ae109b496830?raw)
