Docs/API

Chat completions

Every field we read, every limit we apply, and what comes back.

Checked against the code on

Endpoint
POST https://heyaskr.ai/v1/chat/completions

Create a model response for a conversation. The request is the OpenAI shape. This page is precise about which fields we read, because the rest are dropped without a warning.

Request fields we read

FieldTypeWhat it does
modelstringA chat model id from the catalog. Exact match; there are no suffixes or aliases.
messagesarrayThe conversation. Each item has role (system, user or assistant) and a string content.
max_tokensintegerOutput ceiling, thinking included. Default 4,096, maximum 8,192. Larger values are clamped, not rejected.
streambooleantrue for server-sent events. Streaming.

Everything else is dropped silently: temperature, top_p, tools, tool_choice, response_format, stop, n, seed, plugins. A request that sends them succeeds; they just have no effect. Tool calling and structured output are on the roadmap.

Messages

  • Roles other than system, user and assistant return 400 Unsupported message role.
  • content must be a string. Array content parts (image inputs) are skipped, so a message that is only parts is dropped. Image input is on the roadmap.
  • Only the last 40 messages are sent to the model. Trim on your side if you want control over what is kept.
  • More than 120,000 characters in total returns 400 The conversation is too long.
  • No usable messages returns 400 No usable messages were provided.

Example

curl https://heyaskr.ai/v1/chat/completions \
  -H "Authorization: Bearer $ASKR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-sonnet-5",
    "max_tokens": 300,
    "messages": [
      {"role": "system", "content": "Answer in one sentence."},
      {"role": "user", "content": "Why is the sky blue?"}
    ]
  }'

Response

200
{
  "id": "chatcmpl-9c2b...",
  "object": "chat.completion",
  "created": 1789516800,
  "model": "claude-sonnet-5",
  "choices": [
    {
      "index": 0,
      "message": { "role": "assistant", "content": "Sunlight scatters off air molecules, and blue scatters most." },
      "finish_reason": "stop"
    }
  ],
  "usage": {
    "prompt_tokens": 21,
    "completion_tokens": 14,
    "total_tokens": 35,
    "completion_tokens_details": { "reasoning_tokens": 0 }
  },
  "askr": { "credits_charged": 0.192 }
}
FieldMeaning
choices[0].message.contentThe reply. Always one choice.
choices[0].message.imagesPresent only when the model answered with a picture. Images from chat.
usage.completion_tokens_details.reasoning_tokensOn a thinking model, output tokens you never see. They are billed like any other output token.
askr.credits_chargedWhat the call cost, in credits, to four decimal places. Additive: clients that do not know it ignore it.

How the cost is worked out

Before the call, credits are reserved for the worst case: your estimated input tokens at the model's input rate, plus max_tokens at its output rate. When the model finishes, the reservation is settled to the real cost, using the gateway's own figure for the call. Nothing else is added: there is no platform fee in the first version. Holds and settlement.

Limits

Requests
120 per minute per IP address
Body size
256 KB
Output
max_tokens up to 8,192; default 4,096
Deadline
120 seconds upstream. Past it you get 504 and the reservation is charged, because the model did run. Errors