Authentication
Every request to the API and to the MCP server is authenticated with an API key. There is no OAuth dance and no session to keep alive: one header, one key.
API keys
Keys are created in the app under Settings » Developers. Each key has a name so you can tell them apart, and the full value is shown exactly once at creation. After that the app only shows the first characters, because the key itself is not stored anywhere: only a hash of it is, which is enough to recognise the key when you send it and useless to anyone who reads the database.
Keys can be created on the Pro and Agency plans, which are the plans that include the API and the MCP server. Keys belong to the account that created them and spend that account's credits. A team can have up to ten active keys, for example one per tool or one per client, and revoke any of them independently.
Sending the key
Put the key in the Authorization header as a bearer token. This is what every HTTP client, Claude Code's --header flag and the MCP configuration of other clients expect.
Bearer token
curl https://suvjexogmfpvxjcktvuk.supabase.co/functions/v1/api/v1/me \
-H "Authorization: Bearer pk_live_YOUR_KEY"
If a tool reserves Authorization for something else, X-API-Key works as well.
X-API-Key header
curl https://suvjexogmfpvxjcktvuk.supabase.co/functions/v1/api/v1/me \
-H "X-API-Key: pk_live_YOUR_KEY"
A request without a valid key gets a 401 with a WWW-Authenticate: Bearer header and an error body explaining where to create one.
Checking who you are
GET /v1/me returns the account behind the key: plan, credits, and the id and prefix of the key you used. It costs nothing and is the quickest way to confirm a key works.
GET /v1/me
{
"email": "you@example.com",
"plan": "starter",
"subscription_status": "active",
"credits": 483.5,
"monthly_credits": 500,
"unlimited": false,
"key": { "id": "98f0fc43-...", "prefix": "pk_live_FbgU" }
}
Keeping keys safe
A key is a password. Anyone who has it can spend your credits until you revoke it.
- Never ship a key to a browser. The API sends no CORS headers on purpose, so a page cannot call it directly. Call it from your server, a serverless function, an automation platform or a desktop tool.
- Never commit a key. Read it from an environment variable such as
PENGU_API_KEY. Thepk_live_prefix exists so secret scanners recognise it if it does slip into a repository. - Rotate on suspicion. Revoking a key takes effect immediately; anything still using it gets a
401on its next call. Create the replacement first, switch, then revoke. - One key per integration. When something leaks, you revoke one key and everything else keeps working.
API keys cannot create other API keys. Key management is only possible from the app with your login, so a leaked key can never turn itself into a permanent foothold.
Daily cap
Each key carries its own daily credit cap, a fifth of the plan's monthly credits by default. It is the safety net for automations: a loop that goes wrong stops at the cap instead of at an empty account. See Credits and pricing.
Rate limits
Each key is allowed 60 requests per minute, counted centrally so parallel requests are counted together, on top of the credit balance. Credits cap how much you can spend; the rate limit caps how fast. Over the limit you get a 429 with a Retry-After header. Back off for that many seconds and try again.
