API reference
The gateway surface: authentication, device login, entitlement, models, and inference.
Base URL
https://api.sknib.com
Authentication
Send a bearer token on every request except the two device endpoints.
Authorization: Bearer sk-nib-...
Two credential shapes are accepted: a device token issued by nib login, and an API key created in the console. Both resolve to the same user, plan, and credits.
Errors
Errors use the OpenAI shape so existing SDKs surface a useful message.
{ "error": { "type": "insufficient_quota", "message": "Monthly credits exhausted" } }
| Status | Type | Meaning |
|---|---|---|
| 401 | authentication_error | Missing, expired, or revoked credential |
| 402 | insufficient_quota | Credits exhausted, including top-up balance |
| 403 | permission_error | Plan does not include the requested model |
| 429 | rate_limit_error | Concurrency or RPM exceeded |
| 5xx | api_error | Gateway 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://sknib.com/device",
"verification_uri_complete": "https://sknib.com/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. tier is the only extension.
{
"object": "list",
"data": [
{ "id": "nib-efficient", "object": "model", "owned_by": "nib", "tier": "efficient" },
{ "id": "nib-frontier", "object": "model", "owned_by": "nib", "tier": "frontier" }
]
}
Inference
| Protocol | Path | Used by |
|---|---|---|
| OpenAI Chat Completions | POST /v1/chat/completions | Most editors and SDKs |
| OpenAI Responses | POST /v1/responses | Codex-style clients |
| Anthropic Messages | POST /v1/messages | Claude Code, Anthropic SDK |
| Gemini | POST /v1beta/models/{model}:generateContent | Google SDK |
Usage accounting is identical across protocols. The same request costs the same credits regardless of which endpoint it arrives on.
Response headers
| Header | Meaning |
|---|---|
x-nib-credits-charged | Credits charged for this request |
x-nib-credits-remaining | Plan credits left in the current period |
x-nib-request-id | Support reference |
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
tierand the credit headers.
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.