Reference
REST API
Read your plans, subscribers and payments from your own server. The dashboard runs on the same API.
Authentication
The API lives at https://api.solloop.app/v1. Send an API key from Developers in the dashboard as a bearer token. Keys start sk_test_ on devnet and sk_live_ on mainnet. A key can do anything your account can, so it belongs on your server and never in a browser or an app.
curl https://api.solloop.app/v1/subscribers/H7q2vzHNemDGuPjgsLgVGUeCx5p9UmNZ2xVvKXi6hbzk \
-H "Authorization: Bearer sk_test_…"Conventions
- Requests and responses are JSON.
- Amounts are strings in the token's base units. USDC has six decimals, so
"49000000"is 49 USDC. Strings, because the numbers can exceed what a JavaScript number holds exactly. - Times are ISO 8601 strings in UTC.
Endpoints
| Endpoint | What it does |
|---|---|
| GET /plans | Your plans. |
| GET /plans/:id | One plan. |
| PATCH /plans/:id | Change the name or description. The on-chain terms are fixed. |
| POST /plans/:id/retire | Record a plan as retired, once the owner's wallet has signed the retire transaction on-chain. The dashboard does both. |
| GET /subscribers | Your subscribers. Filter with ?plan= and ?status=. |
| GET /subscribers/:address | A wallet's most recent subscription to one of your plans. |
| GET /payments | Collections. Filter with ?plan=, ?status=, ?from= and ?to=. |
| GET /payments/export | The same, as CSV. |
| GET /metrics | Monthly recurring revenue, active subscribers, churn and totals. |
| GET /public/plans/:id | A plan as the widget sees it. Needs no key. |
Errors
An error has one shape. Switch on code, which is stable; the message is for people and may change.
{
"error": {
"code": "not_found",
"message": "No subscriber with that address."
}
}| Status | code | Meaning |
|---|---|---|
| 400 | bad_request | Something in the request is invalid. The message says what. |
| 401 | unauthorized | No key, or a key that has been revoked. |
| 404 | not_found | There's nothing with that id on your account. |
| 409 | conflict | The request doesn't fit the current state, such as retiring a plan still active on-chain. |
| 429 | rate_limited | Too many requests. Wait for the Retry-After header. |
| 503 | rpc_unreachable | We couldn't reach Solana. Try again shortly. |
| 500 | internal_error | Our fault. Try again; it is logged. |
Rate limits
1,000 requests a minute per API key. Every response carries SolLoop-RateLimit-Limit and SolLoop-RateLimit-Remaining. Past the limit you get a 429 with a Retry-After header in seconds.