Gateway

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/gateway

A /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

MethodPathDescription
POST/chat/completionsOpenAI Chat Completions format
POST/responsesOpenAI Responses format
POST/messagesAnthropic Messages format
POST/embeddingsCreate embeddings
POST/audio/transcriptionsTranscribe audio
GET/modelsList models
GET/providersList providers
GET/embedding-modelsList embedding models
GET/transcription-modelsList transcription models

Chat completions

Create a chat completion in the OpenAI Chat Completions format.

POST /chat/completions

Request 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/completions
type 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 /models

Returns 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 /providers

Returns 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.

StatusMeaning
400Invalid request, unknown model, or a request that exceeds the model's context window
401Missing or invalid API key
402No usage available for a paid model (usage_limit_exceeded), or your BYOK provider account is out of funds
403Blocked by your organization's model policy
429Rate limited
500Internal error
503Provider 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.

On this page