Reference
API
API tokens, the /v1/me endpoint, errors and rate limits for the Porro API on Agency and Enterprise.
The Porro API is on Agency and Enterprise. It's at https://app.porro.dev/api/v1, takes and returns JSON, and needs a token.
It's early. Today the API has one endpoint, GET /v1/me, so you can make tokens and check what each one can do. Endpoints for sites, findings, updates and reports come next, and this page will list each one as it goes live.
Tokens
Make a token in the workspace's Settings, under Integrations → API tokens. A token:
- belongs to you, in one workspace. Someone in two workspaces needs a token for each.
- starts
porro_pat_, is shown once, and is never stored in plain text. If you lose it, revoke it and make another. - can do no more than your role allows. Porro checks your role on every request, so if you're made a member, your tokens lose what members can't do straight away.
- stops working when it's revoked, when it expires, or when you leave or are removed from the workspace.
Send it as a Bearer token:
curl https://app.porro.dev/api/v1/me \
-H "Authorization: Bearer porro_pat_…"
GET /v1/me
Who the token belongs to, the workspace and its plan, what the token can do now, and how much of each limit is left:
{
"data": {
"user": {
"name": "Sam Lee",
"email": "[email protected]",
"role": "admin"
},
"team": { "slug": "kestrel-digital", "name": "Kestrel Digital" },
"plan": { "key": "agency", "name": "Agency", "state": "subscribed" },
"token": {
"name": "Deploy script",
"hint": "porro_pat_…a1b2",
"abilities": ["sites:read", "findings:read"],
"paused_abilities": [],
"role_allows": ["sites:read", "findings:read", "…"],
"created_at": "2026-10-29T09:00:00+00:00",
"expires_at": null
},
"limits": {
"requests": {
"token": { "limit": 120, "remaining": 119 },
"team": { "limit": 600, "remaining": 597 }
},
"members": { "limit": null, "used": 6 },
"sites": { "included": 120, "used": 84 }
}
}
}
paused_abilities are ones the token was given but your role doesn't allow right now.
Abilities
When you make a token, you choose what it may do. Only GET /v1/me exists so far, and any token can call it. The rest are for the endpoints on the way, so a token you make now can be ready for them.
| Ability | For | Roles |
|---|---|---|
sites:read |
Reading sites, clients, care plans and packages | everyone |
findings:read |
Reading findings and fix briefs | everyone |
updates:read |
Reading waiting updates, pull requests, rounds | everyone |
reports:read |
Reading past reports and previews | everyone |
advisories:read |
Reading security advisories | everyone |
servers:read |
Reading servers and their read-only host data | everyone |
findings:write |
Acknowledging, snoozing and noting findings | everyone |
updates:write |
Opening update pull requests, never past a major | everyone |
reports:send |
Sending client reports | owners, admins |
New tokens have the read abilities ticked.
Errors
Errors have a stable code to act on, a message for people, and a link back here:
{
"error": {
"code": "unauthenticated",
"message": "…",
"docs": "https://porro.dev/docs/api#errors"
}
}
| Status | Code | Means |
|---|---|---|
| 401 | unauthenticated |
No token, or it's wrong, expired or revoked |
| 402 | plan_limit |
The workspace's plan doesn't include the API. See upgrade_url |
| 403 | missing_ability |
The token, or your role, doesn't allow this. ability says which |
| 403 | forbidden |
Not allowed for another reason |
| 404 | not_found |
Nothing here |
| 405 | method_not_allowed |
Wrong HTTP method for this path |
| 429 | rate_limited |
Too many requests. Wait for Retry-After seconds |
| 500 | server_error |
Something broke on our side |
Rate limits
Each token can make 120 requests a minute, and a workspace 600 a minute across all its tokens. Responses carry X-RateLimit-Limit and X-RateLimit-Remaining for the token. Over either limit, you get a 429 with Retry-After.
Plans
The API is on Agency and Enterprise. If a workspace moves to a plan without it, its tokens are kept but answer 402 with code: plan_limit and an upgrade_url, and work again once it moves back.