API reference
Hull Gateway endpoints, request and response formats, and error codes.
Hull Gateway accepts OpenAI Chat Completions, OpenAI Responses and Anthropic Messages requests. All endpoints below are relative to the base URL:
https://api.withhull.com/api/gatewayA /v1 prefix also works (for example /v1/chat/completions), which helps with SDKs that append it. Every inference request needs a Hull API key in the Authorization: Bearer header. See Authentication.
Endpoints
| Method | Path | Description |
|---|---|---|
POST | /chat/completions | OpenAI Chat Completions format |
POST | /responses | OpenAI Responses format |
POST | /messages | Anthropic Messages format |
POST | /embeddings | Create embeddings |
POST | /audio/transcriptions | Transcribe audio |
GET | /models | List models |
GET | /providers | List providers |
GET | /embedding-models | List embedding models |
GET | /transcription-models | List transcription models |
Chat completions
Create a chat completion in the OpenAI Chat Completions format.
POST /chat/completionsRequest body
type ChatCompletionRequest = {
// Required
model: string // Model ID (e.g., "anthropic/claude-sonnet-5")
messages: Message[] // Array of conversation messages
// Streaming
stream?: boolean // Enable SSE streaming (default: false)
// Generation parameters
max_tokens?: number // Maximum tokens to generate
temperature?: number // Sampling temperature (0-2)
top_p?: number // Nucleus sampling (0-1)
stop?: string | string[] // Stop sequences
frequency_penalty?: number // Frequency penalty (-2 to 2)
presence_penalty?: number // Presence penalty (-2 to 2)
// Tool calling
tools?: Tool[] // Available tools/functions
tool_choice?: ToolChoice // Tool selection strategy
// Structured output
response_format?: ResponseFormat
// Other
seed?: number // Deterministic sampling seed
}Message types
type Message =
| { role: "system"; content: string }
| { role: "user"; content: string | ContentPart[] }
| { role: "assistant"; content: string | null; tool_calls?: ToolCall[] }
| { role: "tool"; content: string; tool_call_id: string }
type ContentPart = { type: "text"; text: string } | { type: "image_url"; image_url: { url: string; detail?: string } }
type Tool = {
type: "function"
function: {
name: string
description?: string
parameters: object // JSON Schema
}
}
type ToolChoice = "none" | "auto" | "required" | { type: "function"; function: { name: string } }Response (non-streaming)
type ChatCompletionResponse = {
id: string
object: "chat.completion"
created: number
model: string
choices: Array<{
index: number
message: {
role: "assistant"
content: string | null
tool_calls?: ToolCall[]
}
finish_reason: "stop" | "length" | "tool_calls" | "content_filter"
}>
usage: {
prompt_tokens: number
completion_tokens: number
total_tokens: number
}
}Response (streaming)
When stream: true, the response is a series of SSE events:
type ChatCompletionChunk = {
id: string
object: "chat.completion.chunk"
created: number
model: string
choices: Array<{
index: number
delta: {
role?: "assistant"
content?: string
tool_calls?: ToolCall[]
}
finish_reason: string | null
}>
// Only in the final chunk
usage?: {
prompt_tokens: number
completion_tokens: number
total_tokens: number
}
}Example request
curl -X POST "https://api.withhull.com/api/gateway/chat/completions" \
-H "Authorization: Bearer $HULL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "anthropic/claude-sonnet-5",
"messages": [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "What is quantum computing?"}
],
"max_tokens": 500,
"temperature": 0.7
}'Example response
{
"id": "gen-abc123",
"object": "chat.completion",
"created": 1739000000,
"model": "anthropic/claude-sonnet-5",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "Quantum computing is a type of computation that uses quantum mechanics..."
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 25,
"completion_tokens": 150,
"total_tokens": 175
}
}Tool calling
Hull Gateway supports function calling, and repairs common tool-call problems before sending a request to the provider.
Request with tools
{
"model": "anthropic/claude-sonnet-5",
"messages": [{ "role": "user", "content": "What's the weather in San Francisco?" }],
"tools": [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get the current weather for a location",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "City name"
}
},
"required": ["location"]
}
}
}
],
"tool_choice": "auto"
}Tool call response
{
"choices": [
{
"message": {
"role": "assistant",
"content": null,
"tool_calls": [
{
"id": "call_abc123",
"type": "function",
"function": {
"name": "get_weather",
"arguments": "{\"location\":\"San Francisco\"}"
}
}
]
},
"finish_reason": "tool_calls"
}
]
}Tool call repair
Hull Gateway fixes these issues automatically:
- Deduplication: Removes duplicate tool calls with the same ID
- Orphan cleanup: Removes tool result messages without matching tool calls
- Missing results: Inserts placeholder results for tool calls without responses
- ID normalization: Normalizes tool call IDs per provider requirements (Anthropic, Mistral)
Responses and Messages
POST /responses accepts the OpenAI Responses request format, and POST /messages accepts the Anthropic Messages format (with messages as an array). Use them with SDKs and tools built for those APIs by pointing the base URL at Hull Gateway and sending your Hull API key as a Bearer token. Model IDs use the same vendor/model-name format as Chat Completions.
FIM completions
Fill-in-the-middle completions for code, used by Hull's autocomplete. This endpoint is outside the gateway base path:
POST https://api.withhull.com/api/fim/completionstype FIMRequest = {
model: string // A supported FIM model, such as "mistralai/codestral-2508"
prompt: string // Code before the cursor
suffix?: string // Code after the cursor
max_tokens: number // Required, at most 1000
temperature?: number
stop?: string[]
stream?: boolean
}curl -X POST "https://api.withhull.com/api/fim/completions" \
-H "Authorization: Bearer $HULL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "mistralai/codestral-2508",
"prompt": "def fibonacci(n):\n if n <= 1:\n return n\n ",
"suffix": "\n\nprint(fibonacci(10))",
"max_tokens": 200
}'FIM supports Mistral Codestral and Inception models. An unsupported model returns HTTP 400. With BYOK, a codestral or mistral key is used for Mistral models and an inception key for Inception models.
List models
GET /modelsReturns the model catalog in an OpenAI-compatible list, with each model's name, context length, pricing and capabilities. The API key is optional; with an organization header, the list reflects the organization's model policy.
{
"data": [
{
"id": "anthropic/claude-sonnet-5",
"name": "Claude Sonnet 5",
"context_length": 200000,
"pricing": {
"prompt": "0.000003",
"completion": "0.000015"
}
}
]
}Values in this example are illustrative. Read real values from the endpoint.
List providers
GET /providersReturns the providers available through Hull Gateway.
Errors
Errors return an HTTP status code and a JSON body. Most bodies include error (a message, or an object with message), and many include an error_type you can match on.
| Status | Meaning |
|---|---|
| 400 | Invalid request, unknown model, or a request that exceeds the model's context window |
| 401 | Missing or invalid API key |
| 402 | No usage available for a paid model (usage_limit_exceeded), or your BYOK provider account is out of funds |
| 403 | Blocked by your organization's model policy |
| 429 | Rate limited |
| 500 | Internal error |
| 503 | Provider temporarily unavailable |
If the model provider itself reports a payment problem on Hull's account, Hull Gateway returns 503 rather than passing the provider's 402 through.
Context length errors
When a request is larger than the model's context window, the error has error_type: "context_length_exceeded" and a message describing the limit. Shorten the conversation or choose a model with a larger context window.