API key

API reference

Account API

Script your Paranine account from code: API keys, usage and request logs, models and balance.

The Account API is the API the dashboard is built on. Use it to automate key rotation, pull usage and request logs into your own systems, or check your balance. To manage your account from an AI coding tool, P/9Dev MCP is usually simpler.

https://sovereign.paranine.com/api

Every call acts on your own organisation; there is no organisation id to send.

Signing in

The Account API uses a signed-in session, not an API key: sk_p9_ keys work only for models. Sign in once, keep the session cookies, and send them with every call:

# Sign in and store the session cookies
curl -c cookies.txt -X POST https://sovereign.paranine.com/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{"email": "you@company.com", "password": "…"}'

# Call the API with the session
curl -b cookies.txt https://sovereign.paranine.com/api/auth/me

# Renew the session when a call answers 401, then retry
curl -b cookies.txt -c cookies.txt -X POST https://sovereign.paranine.com/api/auth/refresh
EndpointWhat it does
POST /auth/loginSigns in with email and password, and sets the session cookies.
POST /auth/refreshRenews the session.
POST /auth/logoutSigns out.
GET /auth/meYour user and organisation.

A session lasts 15 minutes and can be renewed for up to 7 days; after that, sign in again. Repeated failed sign-ins are blocked for a while (429, with Retry-After).

Conventions

  • Money. Fields ending _cents are in millionths of a rupee (Rs 1 = 1,000,000). Fields ending _pkr are in rupees.
  • Time. Timestamps are ISO 8601 in Pakistan time, with the offset (2026-10-22T09:30:00+05:00). Send times with an offset too.
  • Paging. limit and offset; limit is at most 200.
  • Nulls. null means "not measured" or "none", never zero.

Endpoints

AreaEndpoints
API keysPOST /keys, GET /keys, PATCH /keys/{key_id}, DELETE /keys/{key_id}
ProjectsGET /projects
ModelsGET /models
BalanceGET /ledger/balance
Usage and request logsGET /analytics/summary, GET /analytics/timeseries, GET /analytics/requests, GET /analytics/attribution
Your own Anthropic keyPOST /vault/keys, GET /vault/keys, DELETE /vault/keys/{provider}

Projects

GET /projects lists your organisation's projects. Every organisation has at least one, and creating a key needs a project_id from this list.

{
  "projects": [
    {"id": "<uuid>", "name": "Default Project", "created_at": "2026-07-20T01:23:55.062436+05:00"}
  ]
}

Models

GET /models lists the models your organisation can call, with the price that applies to each (example values below):

{
  "models": [
    {
      "model": "paranine/gpt-oss-120b(Global)",
      "kind": "chat",
      "endpoint": "/v1/chat/completions",
      "pricing_unit": "token",
      "input_price_pkr_per_million": "30.0780",
      "output_price_pkr_per_million": "180.4680"
    }
  ],
  "as_of": "2026-10-22T09:30:00.412870+05:00"
}

kind is the model's type (for example chat, embedding or decision), and endpoint is the path to call it on. Prices are rupees per million of pricing_unit, as strings with four decimals.

Balance

GET /ledger/balance reports your organisation's credit and spend:

{
  "monthly_limit_cents": 1000000000,
  "current_spend_cents": 61050000,
  "monthly_limit_pkr": 1000.0,
  "current_spend_pkr": 61.05
}

monthly_limit_* is all the credit added to your organisation so far (despite the name, it doesn't reset monthly), and current_spend_* is what has been spent. Your balance is the difference. It can take a couple of minutes to reflect your latest requests; the request logs are up to date within seconds.

Errors

Errors carry a sentence for people under error and, for most, a stable code to branch on:

{"error": "an active key with this name already exists in this project; choose another name or revoke that key first", "code": "key_name_taken"}

A body that fails validation answers 422 with a list of field problems under detail, and a missing or expired session answers 401 {"detail": "Unauthorized"}.

StatusMeaning
400Invalid request: for example an expiry in the past, an unknown model id in allowed_models, or a credit cap below what the key has already spent.
401Not signed in, or the session expired. Renew it with POST /auth/refresh, or sign in again.
403Your role doesn't allow this.
404Not found, or not your organisation's: the API doesn't tell the two apart.
409A duplicate, such as a key name already used in the project.
422The body failed validation; see detail.
429Too many attempts. Wait for Retry-After.
503Temporarily unavailable. Retry after Retry-After, if present.

Something unclear or wrong on this page? Tell us. Machine-readable copies: llms.txt.