Skip to content

Keys & Billing API ​

Create API Key ​

POST /v1/keys

Request Body ​

json
{
  "name": "Production Key",
  "expiresInDays": 90
}
FieldTypeDefaultDescription
namestring"Default"Key name (1-100 chars)
expiresInDaysnumber-Days until expiry (1-365). No expiry if omitted.

Response 201 ​

json
{
  "id": "key_abc123",
  "key": "plabs_sk_live_abc123...",
  "name": "Production Key",
  "expiresAt": "2026-06-21T00:00:00Z",
  "message": "Save this key - it will not be shown again."
}

DANGER

The raw API key is only returned once. Store it immediately in a secure location.

List Keys ​

GET /v1/keys?limit=20&cursor=key_xyz

Response 200 ​

json
{
  "data": [
    {
      "id": "key_abc123",
      "name": "Production Key",
      "prefix": "plabs_sk_live_abc1...",
      "createdAt": "2026-03-21T00:00:00Z",
      "expiresAt": "2026-06-21T00:00:00Z",
      "lastUsedAt": "2026-03-21T12:00:00Z"
    }
  ],
  "nextCursor": null,
  "hasMore": false
}

The raw key value is never returned in list responses. Only the prefix is shown.

Revoke Key ​

DELETE /v1/keys/:id

Response 204 ​

No content. The key is immediately invalidated.

Rotate Key ​

POST /v1/keys/:id/rotate

Creates a new key and revokes the old one atomically.

Response 200 ​

json
{
  "id": "key_new123",
  "key": "plabs_sk_live_new123...",
  "name": "Production Key",
  "message": "Save this key - it will not be shown again."
}

Get Usage ​

GET /v1/usage

Reflects a call as soon as that call's response has returned — the API waits for the usage write before replying, so there is no polling delay.

breakdown reports each modality in the unit it is billed in: characters for TTS, minutes of audio for STT, tokens for LLM, queries for RAG.

Response 200 ​

json
{
  "tier": "pro",
  "period": { "start": "2026-09-01T00:00:00.000Z", "end": "2026-09-30T23:59:59.999Z" },
  "credits": {
    "used": 12500,
    "included": 200000,
    "carryover": 0,
    "limit": 200000,
    "remaining": 187500,
    "overageAllowed": true,
    "overageRate": 0.0008,
    "overageCredits": 0,
    "overageCost": 0
  },
  "breakdown": {
    "sttMinutes": 2000,
    "ttsCharacters": 8000,
    "ragQueries": 500,
    "llmTokens": 2000
  },
  "requestCount": 3420
}

A metered endpoint returns X-Credits-Used, X-Credits-Limit and X-Credits-Remaining when the call was charged against your credits. A call that runs on your own provider key is not charged and carries X-Usage-Bypassed: byok instead of the three credit headers. Every response carries X-Request-Id, which is the trace id for that call.


Get Subscription ​

GET /v1/billing/subscription

Response 200 ​

json
{
  "tier": "pro",
  "tierDisplay": "Pro ($99/mo)",
  "credits": {
    "used": 12500,
    "limit": 200000,
    "remaining": 187500
  },
  "plan": {
    "monthlyCredits": 200000,
    "overageRate": 0.0008,
    "carryoverMonths": 1
  },
  "stripeCustomerId": "cus_abc123",
  "tierExpiresAt": "2026-04-21T00:00:00Z"
}

Create Checkout Session ​

Redirect the user to Stripe Checkout to subscribe or upgrade.

POST /v1/billing/checkout

Request Body ​

json
{
  "tier": "pro",
  "successUrl": "https://yourapp.com/billing/success",
  "cancelUrl": "https://yourapp.com/billing/cancel"
}
FieldTypeRequiredDescription
tierstringyesstarter, pro, or scale
successUrlstringyesRedirect URL on successful payment
cancelUrlstringyesRedirect URL on cancellation

Response 200 ​

json
{
  "url": "https://checkout.stripe.com/c/pay/...",
  "sessionId": "cs_live_abc123"
}

Billing Portal ​

Open the Stripe billing portal for subscription management, invoices, and payment methods.

POST /v1/billing/portal

Response 200 ​

json
{
  "url": "https://billing.stripe.com/p/session/..."
}

Built by ph0ny.