Developer guide

One company key, every tool

Mint a key in settings, then call our models from the OpenAI SDK or from Claude Code and other MCP clients. Usage is billed to your company's credits.

1. Mint a key

Company admins create keys under Profile → API Keys. The raw key is shown once — copy it into your environment, never into source control.

2. Call the REST API

The endpoint is OpenAI-compatible: only the base URL and the key change.

https://api.aiqlick.com/llm/v1

Base URL: https://api.aiqlick.com/llm/v1

# pip install openai
from openai import OpenAI

client = OpenAI(api_key="sk-...", base_url="https://api.aiqlick.com/llm/v1")

response = client.chat.completions.create(
    model="<model-alias>",
    messages=[{"role": "user", "content": "Hello"}],
)
print(response.choices[0].message.content)

Keep the key out of source control — read it from an environment variable in anything you deploy. Replace the model alias with one your key is scoped to.

Use model aliases (aiqlick/chat-default), never provider ids. A key scoped to a subset can only call that subset.

3. Connect Claude Code and MCP apps

Point any Streamable-HTTP MCP client at the same origin plus /mcp. The key authenticates and bills exactly like the REST API.

https://api.aiqlick.com/llm/v1/mcp

Base URL: https://api.aiqlick.com/llm/v1/mcp

# The key stays in your shell env, never in the repo
export AIQLICK_API_KEY="sk-..."

claude mcp add --transport http aiqlick https://api.aiqlick.com/llm/v1/mcp \
  --header "Authorization: Bearer $AIQLICK_API_KEY"

# Verify inside Claude Code: /mcp should list aiqlick with chat + list_models.
# Then ask it to call chat with model "<model-alias>".

Keep the key out of source control — read it from an environment variable in anything you deploy. Replace the model alias with one your key is scoped to.

4. Test it

Probe the handshake, list the tools, then make the first chat call — same key, three curl commands.

5. Billing and rotation

Every call lands in API consumption on the same settings page. Rotation mints a sibling and leaves the old key live — deploy the new one, watch the old key go quiet, then revoke it.

Reference: endpoints

Endpoints across inference, parsing, recruitment data, and usage tracking on the same base URL. Bodies are forwarded as received, so provider-specific fields keep working without a client update.

MethodPathNotes
POST/chat/completionsChat and text, streaming and non-streaming
POST/completionsLegacy completion shape
POST/embeddingsText to vectors
GET/modelsOnly the aliases this key may call
GET/usageReal-time usage metrics and credit expenditure
GET/jobsActive company jobs with requirements and metadata
POST/parse/cvParse resume/CV into structured candidate profile JSON
POST/parse/jdParse job posting into structured job requirements JSON

Key scopes & permissions

Granular permissions control what each key can access. Configure scopes when minting a key in company settings.

Required scopeDescriptionDefault
inference:chatChat completions, legacy completions, and vector embeddingsEnabled by default
inference:parseStructured CV and job description extraction endpointsEnabled by default
usage:readRead-only access to key consumption metrics and token spendEnabled by default
jobs:readRead-only access to company active job postings and requirementsOpt-in only

Model Context Protocol (MCP) tools

When connected via MCP streamable HTTP, the server registers the following tools according to your key's scopes:

ToolRequired scopeDescription
chatinference:chatGenerate completions and answers using allowed model aliases
list_modelsinference:chatList model aliases authorized for the active key
get_usageusage:readFetch real-time usage metrics and credit expenditure for this key
list_jobsjobs:readList company job openings with requirements and metadata
parse_cvinference:parseParse resume or CV text into canonical structured candidate profile JSON
parse_jdinference:parseParse job posting text into canonical structured job posting JSON

Streaming

Set "stream": true and the response arrives chunk by chunk. The server always merges stream_options.include_usage into streaming requests — without the usage block a call cannot be billed, so a stream that ends without one is recorded as a failure and not charged.

Errors

Every failure uses the OpenAI error envelope: {"error": {"message", "type", "code"}}. Match on code, not on words.

StatusTypeCodeMeaning
401authentication_error—Missing, unknown, revoked or expired key. All four look identical on purpose.
402insufficient_quotaINSUFFICIENT_CREDITSCompany credit balance is at or below zero. Top up to resume.
403permission_errorLLM_MODEL_NOT_ALLOWEDModel is outside this key's allowlist. Mint a key scoped to it, or pick another alias.
403permission_errorLLM_SCOPE_DENIEDKey does not have the required scope for this endpoint or tool.
403permission_errorPLAN_LIMIT_EXCEEDEDPOSTPAID enterprise only: an overdue invoice blocks access.
404not_found_error—Unknown route. Check the endpoint table above.
429rate_limit_error—Too many requests. Back off and retry.
503api_errorLLM_GATEWAY_UNAVAILABLEGateway unreachable. Retry with backoff.

Rate limits

600 requests per minute per client IP, plus per-key RPM and TPM limits enforced at the gateway. The IP bucket is shared by customers behind the same egress address, which is why the IP limit sits far above any single-tenant rate.

Client libraries

Thin wrappers over the official OpenAI SDK — same calls, with the base URL and model aliases built in. You never need them; the official SDK works directly.

# pip install aiqlick
from aiqlick import AIQLick, Models

client = AIQLick(api_key="sk-...")  # or set AIQLICK_API_KEY

reply = client.chat.completions.create(
    model=Models.CHAT_DEFAULT,
    messages=[{"role": "user", "content": "hello"}],
)
print(reply.choices[0].message.content)
# npm install @aiqlick/inference openai
import { AIQLick, Models } from "@aiqlick/inference";

const client = new AIQLick({ apiKey: process.env.AIQLICK_API_KEY });

const reply = await client.chat.completions.create({
  model: Models.CHAT_DEFAULT,
  messages: [{ role: "user", content: "hello" }],
});
console.log(reply.choices[0]?.message?.content);

Model aliases

Call aliases, never provider ids — the mapping can change without you changing code. A key scoped to a subset can only call that subset; list_models (REST: GET /models) shows exactly what your key may use.

  • aiqlick/chat-premium
  • aiqlick/chat-default
  • aiqlick/chat-cheap
  • aiqlick/extract-default
  • aiqlick/extract-fast
  • aiqlick/embed-default

Troubleshooting

SymptomFix
Everything returns 401The key is missing, wrong, revoked or expired — the server answers all four identically. Re-copy the key from settings; a key that was already shown once is gone, so mint a new one.
"Not permitted" for a modelThe key is not scoped to that alias. Call list_models to see the allowlist.
Calls suddenly stop with 402Credits ran out. Usage and top-up live on the same settings page as the keys.
A stream carries no usageThe client disconnected early or the usage block went missing. It is recorded as a failed, unbilled call — retry non-streaming to compare.

Ready to find your next opportunity?

Create your free profile, let AI match you to the best jobs, and start applying today — with 9 free AI credits.

Get Started Free
Browse Jobs

No credit card required • Always free • 9 AI credits included

AiQlick Logo

AiQlick helps job seekers find the right opportunities through AI-powered matching, smart CV management, and real-time application tracking.

For Job Seekers

  • Browse Jobs
  • AI Job Matching
  • CV Builder
  • How It Works

Resources

  • Pricing & Credits
  • Features
  • Release Notes
  • For Employers

© 2026 AiQlick. All rights reserved.

Privacy PolicyTerms of ServiceCookie PolicyGDPR