API Reference
AgentPay is a payment infrastructure API for AI agents. Your agent authenticates with a Bearer token and makes JSON POST requests. No SDK required โ any HTTP client works.
Base URL: https://agent-pay.pro
ยท
Get your API key โ
Authentication
All protected endpoints require a Bearer token in the Authorization header.
Authorization: Bearer apik_your_api_key_here
Create a new agent account. Returns an API key and a Stripe checkout URL. Complete payment to activate the account.
Request body
| Field | Type | Description |
| name required | string | Display name for the account |
| email required | string | Email address (used for login) |
| plan required | string | starter | growth | scale |
Example request
curl -X POST https://agent-pay.pro/api/agents/register \
-H "Content-Type: application/json" \
-d '{"name":"My Agent","email":"dev@myco.com","plan":"starter"}'
Response
{
"agent_id": "550e8400-e29b-41d4-a716-...",
"api_key": "apik_a1b2c3d4...",
"stripe_checkout_url": "https://checkout.stripe.com/..."
}
Retrieve account details and reissue a fresh API key by email. Use this if you've lost your API key.
Request body
| Field | Type | Description |
| email required | string | Email address used at registration |
Response
{
"agent_id": "550e8400-...",
"api_key": "apik_new_key_...",
"name": "My Agent",
"plan": "starter",
"active": true
}
Get details for an agent account. You can only fetch your own account.
Response
{
"agent_id": "550e8400-...",
"name": "My Agent",
"email": "dev@myco.com",
"plan": "starter",
"active": true,
"transaction_count": 42,
"plan_limit": 1000,
"overage_rate": 0.03
}
Find another registered agent by email or name so you can pay them without exchanging UUIDs out-of-band. Returns only public information (agent ID, display name, active status).
Query params
| Param | Type | Description |
| email | string | Exact email match โ returns a single agent |
| name | string | Partial name match (case-insensitive) โ returns up to 10 results |
Example โ lookup by email
curl https://agent-pay.pro/api/agents/lookup?email=bob@example.com \
-H "Authorization: Bearer apik_..."
Response (email lookup)
{
"agent_id": "a474c284-...",
"name": "Bob Agent",
"active": true
}
Response (name lookup)
{
"results": [
{ "agent_id": "...", "name": "Bob Agent", "active": true }
]
}
Send a payment to another registered agent. Account must be active (payment completed). Overage is billed automatically when you exceed your plan limit. Every payment automatically runs through AgentPay Accept โ the response includes a signed accept_id and merchant_receipt.
Request body
| Field | Type | Description |
| to_agent_id required | string (UUID) | Recipient agent ID |
| amount required | number | Payment amount (positive) |
| purpose | string | Description for the transaction log (max 500 chars) |
Optional headers
Example request
curl -X POST https://agent-pay.pro/api/payments \
-H "Authorization: Bearer apik_..." \
-H "Content-Type: application/json" \
-d '{"to_agent_id":"uuid-of-receiver","amount":0.50,"purpose":"tool usage"}'
Response
{
"transaction_id": "7c9e6679-...",
"status": "completed",
"amount": 0.5,
"timestamp": "2025-01-15T12:34:56Z",
"accept_id": "acc_f0939d9dc4814e...",
"merchant_receipt": {
"receipt_id": "rcpt_b3b6d502f578...",
"merchant_name": "Receiving Agent Name",
"agent_id": "uuid-of-payer",
"purpose": "tool usage",
"amount": 0.5,
"currency": "USD",
"approval_status": "APPROVED",
"timestamp": "2025-01-15T12:34:56Z",
"note": "This payment was initiated by an AI agent via AgentPay Accept."
}
}
AgentPay is its own first customer. Every payment processed by AgentPay is automatically verified through AgentPay Accept. The accept_id links to a retrievable acceptance record โ fetch it any time via GET /api/accept/:accept_id.
Pass an Idempotency-Key header on any POST /api/payments request. If AgentPay has already seen that key for your agent in the last 24 hours, it returns the original response immediately โ no second charge. Safe to retry on network failures.
How it works
| First request | Payment is processed and the response is stored against the key |
| Repeated request (same key) | Stored response returned with X-Idempotency-Replayed: true header โ no charge |
| Expiry | Keys expire after 24 hours; a new request with the same key creates a fresh charge |
| Scope | Keys are scoped per agent โ different agents can reuse the same key string safely |
Example
curl -X POST https://agent-pay.pro/api/payments \
-H "Authorization: Bearer apik_..." \
-H "Content-Type: application/json" \
-H "Idempotency-Key: invoice-2024-001" \
-d '{"to_agent_id":"...", "amount":9.99}'
# Retry safely โ same response, no double charge:
curl -X POST https://agent-pay.pro/api/payments \
-H "Authorization: Bearer apik_..." \
-H "Content-Type: application/json" \
-H "Idempotency-Key: invoice-2024-001" \
-d '{"to_agent_id":"...", "amount":9.99}'
List all transactions for the authenticated agent (both sent and received). Supports pagination.
Query params
| Param | Type | Description |
| limit | number | Results per page (default 50, max 100) |
| offset | number | Pagination offset (default 0) |
Response
{
"data": [
{
"id": "7c9e6679-...",
"from_agent_id": "550e8400-...",
"to_agent_id": "abc12345-...",
"amount": "0.50",
"purpose": "tool usage",
"status": "completed",
"created_at": "2025-01-15T12:34:56Z"
}
],
"total": 42
}
Check your plan usage, remaining transaction quota, and overage rate.
Response
{
"balance": 0,
"currency": "usd",
"transaction_count": 42,
"plan_limit": 1000,
"overage_rate": 0.03,
"transactions_remaining": 958
}
Verify an agent-initiated payment and generate a signed acceptance record. Use this as a merchant to confirm the paying agent is real, capture intent, and produce an auditable receipt before fulfilling a request.
Request body
| Field | Type | Description |
| agent_id required | string | UUID of the paying agent (or demo agent ID) |
| amount required | number | Payment amount |
| purpose required | string | What the agent is paying for (max 500 chars) |
| merchant_name required | string | Your business name shown on the receipt |
| currency | string | Currency code (default: USD) |
| approved_by_human | boolean | Whether a human explicitly approved (default: false) |
| approval_reference | string | Ticket ID, order ID, or other reference for your records |
Example request
curl -X POST https://agent-pay.pro/api/accept \
-H "Authorization: Bearer apik_..." \
-H "Content-Type: application/json" \
-d '{
"agent_id": "uuid-of-paying-agent",
"amount": 49.99,
"purpose": "SaaS subscription renewal",
"merchant_name": "Acme Corp",
"approved_by_human": false,
"approval_reference": "order_001"
}'
Response
{
"ok": true,
"accept_id": "acc_f0939d9dc4814e...",
"status": "accepted",
"verified_agent": {
"agent_id": "uuid-of-paying-agent",
"name": "Paying Agent Name",
"verified": true,
"active": true
},
"amount": 49.99,
"currency": "USD",
"purpose": "SaaS subscription renewal",
"approved_by_human": false,
"approval_reference": "order_001",
"timestamp": "2026-01-15T12:34:56Z",
"merchant_receipt": {
"receipt_id": "rcpt_b3b6d502...",
"merchant_name": "Acme Corp",
"amount": 49.99,
"currency": "USD",
"approval_status": "APPROVED",
"timestamp": "2026-01-15T12:34:56Z"
}
}
Built in to every payment. When agents pay each other via POST /api/payments, AgentPay Accept runs automatically โ the payment response already includes an accept_id and merchant_receipt. Use this endpoint when you need to run Accept independently as a merchant.
Retrieve a previously created acceptance record by its accept_id. Requires a valid agent API key.
Response
{
"ok": true,
"accept_id": "acc_f0939d9dc4814e...",
"status": "accepted",
"verified_agent": { },
"merchant_receipt": { },
"approval_reference": "order_001",
"timestamp": "2026-01-15T12:34:56Z"
}
Register a URL to receive real-time notifications when your agent sends or receives a payment. AgentPay signs every request with HMAC-SHA256 so you can verify authenticity.
Request body
| Field | Type | Required | Description |
| url | string | Yes | HTTPS URL AgentPay will POST events to |
| events | string[] | No | payment.received, payment.sent (default: ["payment.received"]) |
Example
curl -X POST https://agent-pay.pro/api/webhooks \
-H "Authorization: Bearer apik_..." \
-H "Content-Type: application/json" \
-d '{"url":"https://myagent.example.com/hooks","events":["payment.received","payment.sent"]}'
Response
{
"ok": true,
"webhook_id": "071b6756-...",
"url": "https://myagent.example.com/hooks",
"events": ["payment.received", "payment.sent"],
"secret": "a8f3c...",
"note": "Save this secret โ it will not be shown again."
}
List all webhooks registered for your agent.
Response
{
"data": [
{
"id": "071b6756-...",
"url": "https://myagent.example.com/hooks",
"events": ["payment.received"],
"active": true,
"created_at": "2025-01-15T12:00:00Z"
}
]
}
Permanently remove a webhook registration.
Response
{ "ok": true }
Every webhook delivery includes an X-AgentPay-Signature header. Verify it to confirm the request came from AgentPay and wasn't tampered with.
Payload shape
{
"event": "payment.received",
"transaction_id": "7c9e6679-...",
"from_agent_id": "alice-uuid",
"from_agent_name": "Alice Agent",
"to_agent_id": "bob-uuid",
"amount": 9.99,
"purpose": "tool usage",
"timestamp": "2025-01-15T12:34:56Z",
"delivered_at": "2025-01-15T12:34:56.123Z"
}
Verify in Node.js
import crypto from 'crypto';
function verifyWebhook(rawBody, signatureHeader, secret) {
const expected = 'sha256=' + crypto
.createHmac('sha256', secret)
.update(rawBody) // raw Buffer or string, before JSON.parse
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(expected),
Buffer.from(signatureHeader)
);
}
// In your Express/Fastify handler:
app.post('/hooks', (req, res) => {
const sig = req.headers['x-agentpay-signature'];
if (!verifyWebhook(req.rawBody, sig, WEBHOOK_SECRET)) {
return res.status(401).send('Invalid signature');
}
const event = JSON.parse(req.rawBody);
// handle event.event === 'payment.received' ...
res.sendStatus(200);
});
Verify in Python
import hmac, hashlib
def verify_webhook(raw_body: bytes, signature: str, secret: str) -> bool:
expected = 'sha256=' + hmac.new(
secret.encode(), raw_body, hashlib.sha256
).hexdigest()
return hmac.compare_digest(expected, signature)
# In your FastAPI/Flask handler โ use the raw request body, not parsed JSON
What counts as a transaction?
Any call to POST /api/payments or POST /api/accept increments your monthly transaction count. Whether you're the payer or the acceptor, it all draws from the same quota.
This means you can use AgentPay on one side, both sides, or build a marketplace where agents both pay and accept โ all on a single plan, one counter, one bill.
Generate a Stripe billing portal URL. Use this to manage your subscription, update payment methods, or download invoices.
Response
{
"url": "https://billing.stripe.com/session/..."
}
Health check. Returns 200 when the API is up.
Response
{
"status": "ok",
"timestamp": "2025-01-15T12:34:56Z"
}
Errors
All errors return JSON with an error field. HTTP status codes follow REST conventions.
| Status | Meaning |
| 400 | Bad request โ check your request body |
| 401 | Missing or invalid API key |
| 403 | Account inactive or access denied |
| 404 | Resource not found |
| 409 | Conflict โ e.g. email already registered |
| 500 | Internal server error |