Sign & Submit API
Synchronous endpoints for signing and submitting transactions directly — no job polling required.
Endpoints
| Endpoint |
Purpose |
Returns |
POST /agent/sign |
Sign messages, typed data, or transactions |
Signature |
POST /agent/submit |
Submit raw transactions to chain |
Transaction hash |
POST /agent/sign
Signature Types
| Type |
Use Case |
personal_sign |
Plain text messages (auth, verification) |
eth_signTypedData_v4 |
EIP-712 typed data (permits, orders) |
eth_signTransaction |
Sign transactions for later broadcast |
Usage
// personal_sign
const signMessage = await fetch(`${API_URL}/agent/sign`, {
method: "POST",
headers: { "x-api-key": API_KEY, "Content-Type": "application/json" },
body: JSON.stringify({
signatureType: "personal_sign",
message: "Sign in to MyApp\nNonce: abc123",
}),
});
// → { success: true, signature: "0x...", signer: "0x...", signatureType: "personal_sign" }
// eth_signTypedData_v4 (EIP-2612 permit)
const signPermit = await fetch(`${API_URL}/agent/sign`, {
method: "POST",
headers: { "x-api-key": API_KEY, "Content-Type": "application/json" },
body: JSON.stringify({
signatureType: "eth_signTypedData_v4",
typedData: {
domain: { name: "USD Coin", version: "2", chainId: 8453, verifyingContract: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913" },
types: {
Permit: [
{ name: "owner", type: "address" },
{ name: "spender", type: "address" },
{ name: "value", type: "uint256" },
{ name: "nonce", type: "uint256" },
{ name: "deadline", type: "uint256" },
],
},
primaryType: "Permit",
message: { owner: "0x...", spender: "0x...", value: "1000000", nonce: "0", deadline: "1735689600" },
},
}),
});
// eth_signTransaction
const signTx = await fetch(`${API_URL}/agent/sign`, {
method: "POST",
headers: { "x-api-key": API_KEY, "Content-Type": "application/json" },
body: JSON.stringify({
signatureType: "eth_signTransaction",
transaction: { to: "0x...", chainId: 8453, value: "0", data: "0xa9059cbb..." },
}),
});
Error Responses
| Status |
Error |
Cause |
| 400 |
Missing required field |
Missing message, typedData, or transaction |
| 401 |
Authentication required |
Missing or invalid API key |
| 403 |
Read-only API key |
Key lacks write permissions |
POST /agent/submit
Transaction Fields
| Field |
Type |
Required |
Description |
to |
string |
Yes |
Destination address |
chainId |
number |
Yes |
Chain ID (8453=Base, 1=Ethereum, 137=Polygon) |
value |
string |
No |
Value in wei |
data |
string |
No |
Calldata (hex) |
gas |
string |
No |
Gas limit |
maxFeePerGas |
string |
No |
EIP-1559 max fee |
maxPriorityFeePerGas |
string |
No |
EIP-1559 priority fee |
Options
| Field |
Type |
Default |
Description |
description |
string |
— |
Human-readable description for logging |
waitForConfirmation |
boolean |
true |
Wait for on-chain confirmation |
Usage
// Submit a transaction and wait for confirmation
const result = await fetch(`${API_URL}/agent/submit`, {
method: "POST",
headers: { "x-api-key": API_KEY, "Content-Type": "application/json" },
body: JSON.stringify({
transaction: { to: "0x...", chainId: 8453, value: "1000000000000000000" },
description: "Send 1 ETH",
waitForConfirmation: true,
}),
});
// → { success: true, transactionHash: "0x...", status: "success", blockNumber: "123", gasUsed: "21000" }
// Fire-and-forget (don't wait for confirmation)
const pending = await fetch(`${API_URL}/agent/submit`, {
method: "POST",
headers: { "x-api-key": API_KEY, "Content-Type": "application/json" },
body: JSON.stringify({
transaction: { to: "0x...", chainId: 8453, value: "100000000000000000" },
waitForConfirmation: false,
}),
});
// → { success: true, transactionHash: "0x...", status: "pending" }
Multi-Step Workflow
// Approve + Swap sequence
async function approveAndSwap(approveTx: object, swapTx: object) {
// 1. Approve token spending
const approval = await submitTransaction(approveTx);
if (approval.status !== "success") throw new Error("Approval failed");
// 2. Execute swap
const swap = await submitTransaction(swapTx);
if (swap.status !== "success") throw new Error("Swap failed");
return swap;
}
Transaction Status Values
| Status |
Description |
success |
Confirmed and succeeded |
reverted |
Confirmed but reverted |
pending |
Submitted, not yet confirmed |
Comparison with /agent/prompt
| Feature |
/agent/prompt |
/agent/sign |
/agent/submit |
| Input |
Natural language |
Structured data |
Transaction object |
| Response |
Async (job ID) |
Sync (signature) |
Sync (tx hash) |
| Executes on-chain |
Via AI agent |
No |
Yes |
| Best for |
General queries |
Auth, permits |
Raw transactions |
Security Notes
/agent/submit executes immediately — no confirmation prompt
- Read-only API keys get 403 on both endpoints
- Always validate transaction parameters before submission
- Use
waitForConfirmation: true for critical transactions
Related Skills
bankr-api-basics - API fundamentals
bankr-client-patterns - Client setup
bankr-safety - Security best practices
bankr-arbitrary-transaction - Constructing raw transaction JSON
1---2name: bankr-dev-sign-submit-api3description: This skill should be used when building apps that need to sign messages, sign typed data (EIP-712), sign transactions, or submit raw transactions via the Bankr API. Covers the synchronous /agent/sign and /agent/submit endpoints with TypeScript patterns.4---56# Sign & Submit API78Synchronous endpoints for signing and submitting transactions directly — no job polling required.910## Endpoints1112| Endpoint | Purpose | Returns |13|----------|---------|---------|14| `POST /agent/sign` | Sign messages, typed data, or transactions | Signature |15| `POST /agent/submit` | Submit raw transactions to chain | Transaction hash |1617## POST /agent/sign1819### Signature Types2021| Type | Use Case |22|------|----------|23| `personal_sign` | Plain text messages (auth, verification) |24| `eth_signTypedData_v4` | EIP-712 typed data (permits, orders) |25| `eth_signTransaction` | Sign transactions for later broadcast |2627### Usage2829```typescript30// personal_sign31const signMessage = await fetch(`${API_URL}/agent/sign`, {32 method: "POST",33 headers: { "x-api-key": API_KEY, "Content-Type": "application/json" },34 body: JSON.stringify({35 signatureType: "personal_sign",36 message: "Sign in to MyApp\nNonce: abc123",37 }),38});39// → { success: true, signature: "0x...", signer: "0x...", signatureType: "personal_sign" }4041// eth_signTypedData_v4 (EIP-2612 permit)42const signPermit = await fetch(`${API_URL}/agent/sign`, {43 method: "POST",44 headers: { "x-api-key": API_KEY, "Content-Type": "application/json" },45 body: JSON.stringify({46 signatureType: "eth_signTypedData_v4",47 typedData: {48 domain: { name: "USD Coin", version: "2", chainId: 8453, verifyingContract: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913" },49 types: {50 Permit: [51 { name: "owner", type: "address" },52 { name: "spender", type: "address" },53 { name: "value", type: "uint256" },54 { name: "nonce", type: "uint256" },55 { name: "deadline", type: "uint256" },56 ],57 },58 primaryType: "Permit",59 message: { owner: "0x...", spender: "0x...", value: "1000000", nonce: "0", deadline: "1735689600" },60 },61 }),62});6364// eth_signTransaction65const signTx = await fetch(`${API_URL}/agent/sign`, {66 method: "POST",67 headers: { "x-api-key": API_KEY, "Content-Type": "application/json" },68 body: JSON.stringify({69 signatureType: "eth_signTransaction",70 transaction: { to: "0x...", chainId: 8453, value: "0", data: "0xa9059cbb..." },71 }),72});73```7475### Error Responses7677| Status | Error | Cause |78|--------|-------|-------|79| 400 | Missing required field | Missing message, typedData, or transaction |80| 401 | Authentication required | Missing or invalid API key |81| 403 | Read-only API key | Key lacks write permissions |8283## POST /agent/submit8485### Transaction Fields8687| Field | Type | Required | Description |88|-------|------|----------|-------------|89| `to` | string | Yes | Destination address |90| `chainId` | number | Yes | Chain ID (8453=Base, 1=Ethereum, 137=Polygon) |91| `value` | string | No | Value in wei |92| `data` | string | No | Calldata (hex) |93| `gas` | string | No | Gas limit |94| `maxFeePerGas` | string | No | EIP-1559 max fee |95| `maxPriorityFeePerGas` | string | No | EIP-1559 priority fee |9697### Options9899| Field | Type | Default | Description |100|-------|------|---------|-------------|101| `description` | string | — | Human-readable description for logging |102| `waitForConfirmation` | boolean | true | Wait for on-chain confirmation |103104### Usage105106```typescript107// Submit a transaction and wait for confirmation108const result = await fetch(`${API_URL}/agent/submit`, {109 method: "POST",110 headers: { "x-api-key": API_KEY, "Content-Type": "application/json" },111 body: JSON.stringify({112 transaction: { to: "0x...", chainId: 8453, value: "1000000000000000000" },113 description: "Send 1 ETH",114 waitForConfirmation: true,115 }),116});117// → { success: true, transactionHash: "0x...", status: "success", blockNumber: "123", gasUsed: "21000" }118119// Fire-and-forget (don't wait for confirmation)120const pending = await fetch(`${API_URL}/agent/submit`, {121 method: "POST",122 headers: { "x-api-key": API_KEY, "Content-Type": "application/json" },123 body: JSON.stringify({124 transaction: { to: "0x...", chainId: 8453, value: "100000000000000000" },125 waitForConfirmation: false,126 }),127});128// → { success: true, transactionHash: "0x...", status: "pending" }129```130131### Multi-Step Workflow132133```typescript134// Approve + Swap sequence135async function approveAndSwap(approveTx: object, swapTx: object) {136 // 1. Approve token spending137 const approval = await submitTransaction(approveTx);138 if (approval.status !== "success") throw new Error("Approval failed");139140 // 2. Execute swap141 const swap = await submitTransaction(swapTx);142 if (swap.status !== "success") throw new Error("Swap failed");143144 return swap;145}146```147148### Transaction Status Values149150| Status | Description |151|--------|-------------|152| `success` | Confirmed and succeeded |153| `reverted` | Confirmed but reverted |154| `pending` | Submitted, not yet confirmed |155156## Comparison with /agent/prompt157158| Feature | /agent/prompt | /agent/sign | /agent/submit |159|---------|---------------|-------------|---------------|160| Input | Natural language | Structured data | Transaction object |161| Response | Async (job ID) | Sync (signature) | Sync (tx hash) |162| Executes on-chain | Via AI agent | No | Yes |163| Best for | General queries | Auth, permits | Raw transactions |164165## Security Notes166167- `/agent/submit` executes immediately — **no confirmation prompt**168- Read-only API keys get 403 on both endpoints169- Always validate transaction parameters before submission170- Use `waitForConfirmation: true` for critical transactions171172## Related Skills173174- `bankr-api-basics` - API fundamentals175- `bankr-client-patterns` - Client setup176- `bankr-safety` - Security best practices177- `bankr-arbitrary-transaction` - Constructing raw transaction JSON