Skip to main content

Chat Completions

The chat completions endpoint is the core of HPP Router. It is OpenAI-compatible, so request and response shapes match what you already know.

POST https://router.hpp.io/llm/v1/chat/completions

Payment methods​

HPP Router supports prepaid quota, keyed x402 wallet, and a keyless Agent path.

RailHow to enableWhen to use
Quota (default)API key, omit X-Payment-RailPrepaid credit on the API key
Wallet (x402)API key + X-Payment-Rail: walletOn-chain settlement per request
Agent (keyless)No API keyAutonomous agents / hpp-x402 — see x402 Agent

On the wallet or Agent path, paid models typically return 402 until you attach a payment signature. On Agent, free or zero-price models are rejected (keyless_free_model_not_allowed).

See Authentication for key schemes, TypeScript SDK — Wallet for the keyed SDK loop, and x402 Agent (keyless) for no-API-key agents.

Basic request (quota)​

curl -X POST https://router.hpp.io/llm/v1/chat/completions \
-H "apikey: $HPPROUTER_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "openai/gpt-5",
"messages": [
{ "role": "system", "content": "You are a helpful assistant." },
{ "role": "user", "content": "Hello!" }
],
"max_completion_tokens": 100
}'

Basic request (wallet)​

Include X-Payment-Rail: wallet and your API key. The first call for a paid model usually returns 402 with a PAYMENT-REQUIRED challenge — then sign and retry with PAYMENT-SIGNATURE (also accepted as X-PAYMENT).

# 1) First request — expect HTTP 402 for paid models
curl -i -X POST https://router.hpp.io/llm/v1/chat/completions \
-H "apikey: $HPPROUTER_API_KEY" \
-H "X-Payment-Rail: wallet" \
-H "Content-Type: application/json" \
-d '{
"model": "openai/gpt-5",
"messages": [
{ "role": "system", "content": "You are a helpful assistant." },
{ "role": "user", "content": "Hello!" }
],
"max_completion_tokens": 100
}'

# 2) Sign PAYMENT-REQUIRED / JSON body with @x402/core + @x402/evm (upto / Permit2)
# 3) Retry once with the same body + signature header:
curl -X POST https://router.hpp.io/llm/v1/chat/completions \
-H "apikey: $HPPROUTER_API_KEY" \
-H "X-Payment-Rail: wallet" \
-H "PAYMENT-SIGNATURE: <base64-payload>" \
-H "Content-Type: application/json" \
-d '{ ...same body... }'

For production apps and agents, prefer @hpprouter/sdk with paymentRail: 'wallet' and a paymentSigner so the SDK performs the 402 → sign → retry loop.

Request fields​

FieldTypeNotes
modelstringRequired. provider/model (e.g. openai/gpt-5) or hpprouter/auto.
messagesarrayRequired. Chat messages with role and content.
streambooleanStream tokens as Server-Sent Events. See Streaming.
max_tokensintegerMaximum tokens to generate.
max_completion_tokensintegerMaximum completion tokens (newer OpenAI-style field).
temperaturenumberSampling temperature.
stream_optionsobjectStreaming options passed through to the provider.

Additional provider-specific fields are passed through to the upstream model.

Message roles​

role is one of system, user, assistant, or tool. The content is either a string or an array of content parts (used for vision/multimodal).

Response​

{
"id": "chatcmpl-...",
"object": "chat.completion",
"created": 1732700000,
"model": "openai/gpt-5",
"choices": [
{
"index": 0,
"message": { "role": "assistant", "content": "Hi there!" },
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 8,
"completion_tokens": 12,
"total_tokens": 20
}
}

The usage block drives billing. When you use hpprouter/auto, check the X-HPP-Router-Resolved-Model header to see which model was billed — see Smart Routing.

Choosing a model​

  • Pass an explicit provider/model for deterministic routing.
  • Pass hpprouter/auto to let the gateway pick a cost-appropriate model per request.

Errors​

  • 401 — missing or invalid API key; on Agent path, also free-model rejection (keyless_free_model_not_allowed).
  • 402 — wallet / Agent payment challenge (PAYMENT-REQUIRED). Sign and retry once.
  • 429 — rate limit or prepaid quota exhaustion (not the normal wallet challenge).

See Errors and x402 Agent for details.