> For the complete documentation index, see [llms.txt](https://docs.maiagent.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.maiagent.ai/api/en/api-reference/ai-gateway.md).

# AI Gateway

AI Gateway provides OpenAI-compatible endpoints, allowing existing OpenAI SDKs or tools to call models through MaiAgent by changing only the URL and API key. These endpoints are available only under `/api/v1/`, and their paths do not end with `/`. Authentication uses `Authorization: Bearer <API Key>` (the key is your MaiAgent API Key, but Gateway endpoints accept only the `Bearer` prefix; using the `Api-Key` prefix returns `401`). MaiAgent must enable AI Gateway for your organization. Administrators configure which models each key can call in API Key management. For full details, see the technical manual: [AI Gateway: OpenAI-compatible API integration](https://docs.maiagent.ai/tech/api-integration/ai-gateway-openai-compatible).

### List available models <a href="#models-retrieve" id="models-retrieve"></a>

GET `/api/v1/models`

{% hint style="info" %}
Returns the model IDs and pricing available to this key. For the ID rules, see [Model IDs](https://docs.maiagent.ai/tech/api-integration/ai-gateway-openai-compatible#model-ids) in the technical manual.
{% endhint %}

#### Code Examples

{% tabs %}
{% tab title="Shell/Bash" %}

```bash
# Example API call (Shell)
curl -X GET "https://api.maiagent.ai/api/v1/models" \
  -H "Authorization: Bearer YOUR_API_KEY"

# Make sure to replace YOUR_API_KEY and verify the request data before running.
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const axios = require('axios');

// Set request headers
const config = {
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY'
  }
};

axios.get("https://api.maiagent.ai/api/v1/models", config)
  .then(response => {
    console.log('Response received successfully:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('Request failed:');
    console.error(error.response?.data || error.message);
  });
```

{% endtab %}

{% tab title="Python" %}

```python
import requests

url = "https://api.maiagent.ai/api/v1/models"
headers = {
    "Authorization": "Bearer YOUR_API_KEY"
}


response = requests.get(url, headers=headers)
try:
    print("Response received successfully:")
    print(response.json())
except Exception as e:
    print("Request failed:", e)
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();

try {
    $response = $client->get("https://api.maiagent.ai/api/v1/models", [
        'headers' => [
            'Authorization' => 'Bearer YOUR_API_KEY'
        ]
    ]);
    
    $data = json_decode($response->getBody(), true);
    echo "Response received successfully:\n";
    print_r($data);
} catch (Exception $e) {
    echo 'Request failed: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### Response

**Status code: 200**

**Response Schema Example**

```typescript
{
  "object"?: string (enum: list) // optional
  "data"?: [ // optional
    {
      "id"?: string // ID to use as the model when calling (optional)
      "object"?: string (enum: model) // optional
      "created"?: integer // Unix seconds (optional)
      "owned_by"?: string // optional
      "name"?: string // optional
      "icon"?: string // optional
      "type"?: string (enum: language) // optional
      "tags"?: [ // optional
        string (enum: tool-use, multimodal, reasoning, prompt-caching, streaming)
      ]
      "pricing"?: { // Platform models use input/output/unit=credits_per_1k_tokens/currency; organization-owned models use traffic_fee_percent/unit=percent_of_total_tokens/currency (optional)
      {
        "input"?: string // optional
        "output"?: string // optional
        "traffic_fee_percent"?: string // optional
        "unit"?: string // optional
        "currency"?: string // optional
      }
      }
      "providers"?: [ // optional
        {
          "slug"?: string // optional
          "name"?: string // optional
          "icon_url"?: string // optional
          "color"?: string // optional
        }
      ]
      "context_window"?: integer // Only present when set on the model (optional)
      "max_tokens"?: integer // Only present when set on the model (optional)
    }
  ]
}
```

**Response Example**

```json
{
  "object": "list",
  "data": [
    {
      "id": "response string",
      "object": "model",
      "created": 456,
      "owned_by": "response string",
      "name": "response string",
      "icon": "response string",
      "type": "language",
      "tags": [
        "tool-use"
      ],
      "pricing": {
        "id": "550e8400-e29b-41d4-a716-446655440000",
        "name": "Response example name",
        "description": "Response example description"
      },
      "providers": [
        {
          "slug": "response string",
          "name": "response string",
          "icon_url": "response string",
          "color": "response string"
        }
      ],
      "context_window": 456,
      "max_tokens": 456
    }
  ]
}
```

***

### Chat completions (supports streaming and tool calls) <a href="#chat-completions-create" id="chat-completions-create"></a>

POST `/api/v1/chat/completions`

{% hint style="info" %}
The request and response formats are the same as OpenAI `chat/completions` (`model`, `messages`, `stream`, `tools`, etc.); fields not listed in the platform schema also follow OpenAI. For parameters and examples, see [Chat completions parameters](https://docs.maiagent.ai/tech/api-integration/ai-gateway-openai-compatible#chat-completions-params) and [Minimal examples](https://docs.maiagent.ai/tech/api-integration/ai-gateway-openai-compatible#minimal-examples) in the technical manual.
{% endhint %}

#### Request

**Request Parameters**

| Field                          | Type                                                        | Required | Description                                                                                     |
| ------------------------------ | ----------------------------------------------------------- | -------- | ----------------------------------------------------------------------------------------------- |
| model                          | string                                                      | Yes      | Model ID, taken from GET /v1/models                                                             |
| messages                       | array\[object]                                              | Yes      |                                                                                                 |
| stream                         | boolean                                                     | No       | Returns text/event-stream when true                                                             |
| stream\_options                | object                                                      | No       |                                                                                                 |
| stream\_options.include\_usage | boolean                                                     | No       |                                                                                                 |
| temperature                    | number                                                      | No       |                                                                                                 |
| max\_tokens                    | integer                                                     | No       |                                                                                                 |
| top\_p                         | number                                                      | No       |                                                                                                 |
| stop                           | object                                                      | No       |                                                                                                 |
| n                              | integer                                                     | No       |                                                                                                 |
| provider                       | object                                                      | No       |                                                                                                 |
| provider.order                 | array\[string]                                              | No       | Specifies the backend provider; currently only the first one is used                            |
| tools                          | array\[object]                                              | No       |                                                                                                 |
| tool\_choice                   | object                                                      | No       |                                                                                                 |
| parallel\_tool\_calls          | boolean                                                     | No       |                                                                                                 |
| response\_format               | object                                                      | No       | type is text, json\_object, or json\_schema; a json\_schema object is required for json\_schema |
| reasoning\_effort              | string (enum: none, minimal, low, medium, high, xhigh, max) | No       |                                                                                                 |

**Request Schema Example**

```typescript
{
  "model": string // Model ID, taken from GET /v1/models
  "messages": [
    {
      "role": string (enum: system, user, assistant, tool)
      "content": object // Text, or an array of OpenAI multimodal content parts
      "tool_calls"?: [ // optional
        {
          "id"?: string // optional
          "type"?: string (enum: function) // optional
          "function"?: { // optional
          {
            "name"?: string // optional
            "arguments"?: string // JSON string (optional)
          }
          }
        }
      ]
      "tool_call_id"?: string // optional
      "name"?: string // optional
    }
  ]
  "stream"?: boolean // Returns text/event-stream when true (optional)
  "stream_options"?: { // optional
  {
    "include_usage"?: boolean // optional
  }
  }
  "temperature"?: number // optional
  "max_tokens"?: integer // optional
  "top_p"?: number // optional
  "stop"?: // May be one of several types (optional)
  string // optional
  "n"?: integer // optional
  "provider"?: { // optional
  {
    "order"?: [ // Specifies the backend provider; currently only the first one is used (optional)
      string
    ]
  }
  }
  "tools"?: [ // optional
    {
      "type": string (enum: function)
      "function": {
      {
        "name": string
        "description"?: string // optional
        "parameters"?: object // JSON Schema (optional)
        "strict"?: boolean // optional
      }
      }
    }
  ]
  "tool_choice"?: // May be one of several types (optional)
  string (enum: auto, none, required) // optional
  "parallel_tool_calls"?: boolean // optional
  "response_format"?: object // type is text, json_object, or json_schema; a json_schema object is required for json_schema (optional)
  "reasoning_effort"?: string (enum: none, minimal, low, medium, high, xhigh, max) // optional
}
```

**Request Example**

```json
{
  "model": "openai/gpt-5.4-mini",
  "messages": [
    {
      "role": "user",
      "content": "Hello, please introduce yourself in one sentence."
    }
  ]
}
```

#### Code Examples

{% tabs %}
{% tab title="Shell/Bash" %}

```bash
# Example API call (Shell)
curl -X POST "https://api.maiagent.ai/api/v1/chat/completions" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openai/gpt-5.4-mini",
    "messages": [
      {
        "role": "user",
        "content": "Hello, please introduce yourself in one sentence."
      }
    ]
  }'

# Make sure to replace YOUR_API_KEY and verify the request data before running.
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const axios = require('axios');

// Set request headers
const config = {
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json'
  }
};

// Request payload
const data = {
    "model": "openai/gpt-5.4-mini",
    "messages": [
      {
        "role": "user",
        "content": "Hello, please introduce yourself in one sentence."
      }
    ]
  };

axios.post("https://api.maiagent.ai/api/v1/chat/completions", data, config)
  .then(response => {
    console.log('Response received successfully:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('Request failed:');
    console.error(error.response?.data || error.message);
  });
```

{% endtab %}

{% tab title="Python" %}

```python
import requests

url = "https://api.maiagent.ai/api/v1/chat/completions"
headers = {
    "Authorization": "Bearer YOUR_API_KEY",
    "Content-Type": "application/json"
}

# Request payload
data = {
    "model": "openai/gpt-5.4-mini",
    "messages": [
        {
            "role": "user",
            "content": "Hello, please introduce yourself in one sentence."
        }
    ]
}

response = requests.post(url, json=data, headers=headers)
try:
    print("Response received successfully:")
    print(response.json())
except Exception as e:
    print("Request failed:", e)
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();

try {
    $response = $client->post("https://api.maiagent.ai/api/v1/chat/completions", [
        'headers' => [
            'Authorization' => 'Bearer YOUR_API_KEY',
            'Content-Type' => 'application/json'
        ],
        'json' => [
            'model' => 'openai/gpt-5.4-mini',
            'messages' => [
                [
                    'role' => 'user',
                    'content' => 'Hello, please introduce yourself in one sentence.'
                ]
            ]
        ]
    ]);
    
    $data = json_decode($response->getBody(), true);
    echo "Response received successfully:\n";
    print_r($data);
} catch (Exception $e) {
    echo 'Request failed: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### Response

**Status code: 200 - Returns a chat.completion object when stream=false; returns SSE when stream=true**

**Response Schema Example**

```typescript
{
  "id"?: string // optional
  "object"?: string (enum: chat.completion) // optional
  "created"?: integer // Unix seconds (optional)
  "model"?: string // optional
  "choices"?: [ // optional
    {
      "index"?: integer // optional
      "message"?: { // optional
      {
        "role"?: string (enum: assistant) // optional
        "content"?: string // optional
        "tool_calls"?: [ // optional
          {
            "id"?: string // optional
            "type"?: string (enum: function) // optional
            "function"?: { // optional
            {
              "name"?: string // optional
              "arguments"?: string // JSON string (optional)
            }
            }
          }
        ]
      }
      }
      "finish_reason"?: string // optional
    }
  ]
  "usage"?: { // optional
  {
    "prompt_tokens"?: integer // optional
    "completion_tokens"?: integer // optional
    "total_tokens"?: integer // optional
  }
  }
}
```

**Response Example**

```json
{
  "id": "response string",
  "object": "chat.completion",
  "created": 456,
  "model": "response string",
  "choices": [
    {
      "index": 456,
      "message": {
        "id": "msg_550e8400e29b41d4a716446655440000",
        "content": "This is the message content of the response",
        "timestamp": "2025-01-01T00:00:00.000Z"
      },
      "finish_reason": "response string"
    }
  ],
  "usage": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "Response example name",
    "description": "Response example description"
  }
}
```

***

### Generate text embeddings <a href="#embeddings-create" id="embeddings-create"></a>

POST `/api/v1/embeddings`

{% hint style="info" %}
The request and response formats are the same as OpenAI `embeddings` (`model`, `input`). For examples, see [Embeddings](https://docs.maiagent.ai/tech/api-integration/ai-gateway-openai-compatible#embeddings) in the technical manual.
{% endhint %}

#### Request

**Request Parameters**

| Field            | Type                         | Required | Description                                         |
| ---------------- | ---------------------------- | -------- | --------------------------------------------------- |
| model            | string                       | Yes      |                                                     |
| input            | object                       | Yes      | A non-empty string or an array of non-empty strings |
| encoding\_format | string (enum: float, base64) | No       |                                                     |
| dimensions       | integer                      | No       |                                                     |
| user             | string                       | No       |                                                     |

**Request Schema Example**

```typescript
{
  "model": string
  "input": // May be one of several types
  string // A non-empty string or an array of non-empty strings
  "encoding_format"?: string (enum: float, base64) // optional
  "dimensions"?: integer // optional
  "user"?: string // optional
}
```

**Request Example**

```json
{
  "model": "text-embedding-3-large",
  "input": "The weather is nice today"
}
```

#### Code Examples

{% tabs %}
{% tab title="Shell/Bash" %}

```bash
# Example API call (Shell)
curl -X POST "https://api.maiagent.ai/api/v1/embeddings" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "text-embedding-3-large",
    "input": "The weather is nice today"
  }'

# Make sure to replace YOUR_API_KEY and verify the request data before running.
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const axios = require('axios');

// Set request headers
const config = {
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json'
  }
};

// Request payload
const data = {
    "model": "text-embedding-3-large",
    "input": "The weather is nice today"
  };

axios.post("https://api.maiagent.ai/api/v1/embeddings", data, config)
  .then(response => {
    console.log('Response received successfully:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('Request failed:');
    console.error(error.response?.data || error.message);
  });
```

{% endtab %}

{% tab title="Python" %}

```python
import requests

url = "https://api.maiagent.ai/api/v1/embeddings"
headers = {
    "Authorization": "Bearer YOUR_API_KEY",
    "Content-Type": "application/json"
}

# Request payload
data = {
    "model": "text-embedding-3-large",
    "input": "The weather is nice today"
}

response = requests.post(url, json=data, headers=headers)
try:
    print("Response received successfully:")
    print(response.json())
except Exception as e:
    print("Request failed:", e)
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();

try {
    $response = $client->post("https://api.maiagent.ai/api/v1/embeddings", [
        'headers' => [
            'Authorization' => 'Bearer YOUR_API_KEY',
            'Content-Type' => 'application/json'
        ],
        'json' => [
            'model' => 'text-embedding-3-large',
            'input' => 'The weather is nice today'
        ]
    ]);
    
    $data = json_decode($response->getBody(), true);
    echo "Response received successfully:\n";
    print_r($data);
} catch (Exception $e) {
    echo 'Request failed: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### Response

**Status code: 200**

**Response Schema Example**

```typescript
{
  "object"?: string (enum: list) // optional
  "data"?: [ // optional
    {
      "object"?: string (enum: embedding) // optional
      "index"?: integer // optional
      "embedding"?: // May be one of several types (optional)
      array[number] // With encoding_format=float, an array of numbers; with base64, a base64 string of little-endian float32 values (optional)
    }
  ]
  "model"?: string // optional
  "usage"?: { // optional
  {
    "prompt_tokens"?: integer // optional
    "total_tokens"?: integer // optional
  }
  }
}
```

**Response Example**

```json
{
  "object": "list",
  "data": [
    {
      "object": "embedding",
      "index": 456,
      "embedding": [
        456
      ]
    }
  ],
  "model": "response string",
  "usage": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "Response example name",
    "description": "Response example description"
  }
}
```

***


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.maiagent.ai/api/en/api-reference/ai-gateway.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
