API reference

The gateway surface: authentication, device login, entitlement, models, and inference.

Base URL

https://api.nib.am/v1

Inference lives on its own host. OpenAI-compatible clients take https://api.nib.am/v1 as the base URL (so a client appends /chat/completions to it); Anthropic and Gemini paths hang off the same host.

Authentication

Send a bearer token on every request except the two device endpoints.

Authorization: Bearer sk-nib-...

API keys are created in the console under API keys. The key is the only credential the gateway accepts; it resolves to your account, plan, and credit balance. Console sessions use a separate token and are what the settings pages call.

Errors

Errors use the OpenAI shape so existing SDKs surface a useful message.

{ "error": { "type": "insufficient_quota", "message": "Monthly credits exhausted" } }
StatusTypeMeaning
401authentication_errorMissing, expired, or revoked credential
402insufficient_quotaCredits exhausted, including top-up balance
403permission_errorPlan does not include the requested model
429rate_limit_errorConcurrency or RPM exceeded
5xxapi_errorGateway or upstream failure

Device login

POST /api/v1/cli/device/authorize

No authentication. Returns a device code and a short user code.

{
  "device_code": "3f0c2a1e-...",
  "user_code": "MKGX-36FF",
  "verification_uri": "https://nib.am/device",
  "verification_uri_complete": "https://nib.am/device?code=MKGX-36FF",
  "expires_in": 600,
  "interval": 5
}

POST /api/v1/cli/device/token

Poll at interval seconds. Pending responses return HTTP 400 with {"error":"authorization_pending"}. Success returns:

{
  "access_token": "nib_dev_...",
  "token_type": "Bearer",
  "expires_in": 7776000
}

Other error codes: slow_down, access_denied, expired_token.

Entitlement

GET /api/v1/product/entitlement

{
  "plan": {
    "id": "starter-promo",
    "name": "Starter",
    "price_usd": 15,
    "effective_price_usd": 10,
    "currency": "USD",
    "promotional": true,
    "promotional_until": "2027-01-31T00:00:00Z",
    "monthly_credits": 300,
    "weekly_credit_cap": 120,
    "daily_credit_cap": 45,
    "concurrency": 3,
    "requests_per_minute": 120
  },
  "usage": {
    "credits_used": 114.0,
    "credits_used_this_week": 42.5,
    "credits_used_today": 16.2,
    "topup_credits_remaining": 0,
    "resets_at": "2026-11-14T08:00:00Z"
  },
  "models": { "available": 42 }
}

All monetary values are numbers in USD, never strings. Caps may be null when unset; the field itself is always present.

Models

GET /v1/models

OpenAI-compatible listing of the models your account can reach. Model ids are the vendor ids themselves — claude-sonnet-5, gpt-6-sol, gemini-3.8-flash — so a request written against a vendor's own documentation works unchanged.

{
  "object": "list",
  "data": [
    { "id": "claude-sonnet-5", "object": "model", "owned_by": "anthropic" },
    { "id": "gpt-6-sol", "object": "model", "owned_by": "openai" }
  ]
}

The full catalogue is on the Models page.

Inference

ProtocolPathUsed by
OpenAI Chat CompletionsPOST /v1/chat/completionsMost editors and SDKs
OpenAI ResponsesPOST /v1/responsesCodex-style clients
Anthropic MessagesPOST /v1/messagesClaude Code, Anthropic SDK
GeminiPOST /v1beta/models/{model}:generateContentGoogle SDK

Usage accounting is identical across protocols. The same request costs the same credits regardless of which endpoint it arrives on.

Usage and credits

Each response reports the tokens it used in the vendor's own shape (usage for OpenAI, usage for Anthropic, usageMetadata for Gemini). Charges are recorded server-side and appear on the console Usage page against the same credit balance the app shows. Ten credits equal one dollar of usage.

The response also carries the upstream request id, which is what to quote in a support request:

HeaderMeaning
x-request-idUpstream request id, for support
openai-processing-msUpstream latency, when the provider reports it

Versioning

  • Breaking changes ship under /api/v2. v1 stays available for at least six months after v2 ships.
  • Adding optional response fields is not a breaking change.
  • Removing or renaming a field is breaking, including the usage block and the request-id header.

Rate limits

Concurrency and RPM follow your plan and are exposed in the entitlement payload. A 429 response includes retry-after in seconds. Client-side, back off exponentially and cap retries at three.