Quickstart¶
Relay your first gas-sponsored transaction in about five minutes. You will submit a 1-wei transfer on Base Sepolia, poll it to completion, and read what it cost you in USD. No testnet ETH required — Photon's relayer pays the gas.
1. Get an API key¶
Every request carries your key in the api-key header. Get API access and fund your prepaid balance, then export the key:
2. Submit the transaction¶
POST /api/submit-tx queues the transaction and returns immediately with a txId — relaying happens in the background.
const res = await fetch("https://photon.example.com/api/submit-tx", {
method: "POST",
headers: {
"api-key": process.env.EDITH_API_KEY!,
"Content-Type": "application/json",
},
body: JSON.stringify({
to: "0x3dbE34f2C21b3B2980d4dc53f3c7E51e39663F49",
callData: "0x",
value: "1",
chainId: 84532,
label: "quickstart-transfer",
}),
});
const { data } = await res.json();
console.log(data.txId);
Expected response — 201 Created:
{
"success": true,
"data": {
"txId": "68fa3450539a3c9d28bbca33",
"estimatedCostUSD": 0.0021
},
"timestamp": "2026-07-29T09:14:03.412Z"
}
Info
A 201 means queued, not mined. estimatedCostUSD is a pre-flight gas estimate reserved against your balance; the final costUSD comes with the result.
3. Poll until it executes¶
GET /api/tx?id=<txId> returns the transaction record. Poll every second or so until status is EXECUTED (or FAILED).
let tx;
do {
await new Promise((r) => setTimeout(r, 1000));
const res = await fetch(
"https://photon.example.com/api/tx?id=68fa3450539a3c9d28bbca33",
{ headers: { "api-key": process.env.EDITH_API_KEY! } }
);
({ data: tx } = await res.json());
} while (tx.status !== "EXECUTED" && tx.status !== "FAILED");
console.log(tx.status, tx.executionTxHash);
Expected response once mined — 200 OK:
{
"success": true,
"data": {
"id": "68fa3450539a3c9d28bbca33",
"userId": "68c275846a6ba1c9a2198a8c",
"to": "0x3dbE34f2C21b3B2980d4dc53f3c7E51e39663F49",
"callData": "0x",
"value": "1",
"chainId": 84532,
"gasPrice": "1000000000",
"maxFeePerGas": null,
"maxPriorityFeePerGas": null,
"gasLimit": null,
"label": "quickstart-transfer",
"status": "EXECUTED",
"executionTxHash": "0x7d1a8f0f7c2f4b7e9a3d5c1e8b6a4f2d0c9e7b5a3f1d8c6e4b2a0f9d7c5e3b1a",
"timestamp": "2026-07-29T09:14:08.921Z",
"latency": 2500,
"costUSD": 0.0019,
"retries": 0,
"isAccountCharged": true,
"transactionType": "flash",
"submitRegion": "default"
},
"timestamp": "2026-07-29T09:14:09.523Z"
}
4. Read the cost¶
costUSD is the actual amount debited from your prepaid balance for this transaction — here about a fifth of a cent. executionTxHash is the on-chain hash; look it up on Basescan to see the relayer paid the gas, not you.
That's the whole loop: submit intent, Photon signs and pays, you read the result.
Next steps¶
- Core concepts — the transaction lifecycle, balances, and limits behind what you just did.
- Register a webhook — get pushed status updates instead of polling.
- API reference — every endpoint, field by field.