Reference

First token in five minutes.

The API is OpenAI-compatible. Change the base URL, keep the client you already have, and read the rest of this sheet for the surface that goes beyond the schema.

BASE URL — api.idclinktech.com/v1 SCHEMA — OPENAI-COMPATIBLE AUTH — BEARER TOKEN

SEC.01 — GETTING STARTED

DOC 01.1

Quickstart

Every request goes to https://api.idclinktech.com/v1. Send a bearer token, name a model from the catalog, and the gateway resolves the route for you.

FIG.01 — REQUEST LIFECYCLE

REQUEST LIFECYCLE DWG IDC-RL-05 CLIENT PROVIDER [ GATEWAY ] AUTH SCHEMA NORMALIZE ROUTE 401 FAILS CLOSED X-IDC-Route provider/region/pool
POST https://api.idclinktech.com/v1/chat/completions
first-request.sh Shell
curl https://api.idclinktech.com/v1/chat/completions \
  -H "Authorization: Bearer $IDCLINKTECH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-opus-5",
    "messages": [{"role": "user", "content": "Say hello."}]
  }'

No SDK required. Any HTTP client that speaks the OpenAI schema already speaks this one.

NOTE 01.1 — TRIAL KEYS

Request one at sales@idclinktech.com with a short note on what you are building. Trial credit is sized to validate a real workload, not just a smoke test.

DOC 01.2

Authentication

Bearer-token authentication. Keys are scoped to a project, look like sk-idc-…, and can be rotated independently. Keep the key server-side; there is no browser-safe key format.

Request header Required Notes
Authorization Yes Format: Bearer sk-idc-…
Content-Type Yes application/json
X-IDC-Project No Bill the call against a specific project on a multi-project key
X-IDC-Region No Region hint: us-west, eu-fra, ap-sg
X-IDC-Route-Tier No Cap the tier the router may pick — see routing tiers
X-IDC-No-Retention No true forces a zero-retention route or fails closed

Samples on this page read the key from IDCLINKTECH_API_KEY. A rejected key returns 401 before the request reaches any upstream, so a bad key never costs you tokens.

DOC 01.3

Model names

Pass the model as a string. The value is the API ID printed in the catalog — stable across regions, with no replica or region encoded in the name. Six of the thirty-six:

API ID Provider Tier CTX
claude-fable-5 Anthropic Frontier 1M
gpt-5.6-sol OpenAI Frontier 1M
gemini-3.6-flash Google Frontier 1M
deepseek-v4-pro DeepSeek Frontier 1M
kimi-k3 Moonshot Frontier 1M
mistral-medium-3-5 Mistral Frontier 256K
  • Unknown ID404 model_not_found, raised at the gateway.
  • Retired ID — keeps resolving to its documented successor for a published alias window, the way a 301 works for URLs. Every window is announced in the changelog before it opens.
  • Closed weights resolve to their provider; open weights resolve to managed pools.

SEC.02 — CORE API

DOC 02.1

Chat completions

Request and response shapes mirror the OpenAI schema exactly. Provider dialects — system-prompt placement, tool envelopes, image parts — are normalized at the gateway, never in your adapter code.

Field Type Notes
model string Required. Catalog API ID.
messages array Required. Roles: system, user, assistant, tool.
max_tokens integer Output cap. Defaults to the model's own ceiling.
temperature number 0 – 2, normalized across providers.
top_p number Nucleus sampling. Send this or temperature, not both.
stream boolean Server-sent events. See streaming.
stop string / array Up to four stop sequences.
tools array Function definitions. Pairs with tool_choice.
response_format object json_schema is validated at the gateway; one silent retry on a schema miss, then the error surfaces.
seed integer Best-effort determinism where the upstream honors it.

Response body

completion.json JSON
{
  "id": "chatcmpl-01JQ8ZT4M6",
  "object": "chat.completion",
  "created": 1785312000,
  "model": "claude-opus-5",
  "choices": [
    {
      "index": 0,
      "message": {"role": "assistant", "content": "Hello."},
      "finish_reason": "stop"
    }
  ],
  "usage": {"prompt_tokens": 11, "completion_tokens": 3, "total_tokens": 14}
}
DOC 02.2

Streaming

Set stream: true. The response arrives as text/event-stream with standard SSE delta chunks, and the final frame is [DONE] exactly as in the upstream schema.

stream.py Python
from openai import OpenAI

client = OpenAI(base_url="https://api.idclinktech.com/v1", api_key="sk-idc-...")
stream = client.chat.completions.create(
    model="gpt-5.6-terra",
    messages=[{"role": "user", "content": "Stream a haiku about racks."}],
    stream=True,
)
for chunk in stream:
    print(chunk.choices[0].delta.content or "", end="")

Wire format

frames.txt SSE
data: {"id":"chatcmpl-01JQ8ZT4M6","object":"chat.completion.chunk","model":"gpt-5.6-terra","choices":[{"index":0,"delta":{"content":"Cold"},"finish_reason":null}]}

data: {"id":"chatcmpl-01JQ8ZT4M6","object":"chat.completion.chunk","model":"gpt-5.6-terra","choices":[{"index":0,"delta":{},"finish_reason":"stop"}]}

data: [DONE]

Response headers are flushed before the first token, so route and rate are readable while the stream is still open.

DOC 02.3

Tool calls

Pass a tools array on the request. Tool-capable models answer with tool_calls on the assistant message instead of prose; you run the function and reply with a tool-role message carrying the same tool_call_id.

tools-request.json JSON
{
  "model": "gpt-5.6-sol",
  "messages": [
    {"role": "user", "content": "How hot is rack B-14 right now?"}
  ],
  "tools": [
    {
      "type": "function",
      "function": {
        "name": "get_rack_temp",
        "description": "Read the current inlet temperature for one rack.",
        "parameters": {
          "type": "object",
          "properties": {
            "rack_id": {
              "type": "string",
              "description": "Rack label, for example B-14."
            }
          },
          "required": ["rack_id"]
        }
      }
    }
  ],
  "tool_choice": "auto"
}

Returning the result

Append the assistant message you received, then the tool result. arguments and content are both JSON-encoded strings, not objects.

tool-result.json JSON
{
  "role": "tool",
  "tool_call_id": "call_01JQ8ZT4M6",
  "content": "{\"rack_id\":\"B-14\",\"celsius\":24.6}"
}

tool_choice accepts auto, none, required, or a named function. Models without tool support return 400 invalid_request rather than silently dropping the array.

DOC 02.4

Vision input

Send image parts inside the message content array. Public URLs and base64 data URIs are both accepted; vision-capable models carry the v tag in the catalog.

vision-request.json JSON
{
  "model": "gemini-3.6-flash",
  "messages": [
    {
      "role": "user",
      "content": [
        {"type": "text", "text": "Which PSU bay is empty?"},
        {
          "type": "image_url",
          "image_url": {"url": "https://example.com/rack-rear.jpg"}
        }
      ]
    }
  ]
}
  • Data URIsdata:image/png;base64,iVBORw0KGgo… in the same url field.
  • Limits — 20 MB per image, 8 images per message; anything larger is rejected at the gateway.
  • Billing — image tokens land in prompt_tokens at the model's input rate.
DOC 02.5

Routing tiers

Every catalog entry sits in a tier: frontier, balanced, or efficient. Naming an efficient model is the direct route; sending X-IDC-Route-Tier additionally caps what the router may fall back to, so a failover can never quietly upgrade you into a more expensive pool.

efficient-route.sh Shell
curl https://api.idclinktech.com/v1/chat/completions \
  -H "Authorization: Bearer $IDCLINKTECH_API_KEY" \
  -H "Content-Type: application/json" \
  -H "X-IDC-Route-Tier: efficient" \
  -d '{
    "model": "deepseek-v4-flash",
    "messages": [{"role": "user", "content": "Classify this ticket: disk SMART warning."}]
  }'

Tier caps are enforced at dispatch. If no healthy pool fits the cap, the call fails with 503 rather than overspending.

SEC.03 — OPERATIONS

DOC 03.1

Response headers

Every response carries the route it took and the rate it was billed at, so cost attribution is a log field rather than a monthly reconciliation exercise.

Response header Description
X-IDC-Request-Id Stable per-request ID. Quote it in any support thread.
X-IDC-Route Resolved route as provider/region/pool.
X-IDC-Rate-In The contracted input-token rate applied to this call.
X-IDC-Rate-Out The contracted output-token rate applied to this call.
X-IDC-Provider-Latency Upstream time to last token in ms, excluding gateway overhead.
X-IDC-Failover true when the first-choice pool was skipped.
response-headers.txt HTTP
HTTP/1.1 200 OK
Content-Type: application/json
X-IDC-Request-Id: req_01JQ8ZT4M6
X-IDC-Route: anthropic/us-west/pool-c
X-IDC-Rate-In: <contracted-rate>
X-IDC-Rate-Out: <contracted-rate>
X-IDC-Provider-Latency: 1184
X-IDC-Failover: false

Traces are exported to your own sink — a signed webhook, newline-delimited JSON on a prefix you own, or OTLP to a collector you specify. There is no dashboard you are required to live in.

DOC 03.2

Errors & retries

Standard HTTP status codes with a typed body. 429 and 5xx carry Retry-After; honor it and back off exponentially. Upstream failovers happen below your client and never consume your retry budget.

Status Type Cause
400 invalid_request Validation failed at the gateway; no upstream was touched.
401 invalid_api_key Missing, malformed, or revoked key.
402 payment_required Trial credit or prepaid balance exhausted.
404 model_not_found Unknown API ID, or an alias window that has closed.
429 rate_limit_exceeded Project ceiling hit. Retry after the header value.
503 upstream_unavailable Every healthy pool for that model is saturated. Rare.
error.json JSON
{
  "error": {
    "type": "rate_limit_exceeded",
    "message": "Project token budget exhausted for the current minute.",
    "code": 429,
    "request_id": "req_01JQ8ZT4M6"
  }
}
DOC 03.3

Rate limits

Limits are per project and counted on a rolling minute. Ceilings below are defaults; committed traffic gets reserved capacity that you rebalance between projects from the dashboard or the management API.

Plan Requests / min Tokens / min Concurrent streams
Developer 10,000 2,000,000 64
Scale 60,000 20,000,000 512
Enterprise Reserved Reserved Negotiated

Crossing a ceiling returns 429 with Retry-After. It never queues silently — latency you cannot see is worse than an error you can.

SEC.04 — SDKs

DOC 04.1

Python

Use the official openai package and point base_url at the gateway. Nothing else changes: pip install openai, then swap two lines.

client.py Python
import os

from openai import OpenAI

client = OpenAI(
    base_url="https://api.idclinktech.com/v1",
    api_key=os.environ["IDCLINKTECH_API_KEY"],
)

resp = client.chat.completions.create(
    model="claude-opus-5",
    messages=[{"role": "user", "content": "Say hello."}],
)
print(resp.choices[0].message.content)

The streaming form is shown in DOC 02.2. Provider-native SDKs are not required for any catalog model — one client covers all thirty-six.

DOC 04.2

TypeScript / Node

Same package, same schema: pnpm add openai, then set baseURL. Types come from the package, so tool and vision payloads stay checked at compile time.

client.ts TypeScript
import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "https://api.idclinktech.com/v1",
  apiKey: process.env.IDCLINKTECH_API_KEY,
});

const resp = await client.chat.completions.create({
  model: "claude-sonnet-5",
  messages: [{ role: "user", content: "Say hello." }],
});

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

cURL

For streaming from the shell, add -N so curl does not buffer the event stream.

stream.sh Shell
curl -N https://api.idclinktech.com/v1/chat/completions \
  -H "Authorization: Bearer $IDCLINKTECH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-5.6-terra",
    "messages": [{"role": "user", "content": "Say hello."}],
    "stream": true
  }'

Add -D - to dump the X-IDC-* headers alongside the body while you are wiring things up.

NOTE 04.3 — NOT COVERED HERE

Email sales@idclinktech.com. Technical questions are answered by the on-call engineer, not a ticket queue.