DocsOverview

API Documentation

Everything you need to integrate AIHub into your applications.

OpenAI-compatible API

AIHub is fully compatible with the OpenAI API format. If you already use OpenAI, migration takes less than a minute — just swap the base URL and API key.

Quickstart

Get started with AIHub in just a few lines of code.

1. Get your API key

Go to the API Keys page and create a new key. Keep it secret — never commit it to version control.

sk-aihub-••••••••••••••••••••••••••••••••Keep secret

2. Install the SDK (optional)

Terminal
shell
npm install @aihub/sdk

3. Make your first request

quickstart.ts
typescript
import { AIHub } from '@aihub/sdk';

const client = new AIHub({
  apiKey: process.env.AIHUB_API_KEY,
  defaultHeaders: {
    'HTTP-Referer': '<YOUR_SITE_URL>',   // Optional
    'X-AIHub-Title': '<YOUR_SITE_NAME>', // Optional
  },
});

const completion = await client.chat.send({
  model: 'openai/gpt-4o',
  messages: [
    {
      role: 'user',
      content: 'What is the meaning of life?',
    },
  ],
  stream: false,
});

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

The HTTP-Referer and X-AIHub-Title headers are optional but recommended — they help with analytics and attribution.

Authentication

All API requests must include your API key in the Authorization header using the Bearer scheme.

HTTP Header
shell
Authorization: Bearer <YOUR_API_KEY>

Example with fetch

auth-example.ts
typescript
const response = await fetch('https://api.aihub.io/v1/chat/completions', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer sk-aihub-xxxxxxxxxxxxxxxxxxxx',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    model: 'openai/gpt-4o',
    messages: [{ role: 'user', content: 'Hello!' }],
  }),
});
Never do this

Hardcode your API key in client-side JavaScript or commit it to a public repository.

Best practice

Store your key in an environment variable (AIHUB_API_KEY) and access it server-side only.

Models

AIHub gives you access to hundreds of AI models from leading providers through a single unified endpoint.

Model IDProviderContextInput / 1M tokens
openai/gpt-4oOpenAI128k$5.00
openai/gpt-4o-miniOpenAI128k$0.15
anthropic/claude-3.5-sonnetAnthropic200k$3.00
google/gemini-1.5-proGoogle1M$3.50
meta-llama/llama-3.1-70bMeta128k$0.52
mistralai/mistral-largeMistral AI128k$2.00

Listing Models

list-models.ts
typescript
const response = await fetch('https://api.aihub.io/v1/models', {
  headers: {
    'Authorization': 'Bearer <YOUR_API_KEY>',
  },
});

const { data } = await response.json();
console.log(data); // Array of available models

Selecting a Model

Pass the model ID in the model field of your request. Use the format provider/model-name.

typescript
// Use any model by its ID
const body = {
  model: 'anthropic/claude-3.5-sonnet', // or 'openai/gpt-4o', etc.
  messages: [{ role: 'user', content: 'Hello!' }],
};

Chat Completions

The POST /v1/chat/completions endpoint is the core of the AIHub API.

Basic Request

chat.ts
typescript
const response = await fetch('https://api.aihub.io/v1/chat/completions', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer <YOUR_API_KEY>',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    model: 'openai/gpt-4o',
    messages: [
      { role: 'system', content: 'You are a helpful assistant.' },
      { role: 'user',   content: 'Explain quantum computing in simple terms.' },
    ],
    temperature: 0.7,
    max_tokens: 1024,
  }),
});

const data = await response.json();
console.log(data.choices[0].message.content);

Streaming

Set stream: true to receive tokens as they are generated via Server-Sent Events.

streaming.ts
typescript
const response = await fetch('https://api.aihub.io/v1/chat/completions', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer <YOUR_API_KEY>',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    model: 'openai/gpt-4o',
    messages: [{ role: 'user', content: 'Tell me a short story.' }],
    stream: true,
  }),
});

const reader = response.body!.getReader();
const decoder = new TextDecoder();

while (true) {
  const { done, value } = await reader.read();
  if (done) break;

  const chunk = decoder.decode(value);
  const lines = chunk.split('\n').filter(line => line.startsWith('data: '));

  for (const line of lines) {
    const json = line.replace('data: ', '');
    if (json === '[DONE]') break;
    const parsed = JSON.parse(json);
    process.stdout.write(parsed.choices[0]?.delta?.content || '');
  }
}

Parameters

ParameterTypeRequiredDescription
modelstringrequiredID of the model to use (e.g. openai/gpt-4o).
messagesarrayrequiredArray of message objects with role and content.
streambooleanoptionalIf true, tokens are streamed via SSE.
temperaturenumberoptionalSampling temperature between 0 and 2. Default: 1.
max_tokensintegeroptionalMaximum number of tokens to generate.
top_pnumberoptionalNucleus sampling probability. Default: 1.
stopstring | arrayoptionalStop sequences to end generation.

Multimodal

Text, images, audio, files — all through one API.

Vision — Image Input

Send images alongside text to vision-capable models. Images can be provided as a public URL or as a base64-encoded string.

vision-url.ts
typescript
const response = await fetch('https://api.aihub.io/v1/chat/completions', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer <YOUR_API_KEY>',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    model: 'openai/gpt-4o',
    messages: [
      {
        role: 'user',
        content: [
          {
            type: 'text',
            text: 'What is in this image? Describe it in detail.',
          },
          {
            type: 'image_url',
            image_url: {
              url: 'https://example.com/photo.jpg',
              detail: 'high', // 'low' | 'high' | 'auto'
            },
          },
        ],
      },
    ],
    max_tokens: 1024,
  }),
});

const data = await response.json();
console.log(data.choices[0].message.content);

Image detail levels

low

Faster & cheaper. Resizes image to 512×512. Good for simple tasks.

high

Full resolution analysis. Uses more tokens. Best for detailed inspection.

auto

Model decides based on image size. Recommended default.

Image Generation

Generate images from text prompts using POST /v1/images/generations.

image-generation.ts
typescript
const response = await fetch('https://api.aihub.io/v1/images/generations', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer <YOUR_API_KEY>',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    model: 'openai/dall-e-3',       // or 'stability/stable-diffusion-xl'
    prompt: 'A futuristic city at sunset, cyberpunk style, ultra-detailed, 8k',
    n: 1,                           // number of images (1–4)
    size: '1024x1024',              // '256x256' | '512x512' | '1024x1024' | '1792x1024' | '1024x1792'
    quality: 'hd',                  // 'standard' | 'hd'
    style: 'vivid',                 // 'vivid' | 'natural'
    response_format: 'url',         // 'url' | 'b64_json'
  }),
});

const data = await response.json();
console.log(data.data[0].url); // Image URL
ParameterTypeDescription
modelstringopenai/dall-e-3, openai/dall-e-2, stability/sdxl, etc.
promptstringText description of the image to generate.
nintegerNumber of images to generate (1–4). Default: 1.
sizestring256x256 | 512x512 | 1024x1024 | 1792x1024 | 1024x1792
qualitystringstandard | hd. HD uses more tokens.
stylestringvivid (dramatic) | natural (realistic). DALL-E 3 only.
response_formatstringurl (default) | b64_json

Audio — TTS & Speech-to-Text

Convert text to speech or transcribe audio files to text.

text-to-speech.ts
typescript
// Text-to-Speech
const response = await fetch('https://api.aihub.io/v1/audio/speech', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer <YOUR_API_KEY>',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    model: 'openai/tts-1-hd',
    input: 'Hello! Welcome to AIHub, your unified AI gateway.',
    voice: 'nova',       // 'alloy' | 'echo' | 'fable' | 'onyx' | 'nova' | 'shimmer'
    speed: 1.0,          // 0.25 – 4.0
    response_format: 'mp3', // 'mp3' | 'opus' | 'aac' | 'flac' | 'wav'
  }),
});

// Save audio to file
const buffer = await response.arrayBuffer();
fs.writeFileSync('output.mp3', Buffer.from(buffer));

File & Document Analysis

Send PDFs, spreadsheets, or other documents to models with large context windows for analysis, summarization, or Q&A.

file-analysis.ts
typescript
// Send a PDF or document for analysis
const response = await fetch('https://api.aihub.io/v1/chat/completions', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer <YOUR_API_KEY>',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    model: 'google/gemini-1.5-pro', // Models with large context windows work best
    messages: [
      {
        role: 'user',
        content: [
          { type: 'text', text: 'Summarize the key points of this document.' },
          {
            type: 'file',
            file: {
              url: 'https://example.com/report.pdf',
              mime_type: 'application/pdf',
            },
          },
        ],
      },
    ],
  }),
});

Supported Models by Modality

ModelTextVisionImage GenAudioFiles
openai/gpt-4o
openai/gpt-4o-mini
openai/dall-e-3
openai/tts-1-hd
openai/whisper-1
anthropic/claude-3.5-sonnet
google/gemini-1.5-pro
stability/stable-diffusion-xl

Advanced Parameters

Fine-tune model behavior with precision.

Below is a complete request body showing every available parameter with inline comments.

all-parameters.ts
typescript
const response = await fetch('https://api.aihub.io/v1/chat/completions', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer <YOUR_API_KEY>',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    // ── Core ──────────────────────────────────────────
    model: 'openai/gpt-4o',
    messages: [
      { role: 'system', content: 'You are a concise technical assistant.' },
      { role: 'user',   content: 'Explain REST APIs.' },
    ],

    // ── Sampling ──────────────────────────────────────
    temperature: 0.7,       // 0–2. Controls randomness. Default: 1
    top_p: 0.9,             // 0–1. Nucleus sampling. Default: 1
    top_k: 40,              // Integer. Top-K sampling (model-dependent)
    min_p: 0.05,            // Minimum probability threshold

    // ── Output length ─────────────────────────────────
    max_tokens: 2048,       // Max tokens to generate
    max_completion_tokens: 2048, // Alias for max_tokens (newer models)

    // ── Repetition control ────────────────────────────
    frequency_penalty: 0.3, // -2 to 2. Penalizes repeated tokens
    presence_penalty: 0.2,  // -2 to 2. Penalizes tokens already used
    repetition_penalty: 1.1, // >1 discourages repetition (some models)

    // ── Stop sequences ────────────────────────────────
    stop: ['###', '\n\n---'], // Stop generation at these strings

    // ── Streaming ─────────────────────────────────────
    stream: false,          // true = SSE streaming
    stream_options: {
      include_usage: true,  // Include token usage in final SSE chunk
    },

    // ── Reproducibility ───────────────────────────────
    seed: 42,               // Integer. Same seed = same output (best-effort)

    // ── Logprobs ──────────────────────────────────────
    logprobs: true,         // Return log probabilities
    top_logprobs: 5,        // Number of top tokens to return logprobs for

    // ── Response format ───────────────────────────────
    response_format: {
      type: 'json_object', // 'text' | 'json_object' | 'json_schema'
    },

    // ── Tools / Function calling ──────────────────────
    tools: [
      {
        type: 'function',
        function: {
          name: 'get_weather',
          description: 'Get current weather for a city',
          parameters: {
            type: 'object',
            properties: {
              city: { type: 'string', description: 'City name' },
              unit: { type: 'string', enum: ['celsius', 'fahrenheit'] },
            },
            required: ['city'],
          },
        },
      },
    ],
    tool_choice: 'auto', // 'none' | 'auto' | { type: 'function', function: { name: '...' } }
  }),
});

Temperature

Controls the randomness of the output. Range: 0 – 2. Default: 1. Lower values produce more focused, deterministic responses; higher values produce more creative, varied outputs.

0 – 0.3

Precise

Factual Q&A, code generation, data extraction

0.5 – 0.9

Balanced

Summarization, translation, chat assistants

1.0 – 2.0

Creative

Storytelling, brainstorming, poetry

temperature.ts
typescript
// Low temperature → focused, deterministic
const precise = await fetch('https://api.aihub.io/v1/chat/completions', {
  method: 'POST',
  headers: { 'Authorization': 'Bearer <YOUR_API_KEY>', 'Content-Type': 'application/json' },
  body: JSON.stringify({
    model: 'openai/gpt-4o',
    messages: [{ role: 'user', content: 'What is 2 + 2?' }],
    temperature: 0.1,   // Near 0: very deterministic
  }),
});

// High temperature → creative, varied
const creative = await fetch('https://api.aihub.io/v1/chat/completions', {
  method: 'POST',
  headers: { 'Authorization': 'Bearer <YOUR_API_KEY>', 'Content-Type': 'application/json' },
  body: JSON.stringify({
    model: 'openai/gpt-4o',
    messages: [{ role: 'user', content: 'Write a poem about the ocean.' }],
    temperature: 1.4,   // Higher: more creative and varied
  }),
}

Top P & Top K

ParameterRangeDefaultDescription
top_p0 – 11Nucleus sampling. Only considers tokens whose cumulative probability ≥ top_p. Lower = more focused.
top_k1 – ∞model defaultOnly considers the top K most likely tokens at each step. Lower = more deterministic.
min_p0 – 10Minimum probability threshold relative to the top token. Filters out very unlikely tokens.

Best practice: Adjust either temperature or top_p, not both simultaneously. Combining them can produce unpredictable results.

Repetition Penalties

ParameterRangeDefaultDescription
frequency_penalty-2 to 20Penalizes tokens proportionally to how often they have appeared. Reduces word repetition.
presence_penalty-2 to 20Penalizes tokens that have appeared at all (binary). Encourages topic diversity.
repetition_penalty> 01Multiplicative penalty. Values > 1 discourage repetition; < 1 encourage it. (Some models only)

Streaming (SSE) — Advanced

Full streaming implementation with usage tracking and proper error handling.

streaming-advanced.ts
typescript
const response = await fetch('https://api.aihub.io/v1/chat/completions', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer <YOUR_API_KEY>',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    model: 'openai/gpt-4o',
    messages: [{ role: 'user', content: 'Write a detailed essay on AI.' }],
    stream: true,
    stream_options: { include_usage: true }, // Get token count at the end
  }),
});

const reader = response.body!.getReader();
const decoder = new TextDecoder();
let fullText = '';

while (true) {
  const { done, value } = await reader.read();
  if (done) break;

  const lines = decoder.decode(value).split('\n');
  for (const line of lines) {
    if (!line.startsWith('data: ')) continue;
    const raw = line.slice(6);
    if (raw === '[DONE]') {
      console.log('\n\nStream complete. Full text:', fullText);
      break;
    }
    try {
      const chunk = JSON.parse(raw);
      const delta = chunk.choices?.[0]?.delta;

      if (delta?.content) {
        fullText += delta.content;
        process.stdout.write(delta.content); // Real-time output
      }

      // Final chunk includes usage when stream_options.include_usage = true
      if (chunk.usage) {
        console.log('\nTokens used:', chunk.usage);
      }
    } catch (_) { /* skip malformed lines */ }
  }
}

Tools & Function Calling

Allow the model to call external functions. The model decides when to call a tool and returns structured arguments you can execute.

function-calling.ts
typescript
// Step 1: Send request with tools defined
const response = await fetch('https://api.aihub.io/v1/chat/completions', {
  method: 'POST',
  headers: { 'Authorization': 'Bearer <YOUR_API_KEY>', 'Content-Type': 'application/json' },
  body: JSON.stringify({
    model: 'openai/gpt-4o',
    messages: [{ role: 'user', content: 'What is the weather in Paris right now?' }],
    tools: [{
      type: 'function',
      function: {
        name: 'get_weather',
        description: 'Returns current weather for a given city',
        parameters: {
          type: 'object',
          properties: {
            city: { type: 'string' },
            unit: { type: 'string', enum: ['celsius', 'fahrenheit'] },
          },
          required: ['city'],
        },
      },
    }],
    tool_choice: 'auto',
  }),
});

const data = await response.json();
const toolCall = data.choices[0].message.tool_calls?.[0];

if (toolCall) {
  const args = JSON.parse(toolCall.function.arguments);
  // Step 2: Execute your function
  const weatherResult = await getWeather(args.city, args.unit);

  // Step 3: Send result back to the model
  const followUp = await fetch('https://api.aihub.io/v1/chat/completions', {
    method: 'POST',
    headers: { 'Authorization': 'Bearer <YOUR_API_KEY>', 'Content-Type': 'application/json' },
    body: JSON.stringify({
      model: 'openai/gpt-4o',
      messages: [
        { role: 'user', content: 'What is the weather in Paris right now?' },
        data.choices[0].message,
        {
          role: 'tool',
          tool_call_id: toolCall.id,
          content: JSON.stringify(weatherResult),
        },
      ],
    }),
  });
  const final = await followUp.json();
  console.log(final.choices[0].message.content);
}

System Prompt

The system role message sets the model's behavior, persona, and constraints for the entire conversation.

system-prompt.ts
typescript
const messages = [
  {
    role: 'system',
    content: `You are a senior TypeScript engineer. 
Rules:
- Always use strict TypeScript types, never use 'any'.
- Prefer functional patterns over classes.
- Keep responses concise and include code examples.
- If unsure, say so rather than guessing.`,
  },
  { role: 'user', content: 'How do I type a generic fetch wrapper?' },
];

Seed & Reproducibility

Set seed to an integer to get deterministic outputs. Same seed + same inputs = same output (best-effort, not guaranteed across model updates).

seed.ts
typescript
// Reproducible generation
const body = {
  model: 'openai/gpt-4o',
  messages: [{ role: 'user', content: 'Give me a random number between 1 and 100.' }],
  seed: 42,
  temperature: 0,
};

// The system_fingerprint in the response tells you if the model changed
// { ..., "system_fingerprint": "fp_44709d6fcb" }

Structured Output (JSON Mode)

Force the model to return valid JSON by setting response_format.

json-mode.ts
typescript
const response = await fetch('https://api.aihub.io/v1/chat/completions', {
  method: 'POST',
  headers: { 'Authorization': 'Bearer <YOUR_API_KEY>', 'Content-Type': 'application/json' },
  body: JSON.stringify({
    model: 'openai/gpt-4o',
    messages: [
      {
        role: 'system',
        content: 'You are a data extractor. Always respond with valid JSON.',
      },
      {
        role: 'user',
        content: 'Extract: name, email, and company from: "Hi, I am Alice (alice@acme.com) from Acme Corp."',
      },
    ],
    response_format: { type: 'json_object' },
    temperature: 0,
  }),
});

const data = await response.json();
const extracted = JSON.parse(data.choices[0].message.content);
// { name: "Alice", email: "alice@acme.com", company: "Acme Corp" }

API Response Format

Understand every field returned by the API.

Chat Completion Response

Full annotated response object from POST /v1/chat/completions.

chat-response.json
json
{
  "id": "chatcmpl-abc123xyz",
  "object": "chat.completion",
  "created": 1720000000,
  "model": "openai/gpt-4o",
  "system_fingerprint": "fp_44709d6fcb",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "The meaning of life is a profound philosophical question...",
        "tool_calls": null,       // Populated when the model calls a tool
        "refusal": null           // Non-null if the model refused to answer
      },
      "logprobs": null,           // Populated when logprobs: true
      "finish_reason": "stop"     // See Finish Reasons section
    }
  ],
  "usage": {
    "prompt_tokens": 15,
    "completion_tokens": 87,
    "total_tokens": 102,
    "prompt_tokens_details": {
      "cached_tokens": 0,
      "audio_tokens": 0
    },
    "completion_tokens_details": {
      "reasoning_tokens": 0,
      "audio_tokens": 0,
      "accepted_prediction_tokens": 0,
      "rejected_prediction_tokens": 0
    }
  }
}
FieldTypeDescription
idstringUnique identifier for this completion (chatcmpl-…).
objectstringAlways "chat.completion" for non-streaming responses.
createdintegerUnix timestamp (seconds) when the completion was created.
modelstringThe model that generated the response.
system_fingerprintstringIdentifies the model configuration. Changes when the model is updated.
choicesarrayArray of completion choices. Usually 1 unless n > 1.
choices[].indexintegerIndex of this choice (0-based).
choices[].messageobjectThe generated message with role and content.
choices[].message.rolestringAlways "assistant" in responses.
choices[].message.contentstring | nullThe text content. Null when tool_calls is populated.
choices[].message.tool_callsarray | nullTool calls requested by the model.
choices[].message.refusalstring | nullNon-null if the model refused to answer.
choices[].logprobsobject | nullLog probabilities. Populated when logprobs: true.
choices[].finish_reasonstringWhy generation stopped. See Finish Reasons.
usageobjectToken usage statistics for this request.

Streaming Response Chunks

When stream: true, the API sends Server-Sent Events. Each event is a JSON chunk with a delta instead of a full message.

streaming-chunks.json
json
// Each SSE chunk looks like:
data: {
  "id": "chatcmpl-abc123xyz",
  "object": "chat.completion.chunk",
  "created": 1720000000,
  "model": "openai/gpt-4o",
  "choices": [
    {
      "index": 0,
      "delta": {
        "role": "assistant",   // Only in the first chunk
        "content": "The "     // Incremental token(s)
      },
      "finish_reason": null    // null until the last chunk
    }
  ]
}

// ... more chunks ...

// Last content chunk:
data: {
  "choices": [{ "delta": { "content": "." }, "finish_reason": null }]
}

// Final chunk (finish_reason set):
data: {
  "choices": [{ "delta": {}, "finish_reason": "stop" }],
  "usage": { "prompt_tokens": 15, "completion_tokens": 87, "total_tokens": 102 }
}

// Stream end marker:
data: [DONE]

Usage Object

The usage object tells you exactly how many tokens were consumed — which directly maps to your billing.

usage-object.json
json
{
  "usage": {
    "prompt_tokens": 15,          // Tokens in your input (messages + system)
    "completion_tokens": 87,      // Tokens generated by the model
    "total_tokens": 102,          // prompt_tokens + completion_tokens

    // Detailed breakdown (newer models)
    "prompt_tokens_details": {
      "cached_tokens": 0,         // Tokens served from cache (billed at reduced rate)
      "audio_tokens": 0           // Audio input tokens
    },
    "completion_tokens_details": {
      "reasoning_tokens": 0,      // Internal reasoning tokens (o1 models)
      "audio_tokens": 0,
      "accepted_prediction_tokens": 0,
      "rejected_prediction_tokens": 0
    }
  }
}

Finish Reasons

The finish_reason field tells you why the model stopped generating.

ValueMeaningAction
stopModel finished naturally or hit a stop sequence.Normal — response is complete.
lengthHit the max_tokens limit before finishing.Increase max_tokens or summarize context.
tool_callsModel wants to call one or more tools.Execute the tool and send result back.
content_filterContent was filtered by safety systems.Revise your prompt or use a different model.
nullStreaming: generation is still in progress.Keep reading chunks until finish_reason is set.

Tool Call Response

tool-call-response.json
json
// When the model decides to call a tool, finish_reason = "tool_calls"
{
  "id": "chatcmpl-abc123xyz",
  "object": "chat.completion",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": null,
        "tool_calls": [
          {
            "id": "call_abc123",
            "type": "function",
            "function": {
              "name": "get_weather",
              "arguments": "{\"city\": \"Paris\", \"unit\": \"celsius\"}"
            }
          }
        ]
      },
      "finish_reason": "tool_calls"
    }
  ],
  "usage": { "prompt_tokens": 82, "completion_tokens": 18, "total_tokens": 100 }
}

SDKs & Libraries

Use our official SDK or any OpenAI-compatible library to interact with the AIHub API.

Install the AIHub JavaScript/TypeScript SDK:

Terminal
shell
npm install @aihub/sdk
index.ts
typescript
import { AIHub } from '@aihub/sdk';

const client = new AIHub({
  apiKey: process.env.AIHUB_API_KEY,
  defaultHeaders: {
    'HTTP-Referer': '<YOUR_SITE_URL>',   // Optional
    'X-AIHub-Title': '<YOUR_SITE_NAME>', // Optional
  },
});

const completion = await client.chat.send({
  model: 'openai/gpt-4o',
  messages: [
    {
      role: 'user',
      content: 'What is the meaning of life?',
    },
  ],
  stream: false,
});

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

Error Handling

When an error occurs, the API returns a JSON object with an error field.

Error Response
json
{
  "error": {
    "code": 401,
    "message": "Invalid API key. Please check your credentials.",
    "type": "authentication_error"
  }
}
HTTP StatusError TypeDescription
400bad_requestMalformed request body or missing required fields.
401authentication_errorInvalid or missing API key.
402payment_requiredInsufficient credits. Top up your balance.
403permission_deniedYour key does not have access to this resource.
404not_foundThe requested model or resource does not exist.
429rate_limit_exceededToo many requests. Implement exponential backoff.
500server_errorInternal server error. Retry after a short delay.

Handling errors in code

error-handling.ts
typescript
try {
  const response = await fetch('https://api.aihub.io/v1/chat/completions', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer <YOUR_API_KEY>',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ model: 'openai/gpt-4o', messages: [...] }),
  });

  if (!response.ok) {
    const error = await response.json();
    console.error('API Error:', error.error.message);
    // Handle specific error codes
    if (response.status === 429) {
      console.log('Rate limit hit — please wait before retrying.');
    }
    return;
  }

  const data = await response.json();
  console.log(data.choices[0].message.content);
} catch (err) {
  console.error('Network error:', err);
}

Rate Limits

Rate limits are applied per API key and vary by plan. When exceeded, the API returns a 429 status code.

PlanRequests / minTokens / minConcurrent
Free1040,0002
Starter60200,00010
Pro3001,000,00050
EnterpriseCustomCustomCustom

Exponential backoff recommended

When you receive a 429, wait 1s, then 2s, then 4s before retrying. Most client libraries handle this automatically.

FAQ

Frequently asked questions about the AIHub API.

Talk with Us