Rate limits
The per-IP and per-identity request ceilings on the penv.cloud API, plan limits, the 429 response and back-off.
| Ceiling | Keyed on | Limit | Applies to |
|---|---|---|---|
| IP | First hop of x-forwarded-for | 1000 requests per minute | Every call, before we read the credential |
| Identity | The identity your credential names | Per your plan, below | Every authenticated call |
| Workspace | Your workspace | Free only, below | Every authenticated call, on top of the identity ceiling |
Every counter resets on a fixed one-minute window.
IP ceiling
We count it before authentication, so a flood of invalid tokens is turned away before any credential check.
It caps abuse, not your use, and sits well above one pipeline, a CI egress range or a NAT with many identities. The exchange routes under /api/v1/auth have no identity yet, so only this ceiling applies to them.
Identity ceiling
| Bucket | Operations |
|---|---|
read | GET /api/v1/secrets, GET /api/v1/secrets/{address}, GET /api/v1/bulk-read-secrets, HEAD and GET /api/v1/envs/{org}/{project}/{environment} (penv run, penv pull), POST /api/v1/dynamic/{address}/lease |
write | PUT /api/v1/secrets/{address}, DELETE /api/v1/secrets/{address}, PUT /api/v1/envs/... (penv push), PATCH and DELETE /api/v1/envs/.../keys/... (penv set, penv unset) |
| Plan | Reads per minute | Writes per minute |
|---|---|---|
| Free | 240 | 60 |
| Pro | 2000 | 300 |
| Enterprise | Custom | Custom |
The pricing page shows the same numbers. Change your plan: billing and plans.
We key the counter on the identity, not the credential, so rotating your credential does not reset it. Two identities in one project count separately.
GET /api/v1/bulk-read-secrets and GET /api/v1/envs/... cost one read per value they open: an environment of 40 values spends 40 reads. We skip addresses that mint on demand, and they cost nothing. A HEAD, or a GET answered 304, costs one.
A bulk read that overshoots leaves the bucket over its ceiling until the minute ends; the next minute starts at zero.
Workspace ceiling
Free only. Every identity and every person's CLI in the workspace draws on it, at the same cost as the identity ceiling. We check your identity first, so a request the workspace ceiling refuses still counts against your identity's minute.
| Plan | Reads per minute | Writes per minute |
|---|---|---|
| Free | 600 | 150 |
| Pro, Enterprise | None | None |
Machine identities are free and unlimited (billing), so without this ceiling more identities would mean more Free throughput. The refusal is the same 429: retry-after gives the wait.
429 response
HTTP/1.1 429 Too Many Requests
retry-after: 17{ "error": "rate_limited" }retry-after is whole seconds until the window resets, never below 1. We return the same body for every ceiling, because naming the ceiling would reveal more about other tenants than about you.
POST /api/v1/dynamic/{address}/lease has a separate 429, ceiling_reached, when your environment trips our abuse ceiling on minting credentials. Codes: error codes.
Back-off
const res = await fetch(url, { headers: { authorization: `Bearer ${credential}` } });
if (res.status === 429) {
const wait = Number(res.headers.get("retry-after") ?? 1) * 1000;
await new Promise((done) => setTimeout(done, wait));
}Sleep for retry-after seconds, then retry. Without the header, wait one second and double on each further 429, up to a minute.
| Practice | Effect |
|---|---|
| Read once per job and pass values to one child process | One read per job; penv run works this way. |
Use GET /api/v1/bulk-read-secrets instead of one request per key | Fewer calls; still priced per value. |
| One machine identity per pipeline | Separate buckets; a shared identity shares one bucket. |
Next: versioning.
Register an app
How to register an app that connects to Penv Cloud: the console page, fields, client_id, redirect URI rules, testing mode, domain proof, verification, and what happens on suspension or deletion.
Versioning
What the /api/v1 prefix guarantees, which changes can happen inside it, the unversioned discovery paths, and the OpenAPI document.