REST API
Register TempoKey agents, authenticate API calls, send payments and batches, and handle retries with idempotency keys.
Registration and authentication
Base URL: https://api.tempokey.xyz. The hosted payment API serves Tempo Mainnet. Requests and responses use JSON. Register a P256 key already authorized by the owner on that network.
const response = await fetch("https://api.tempokey.xyz/api/agent/register", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
ownerAddress: process.env.OWNER_ADDRESS,
name: "research-agent",
privateKeyHex: process.env.AGENT_PRIVATE_KEY,
accessKeyAddress: process.env.AGENT_ADDRESS,
spendingLimit: process.env.AGENT_SPENDING_LIMIT,
expiry: Number(process.env.AGENT_EXPIRY),
}),
});
const result = await response.json();
if (!response.ok) throw new Error(result.error);
const { agentId, bearerToken } = result;
// Save bearerToken in your secret store. Never print it.
console.log("Registered:", agentId);Set the environment variables to your exported agent configuration; AGENT_EXPIRY is its actual future expiry in Unix seconds. The service verifies key possession and on-chain authorization. A successful response contains agentId and bearerToken. Save the Bearer token securely; it is not retrievable later. Re-registering the same authorized key replaces its previous Bearer token.
Endpoint reference
| Method and path | Authentication | Purpose |
|---|---|---|
| GET /api/health | Public | Service configuration and chain ID; not a continuous RPC health check. |
| POST /api/agent/register | Key proof | Register an authorized P256 key; returns a Bearer token. |
| GET /api/agent/list/{ownerAddress} | Public | List public registration metadata for an owner. |
| POST /api/agent/{agentId}/pay | Bearer | Send a single payment in a supported token. |
| POST /api/agent/{agentId}/batch | Bearer | Send 1-50 pathUSD payments, with per-entry results. |
| GET /api/agent/{agentId}/balance | Bearer | Owner balance; optional token query parameter. |
| GET /api/agent/{agentId}/status | Bearer | Key status, pathUSD limit, reset time and call permissions. |
| GET /api/agent/{agentId}/usage | Bearer | Owner's hosted API usage counters. |
| GET /api/membership/config | Public | Pilot network, contracts, tiers and base limits. |
| GET /api/membership/position/{owner} | Public | Verified token position and membership tier. |
Send a payment
const response = await fetch(
"https://api.tempokey.xyz/api/agent/" + process.env.AGENT_ID + "/pay",
{
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: "Bearer " + process.env.AGENT_TOKEN,
"Idempotency-Key": "invoice-1042",
},
body: JSON.stringify({
to: process.env.RECIPIENT_ADDRESS,
amount: 0.01,
token: "PathUSD",
}),
},
);
const result = await response.json();
if (!response.ok) throw new Error(result.error);
console.log(result.hash);token is optional and defaults to PathUSD; mainnet also supports USDC.e and their registered addresses. Amounts must be positive numbers of at least 0.000001. Use at most six decimal places. Authenticated agent routes accept bodies up to 16 KiB.
{
"entries": [
{ "to": "0xFIRST_RECIPIENT", "amount": 0.01 },
{ "to": "0xSECOND_RECIPIENT", "amount": 0.02 }
]
}The HTTP batch endpoint uses pathUSD. It returns results and summary, and can return HTTP 200 with failed entries. Check summary.failed and every entry before deciding which payments still need attention. Token swaps are available through the SDK and dashboard, not through a REST swap endpoint.
Retries and idempotency
- Send a unique Idempotency-Key for each logical POST payment or batch.
- For a retry, keep the same key, route and identical JSON body. The fingerprint includes the raw request body.
- A completed replay returns the stored response without another payment or owner quota charge.
- Changed requests with the same key return 409 IDEMPOTENCY_CONFLICT.
- Unfinished requests return 409 REQUEST_IN_PROGRESS; reconcile the original transaction before proceeding.
The store is scoped to the owner and registered agent. Completed records expire after a 24-hour window measured from the first request. Unfinished reservations are retained for reconciliation. This is bounded retry protection, not an unlimited exactly-once guarantee. Direct SDK calls do not use this store.
Limits and response headers
| Limit | Current behavior |
|---|---|
| Authenticated calls | 10 requests per minute per agent. |
| Registration | 5 attempts per minute per IP. |
| Public membership position | 30 reads per minute per IP. |
| Owner quota | Base 300 units/minute and 10,000 units/day; eligible membership adds capacity. |
| Quota cost | Reads: 1 unit. Payments: 5 per recipient. The usage endpoint is not charged. |
Validated execution attempts can consume quota even if Tempo rejects the payment. Per-agent rate limits also apply to cached replays. Daily owner quota windows use UTC.
X-Membership-Tier: member
X-Membership-Status: verified
X-Usage-Limit-Daily: 11000
X-Usage-Remaining-Daily: 10995
Retry-After: 12Retry-After is returned when relevant, such as a rate limit or pending request. Quota headers apply to charged routes; cached responses and /usage do not necessarily include them.