Developer docs

API documentation

lincorelink speaks the SDKs you already use. Point an OpenAI or Anthropic client at our base URL, swap in your key, and you are done — no new client, no rewrites.

Introduction

lincorelink is an API gateway for frontier AI models. It authenticates your request, meters your usage, and relays the call to a third-party large-language-model provider — currently DeepSeek V4 — then streams the response back to you. It speaks two wire protocols, so the SDKs and tools you already use work without changes:

  • OpenAI Chat CompletionsPOST /v1/chat/completions, for the OpenAI SDK, LangChain, the Vercel AI SDK, and anything OpenAI-compatible.
  • Anthropic MessagesPOST /v1/messages, for the Anthropic SDK and Anthropic-compatible agents such as Claude Code.

Both protocols share one sk-lcl-… key, one prepaid balance, and the same per-token pricing — pick whichever your code already speaks.

Base URL

bash
https://api.lincorelink.ai

OpenAI clients use the /v1 base (https://api.lincorelink.ai/v1); Anthropic SDKs take the root base and append /v1/messages themselves.

Endpoints

MethodPathDescription
POST/v1/chat/completionsOpenAI protocol. Create a chat response (streaming or non-streaming).
POST/v1/messagesAnthropic protocol. Create a message response (streaming or non-streaming).
GET/v1/modelsList the model IDs the platform exposes (availability per plan — see Models).

Authentication

The same sk-lcl-… key works for both protocols — present it the way your SDK expects. OpenAI clients send it as a Bearer token in the Authorization header; the Anthropic SDK sends it in the x-api-key header. We accept either on every endpoint. Create and manage keys in your dashboard. Keys are shown in full only once, at creation — store them securely, because we keep only a hash and cannot recover a key later.

bash
Authorization: Bearer sk-lcl-...   # OpenAI clients
x-api-key: sk-lcl-...               # Anthropic SDK

A missing or invalid key returns 401 with code invalid_api_key. Keep keys server-side; never embed them in browser, mobile, or other client-side code. If a key is exposed, revoke it in the dashboard — revocation takes effect immediately.

Quickstart (OpenAI)

Send your first request with cURL or any OpenAI SDK. Prefer the Anthropic SDK or Claude Code? Jump to Anthropic API.

cURL

bash
curl https://api.lincorelink.ai/v1/chat/completions \
  -H "Authorization: Bearer $LINCORELINK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "deepseek-v4-pro",
    "messages": [{ "role": "user", "content": "Hello!" }]
  }'

Python (OpenAI SDK)

python
from openai import OpenAI

client = OpenAI(
    base_url="https://api.lincorelink.ai/v1",
    api_key="sk-lcl-...",   # your lincorelink key
)

resp = client.chat.completions.create(
    model="deepseek-v4-pro",
    messages=[
        {"role": "system", "content": "You are concise."},
        {"role": "user", "content": "Hello!"},
    ],
)
print(resp.choices[0].message.content)

Node.js (OpenAI SDK)

node
import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "https://api.lincorelink.ai/v1",
  apiKey: process.env.LINCORELINK_API_KEY,
});

const resp = await client.chat.completions.create({
  model: "deepseek-v4-flash",
  messages: [{ role: "user", content: "Hello!" }],
});
console.log(resp.choices[0].message.content);

Chat completions

POST /v1/chat/completions accepts the standard OpenAI Chat Completions body. The most common parameters:

ParameterTypeDescription
modelstringRequired. One of deepseek-v4-flash or deepseek-v4-pro.
messagesarrayRequired. A non-empty list of { role, content } messages (system, user, assistant).
max_tokensintegerMaximum tokens to generate. Clamped to your plan's output cap (see Rate limits & tiers).
streambooleanIf true, tokens are sent as Server-Sent Events. See Streaming.
temperature, top_pnumberSampling controls, passed through to the provider.
stop, frequency_penalty, presence_penaltyvariousStandard OpenAI parameters, passed through to the provider.

Response

A non-streaming call returns a chat.completion object. The usage object includes cached vs non-cached input tokens, which is what we bill on (see Pricing & metering).

json
{
  "id": "chatcmpl-...",
  "object": "chat.completion",
  "created": 1734220000,
  "model": "deepseek-v4-pro",
  "choices": [
    {
      "index": 0,
      "message": { "role": "assistant", "content": "Hello! How can I help?" },
      "finish_reason": "stop"
    }
  ],
  "usage": {
    "prompt_tokens": 12,
    "completion_tokens": 7,
    "total_tokens": 19,
    "prompt_cache_hit_tokens": 0,
    "prompt_cache_miss_tokens": 12
  }
}

Streaming

Set stream: true to receive tokens incrementally as Server-Sent Events, exactly like the OpenAI API. Each event is a chat.completion.chunk with a delta; the stream ends with a data: [DONE] line.

To receive token usage at the end of a stream, set stream_options.include_usage = true; a final frame then carries the usage object. If you do not request it, we strip our internal usage frame so the stream stays byte-for-byte like a native OpenAI stream.

python
stream = client.chat.completions.create(
    model="deepseek-v4-pro",
    messages=[{"role": "user", "content": "Write a haiku about the edge"}],
    stream=True,
    stream_options={"include_usage": True},  # optional: get a final usage frame
)
for chunk in stream:
    if chunk.choices:
        print(chunk.choices[0].delta.content or "", end="")

Anthropic API

lincorelink also speaks the Anthropic Messages API, so the Anthropic SDKs and Anthropic-compatible agents (including Claude Code) work against the same key and balance. Send a POST to /v1/messages with a standard Anthropic body — note that max_tokens is required, and system is a top-level field rather than a message. As on the OpenAI endpoint, max_tokens is clamped to your plan's output cap (see Rate limits & tiers). Token counting via POST /v1/messages/count_tokens is supported too (Claude Code uses it for context budgeting).

Models

Pass a lincorelink model id (deepseek-v4-pro or deepseek-v4-flash) directly. For drop-in use with existing Anthropic tools, Claude model names are mapped automatically: anything with opus maps to deepseek-v4-pro, and every other name (Sonnet, Haiku, or unknown) maps to deepseek-v4-flash. Set the model explicitly when you want to control which tier you are billed at.

cURL

bash
curl https://api.lincorelink.ai/v1/messages \
  -H "x-api-key: $LINCORELINK_API_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "deepseek-v4-pro",
    "max_tokens": 1024,
    "messages": [{ "role": "user", "content": "Hello!" }]
  }'

Python (Anthropic SDK)

python
from anthropic import Anthropic

client = Anthropic(
    base_url="https://api.lincorelink.ai",  # SDK appends /v1/messages
    api_key="sk-lcl-...",                    # your lincorelink key
)

msg = client.messages.create(
    model="deepseek-v4-pro",
    max_tokens=1024,
    system="You are concise.",
    messages=[{"role": "user", "content": "Hello!"}],
)
print(msg.content[0].text)

Node.js (Anthropic SDK)

node
import Anthropic from "@anthropic-ai/sdk";

const client = new Anthropic({
  baseURL: "https://api.lincorelink.ai",   // SDK appends /v1/messages
  apiKey: process.env.LINCORELINK_API_KEY,
});

const msg = await client.messages.create({
  model: "deepseek-v4-flash",
  max_tokens: 1024,
  messages: [{ role: "user", content: "Hello!" }],
});
console.log(msg.content[0].text);

Response

A non-streaming call returns a standard Anthropic message. We meter on the same token counts the provider reports — cache_read_input_tokens is billed at the cached-input rate, and input_tokens plus cache_creation_input_tokens at the fresh-input rate (see Pricing & metering).

json
{
  "id": "...",
  "type": "message",
  "role": "assistant",
  "model": "deepseek-v4-pro",
  "content": [{ "type": "text", "text": "Hello! How can I help?" }],
  "stop_reason": "end_turn",
  "usage": {
    "input_tokens": 12,
    "output_tokens": 7,
    "cache_read_input_tokens": 0,
    "cache_creation_input_tokens": 0
  }
}

Streaming

Set stream: true for an Anthropic-native event stream (message_start, content_block_delta, message_delta, message_stop). Token usage is part of the protocol — it arrives on message_start and the final message_delta— so nothing extra is needed to get it.

Claude Code

Point Claude Code (or any agent that reads the ANTHROPIC_* environment variables) at lincorelink:

bash
# Point Claude Code (or any Anthropic-compatible agent) at lincorelink
export ANTHROPIC_BASE_URL=https://api.lincorelink.ai
export ANTHROPIC_AUTH_TOKEN=sk-lcl-...        # sent as Authorization: Bearer
export ANTHROPIC_MODEL=deepseek-v4-pro        # main model
export ANTHROPIC_SMALL_FAST_MODEL=deepseek-v4-flash

claude   # start coding

Gateway errors on this endpoint use the Anthropic error shape ({ "type": "error", "error": { "type", "message" } }), so Anthropic SDK error handling works unchanged.

Models

Model IDBest forNotes
deepseek-v4-flashHigh-volume, latency-sensitive, cheapAvailable on every plan, including Basic.
deepseek-v4-proHarder reasoning, agents, codeAvailable on Pro and Max plans.

Fetch the list any time with GET /v1/models (it returns every model the platform exposes; which ones your key may call depends on your plan, per the table above). More models and providers join the same key and balance over time.

Pricing & metering

Billing is prepaid and metered per token. You are charged on the usage the provider reports, with cached input billed far cheaper than fresh (non-cached) input. Rates per 1M tokens (USD):

ModelInputCached inputOutput
deepseek-v4-flash$0.16$0.004$0.30
deepseek-v4-pro$0.60$0.005$1.20

Each request reserves an estimated maximum from your balance, then settles to the actual metered cost when it completes. A request is rejected up front with 402 if your balance cannot cover the estimate. See the pricing page for plans and the latest rates, which may change with notice.

Rate limits & tiers

Per-request context and output caps, concurrency, and any daily token cap depend on your plan. A request whose input exceeds the context cap is rejected before it reaches the provider (413 context_length_exceeded), and max_tokens is clamped to your output cap.

PlanContextMax outputConcurrencyDaily tokens
Basic (free)128K32K10100M
Pro256K32K20Unlimited
Max1M64K20Unlimited

When you exceed a limit you receive 429 with a Retry-After header — wait that many seconds, then retry with backoff.

Errors

On the OpenAI endpoints, errors use the OpenAI shape, so existing error handling works unchanged: { "error": { "message", "type", "param", "code" } }. On /v1/messages they use the Anthropic shape ({ "type": "error", "error": { "type", "message" } }). The HTTP status codes below apply to both.

json
{
  "error": {
    "message": "Insufficient balance. Top up to continue.",
    "type": "insufficient_quota",
    "param": null,
    "code": "insufficient_funds"
  }
}
StatuscodeMeaning
400model_not_foundMalformed request, or an unknown model ID.
401invalid_api_keyMissing or invalid API key.
402insufficient_fundsBalance cannot cover the request. Top up to continue.
403model_not_availableThe model is not included in your plan (e.g. Pro model on Basic).
413context_length_exceededInput exceeds your plan's context cap.
429rate_limit_errorToo many requests / concurrency or daily cap reached. Honour Retry-After.
5xxapi_errorUpstream/provider error. Safe to retry with backoff.

Best practices

  • Keep keys server-side and rotate them periodically. Revoke immediately if one leaks.
  • Retry on 429 and 5xx with exponential backoff, and honour the Retry-After header when present.
  • Reuse system prompts and prefixes to benefit from cached-input pricing, which is roughly 50× cheaper than fresh input.
  • Set max_tokens deliberately so reservations against your balance stay tight and predictable.
  • Stream long responses for better perceived latency, and request include_usage if you need token counts.

Need a key? Create an account, top up a few dollars, and make your first call in minutes.