Reseller accounts
What a reseller account is
accounts.is_reseller is an account type, not a plan. It's a boolean
flag an operator can flip on any account, on any plan — including Free.
There's no separate reseller plan or pricing; the flag just makes every
existing plan limit unlimited for that account:
- Site quota — unlimited, for both creating new sites and reactivating paused ones.
- Site key and account key counts — no cap (normally 2 active site keys per site, 10 active account keys per account).
- The paid-plan API gate — the read API, the Account API, and MCP all become reachable regardless of plan slug, so a reseller sitting on the Free plan still gets full API/MCP access.
- Retention — events are never purged by the retention worker.
- Fair use — the monthly fair-use email never fires.
- Downgrades — a plan change (including a Stripe-driven downgrade to Free) never pauses the account's sites.
- Limits readouts — the dashboard's
/me,/usage, and/billingresponses all report unlimited limits for a reseller account.
The flag never changes accounts.plan. A reseller account keeps
whatever plan slug it had — flipping the flag off restores exactly that
plan's normal limits, immediately.
Set the flag
POST {base}/admin/accounts/{id}/reseller where {base} is
https://api.hellolog.io/v1/wordpress-activity-audit-log.
curl -X POST https://api.hellolog.io/v1/wordpress-activity-audit-log/admin/accounts/3fa85f64-5717-4562-b3fc-2c963f66afa6/reseller \
-H "Authorization: Bearer <ADMIN_TOKEN>" \
-H "Content-Type: application/json" \
-d '{"enabled":true}'
204 No Content on success. Send {"enabled":false} to turn it back off —
this restores the account's normal plan limits right away, it does not
touch accounts.plan.
Errors
| Status | When | Body |
|---|---|---|
| 401 | Missing or invalid bearer token | {"error":"missing bearer token"} / {"error":"invalid token"} (varies by failure) |
| 403 | Token is valid but lacks the admin:write scope | {"error":"missing scope: admin:write"} |
| 404 | Account id doesn't exist | {"error":"not found"} |
| 404 | Account id isn't a valid UUID | {"error":"not found"} |
A malformed id and an unknown-but-well-formed id both answer the same
404 — the endpoint doesn't distinguish "not a UUID" from "no such
account" so a caller can't use the difference to enumerate account ids.
Reading the flag back
GET {base}/admin/accounts/{id} includes is_reseller alongside the rest
of the account:
curl https://api.hellolog.io/v1/wordpress-activity-audit-log/admin/accounts/3fa85f64-5717-4562-b3fc-2c963f66afa6 \
-H "Authorization: Bearer <ADMIN_TOKEN>"
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"email": "[email protected]",
"plan": "starter",
"is_reseller": true,
"created_at": "2026-07-01T10:00:00Z",
"sites": [
{
"id": "9d2c1e4a-6b8f-4a3d-9c7e-1f5a8b2d3c4e",
"account_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"domain": "shop.example.com",
"site_url": "https://shop.example.com",
"name": "Main store",
"status": "active",
"rate_limit_rps": 5,
"retention_days": 90,
"created_at": "2026-07-01T10:05:00Z",
"active_token_count": 1
}
]
}
plan stays "starter" here even though the account is unlimited — that's
the point: the flag layers on top of the plan, it never rewrites it.
GET {base}/admin/accounts (the account list) includes the same
is_reseller field on every row.
Also requires admin:write
Like every other mutating admin route, this one sits behind
RequireAdminScope("admin:write") — a read-only admin token
(admin:read only) can look up is_reseller on an account but can't flip
it.