API for machines & AI agents
A small REST surface so an autonomous agent — a robot, a Home Assistant automation, a langgraph node, an n8n flow — can sign itself up, get an API key and start collecting Bitcoin Lightning payments for the hardware it controls. No browser, no human in the loop.
Base URL & auth
https://iotpay.botrift.com is the production base URL. All responses are JSON; all timestamps are ISO 8601 UTC.
Authenticate every request except POST /api/v1/accounts with Authorization: Bearer lib_xxx. Keys are issued by the signup endpoint and returned exactly once — store them in your secrets manager immediately.
CORS is open for browser-based agents. Preflight (OPTIONS) is supported on every endpoint.
30-second quickstart
Three calls: create account, prove the key works, post an event.
curl -X POST https://iotpay.botrift.com/api/v1/accounts \
-H "Content-Type: application/json" \
-d '{"label":"my-coffee-bot","lightning_address":"you@getalby.com"}'curl https://iotpay.botrift.com/api/v1/accounts/me \
-H "Authorization: Bearer lib_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"curl -X POST https://iotpay.botrift.com/api/v1/assets \
-H "Authorization: Bearer lib_xxxxxxxx" \
-H "Content-Type: application/json" \
-d '{"name":"Coffee machine","price_sats":1500}'curl -X POST https://iotpay.botrift.com/api/v1/assets/<asset_id>/payment-link \
-H "Authorization: Bearer lib_xxxxxxxx"curl -L -o iot-lightning-bridge-api.pdf https://iotpay.botrift.com/api/public/docs.pdfEndpoints
/api/v1/accounts/api/v1/auth/exchange/api/v1/accounts/me/api/v1/accounts/me/rotate-key/api/v1/assets/api/v1/assets/api/v1/assets/{id}/api/v1/assets/{id}/payment-link/api/v1/assets/{id}/payment-link/api/v1/assets/{id}/payments/api/public/events/api/public/events/api/public/events/{id}/api/public/docs.pdfAsset CRUD, signed outbound webhooks and scoped read-only keys are on the roadmap.
Monitor a bot from the GUI
Accounts provisioned via POST /api/v1/accounts have no email or password — they're identified purely by their api_key. To watch a bot's assets, payments and stats in the dashboard, log in with the API key:
- Open /login and switch to the API key tab.
- Paste the
lib_…key you stored at signup. - The server calls
POST /api/v1/auth/exchangebehind the scenes and saves a 24h session token. - You land on the same dashboard as an email-signed-up user — Assets, Payments, Settings all work identically.
You can also do the exchange yourself (e.g. for embedded dashboards):
curl -X POST https://iotpay.botrift.com/api/v1/auth/exchange \
-H "Content-Type: application/json" \
-d '{"api_key":"lib_xxxxxxxxxxxxxxxx"}'
# → { "token": "<pb-jwt>", "record": { ... }, "expires_in": 86400 }The token is a standard PocketBase auth token. Save it under the pb_auth_iot localStorage key, or send it as Authorization: <token> on PocketBase requests. Tokens expire after 24h — re-exchange with the API key to refresh.
Rate limits
60 requests per minute per API key. Exceeding the limit returns 429 with a Retry-After header (seconds).
5 signups per hour per IP on POST /api/v1/accounts. Build your fleet provisioning around this — one key per agent, not one key per request.
Errors
| Status | Code | Meaning |
|---|---|---|
| 400 | invalid_body / invalid_json | Validation failed on the request body or query. |
| 401 | missing_token / invalid_token / invalid_key | No Authorization header, malformed key, or unknown key. |
| 403 | asset_not_owned | You tried to act on a resource that belongs to another account. |
| 404 | asset_not_found | The referenced resource does not exist. |
| 409 | duplicate_event | An event with the same external_id already exists. Treat as success. |
| 429 | rate_limited | Too many requests. Inspect Retry-After and back off. |
| 500 | lookup_failed / backend_unavailable | Transient backend error. Retry with exponential backoff. |
Every error body is { "error": "code", "message": "..." }. Treat unknown codes the same as a 500.