Transaction Relay API
POST
/relay/prepare
Prepare an unsigned transaction. Returns a serialized transaction for client-side signing.
Body:
instructions, signerPubkeys, priorityLevel, sponsored
POST
/relay/prepare/sponsored
Prepare a fee-sponsored transaction. Works like /relay/prepare but with stricter rate limits for fee-sponsored transactions. Returns an additional sponsored: true field in the response.
Body:
instructions, signerPubkeys, priorityLevel
POST
/relay/submit
Submit a signed transaction for on-chain execution.
Body:
id, signedTx
GET
/relay/status/:id
Check the status of a submitted transaction.
POST
/relay/estimate-fees
Estimate priority fees for a set of accounts.
Body:
accountKeys
Request Body Schema
POST /relay/prepare — instructions body
Body
{
"instructions": [
{
"programId": "5i73FN7Ycgnh9dr2Yzf3oFiTCKhu85JPpTUbZ84VPtu4",
"keys": [
{ "pubkey": "AbC...xYz", "isSigner": true, "isWritable": true },
{ "pubkey": "DeF...uVw", "isSigner": false, "isWritable": true }
],
"data": "AQIDBA==..."
}
],
"signerPubkeys": ["AbC...xYz"],
"priorityLevel": "medium"
}
| Field | Type | Description |
|---|---|---|
instructions | array | Array of instruction objects (required). |
instructions[].programId | string | Program public key (base-58). |
instructions[].keys | array | Array of account key objects with pubkey (string), isSigner (boolean), and isWritable (boolean). |
instructions[].data | string | Instruction data encoded as a base64 string. |
signerPubkeys | string[] | Public keys of all signers (required). |
priorityLevel | string | Priority fee level: "low" | "medium" | "high" (default "medium"). |
Example Responses
POST /relay/prepare
Response
{
"id": "tx_a1b2c3d4",
"serializedTx": "AQAAAA...base64...",
"blockhash": "GHtXQBtXMQ2...",
"lastValidBlockHeight": 287654500,
"estimatedComputeUnits": 85000,
"priorityFee": 5000,
"feePayer": "FeePayerPubkey..."
}
POST /relay/submit
Response
{
"id": "tx_a1b2c3d4",
"status": "confirmed",
"signature": "5UfDuX...abc123",
"error": null,
"slot": 287654321
}
Status values: status can be one of: "pending", "simulated", "submitted", "confirmed", or "failed". The error field will be non-null when status is "failed".
GET /relay/status/:id
Response
{
"id": "tx_a1b2c3d4",
"status": "confirmed",
"signature": "5UfDuX...abc123",
"error": null,
"slot": 287654321
}
POST /relay/estimate-fees
Response
{
"low": 1000,
"medium": 5000,
"high": 25000
}
Error Responses
| Status | Error | Description |
|---|---|---|
400 | "instructions array is required" | Missing instructions in request body. |
400 | "signerPubkeys array is required" | Missing signerPubkeys in request body. |
400 | "Too many instructions..." | The instruction count exceeds the allowed maximum. |
400 | "Transaction too large..." | The serialized transaction exceeds the size limit. |
403 | "Program <id> is not allowed..." | The target program is not on the relay allowlist. |
404 | "Transaction not found" | No transaction with the given ID exists (on /relay/status/:id). |
422 |
{
"error": "Transaction simulation failed",
"message": "...",
"logs": ["..."]
}
| |
500 | "Failed to prepare transaction" | Internal error during transaction preparation. |
Transaction Flow Notes
- Message hash verification on submit: When a signed transaction is submitted via
/relay/submit, the relay verifies that the submitted transaction message matches the one that was originally prepared. If the message has been tampered with, the submission is rejected. - Automatic retry on transient failures: The relay will automatically retry submission on transient network errors. Callers do not need to implement their own retry logic for intermittent RPC failures.
- Blockhash expiration: Prepared transactions include a
lastValidBlockHeight. If the blockhash expires before the transaction is submitted and confirmed, the transaction cannot be landed on-chain and must be re-prepared via/relay/prepare.