Documentation

Linka API docs

Everything you need to call every major LLM through one OpenAI-compatible endpoint: https://api.linka.ink/v1.

Quickstart

Linka speaks the OpenAI chat-completions protocol, so if you have working OpenAI code you are one base-URL change away from every model on the platform.

  1. Create an account and API key. Sign in to the Linka console at app.linka.ink, top up your balance (any amount from $10), and generate a key. Keys begin with sk-linka-.
  2. Point your client at Linka. The base URL is https://api.linka.ink/v1.
  3. Make your first request. Pick any model ID from the models page and send a chat completion:
curl
curl "https://api.linka.ink/v1/chat/completions" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer sk-linka-your-key" \
  -d '{
    "model": "openai/gpt-4o",
    "messages": [
      { "role": "user", "content": "Hello from Linka!" }
    ]
  }'
python — openai SDK
from openai import OpenAI

client = OpenAI(
    api_key="sk-linka-your-key",
    base_url="https://api.linka.ink/v1",
)

resp = client.chat.completions.create(
    model="anthropic/claude-sonnet-4.5",
    messages=[{"role": "user", "content": "Hello from Linka!"}],
)

print(resp.choices[0].message.content)
print(resp.usage)  # prompt_tokens, completion_tokens, cost_credits
node — openai SDK
import OpenAI from "openai";

const client = new OpenAI({
  apiKey: "sk-linka-your-key",
  baseURL: "https://api.linka.ink/v1",
});

const resp = await client.chat.completions.create({
  model: "google/gemini-2.5-flash",
  messages: [{ role: "user", content: "Hello from Linka!" }],
});

console.log(resp.choices[0].message.content);

That is the whole integration. Change only the model string to route the same request to any other provider on the platform.

Authentication

Every request must carry your API key as a Bearer token in the Authorization header:

http header
Authorization: Bearer sk-linka-your-key
  • Keys are shown once at creation. Store them like passwords.
  • Create separate keys per environment or service, with per-key spend caps, in the console.
  • If a key leaks, revoke it in the console immediately — revocation is instant — then email support@linka.ink if you see usage you do not recognize.

Endpoints

EndpointDescription
POST /v1/chat/completionsCreate a chat completion. Supports streaming, tool calling, JSON mode, and fallback chains.
GET /v1/modelsList available models with context lengths and current per-token pricing.
GET /v1/credits/balanceReturn your current prepaid credit balance and lifetime totals.
list models
curl "https://api.linka.ink/v1/models" \
  -H "Authorization: Bearer sk-linka-your-key"

# {
#   "object": "list",
#   "data": [
#     {
#       "id": "openai/gpt-4o",
#       "object": "model",
#       "context_length": 128000,
#       "pricing": { "prompt": 2.50, "completion": 10.00 }
#     },
#     ...
#   ]
# }
check balance
curl "https://api.linka.ink/v1/credits/balance" \
  -H "Authorization: Bearer sk-linka-your-key"

# {
#   "balance": 48.21,
#   "currency": "USD",
#   "lifetime_topups": 60.00,
#   "lifetime_usage": 11.79
# }

Routing & fallbacks

Model IDs use the provider/name format, e.g. anthropic/claude-sonnet-4.5. For production workloads, pass a models array instead of a single model to define an ordered fallback chain:

request body — fallback chain
{
  "models": [
    "anthropic/claude-sonnet-4.5",
    "openai/gpt-4o",
    "google/gemini-2.5-pro"
  ],
  "messages": [ { "role": "user", "content": "Summarize this ticket." } ]
}

Linka tries each model in order and returns the first successful response. The model that actually served the request is always in the response's model field, and you are billed at that model's rate. Failover across providers typically adds one round-trip of latency.

Streaming

Set "stream": true to receive server-sent events. The stream emits chat.completion.chunk objects and terminates with data: [DONE]. Streamed requests are billed exactly like non-streamed requests once the stream completes.

curl — streaming
curl "https://api.linka.ink/v1/chat/completions" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer sk-linka-your-key" \
  -d '{
    "model": "deepseek/deepseek-chat-v3",
    "stream": true,
    "messages": [ { "role": "user", "content": "Count to five." } ]
  }'

# data: {"id":"chatcmpl-linka-...","choices":[{"delta":{"content":"1"}}]}
# data: {"id":"chatcmpl-linka-...","choices":[{"delta":{"content":", 2"}}]}
# ...
# data: [DONE]

Error codes

Errors return a non-2xx status and a JSON body with a machine-readable type:

error response body
{
  "error": {
    "message": "Insufficient credits. Top up your balance to continue.",
    "type": "insufficient_credits",
    "code": 402
  }
}
CodeTypeMeaningWhat to do
400invalid_requestThe request body is malformed or a parameter is invalid.Check the JSON body and parameter names against this documentation.
401authentication_errorMissing or invalid API key.Send Authorization: Bearer sk-linka-... with an active key.
402insufficient_creditsYour prepaid balance is too low to serve the request.Top up in the console; the request is not served and nothing is billed.
404not_foundUnknown model ID or endpoint.Check the model ID on the models page or via GET /v1/models.
429rate_limitedToo many requests for your key.Back off and honor the Retry-After header.
500internal_errorSomething went wrong on Linka's side.Retry with exponential backoff; contact support if it persists.
502upstream_errorThe upstream provider returned an error.Retry, or configure a fallback model chain.
503upstream_unavailableThe upstream provider is temporarily unavailable.Retry shortly; fallback chains reroute automatically.

Rate limits

Default limits are 600 requests per minute and 60 concurrent requests per API key, across all models. Exceeding either returns 429 with a Retry-After header.

Need more? We routinely raise limits for funded accounts — email support@linka.ink with your expected throughput.

Billing notes

  • Every response includes a usage object with prompt_tokens, completion_tokens, and cost_credits — the exact amount deducted for that call.
  • Requests that fail with a 4xx error are never billed. Upstream 5xx failures are refunded automatically to your balance.
  • When your balance cannot cover a request, the API returns 402 insufficient_credits and nothing is served or charged.
  • Credits never expire. Unused credits are refundable within 14 days of top-up — see the refund policy.