Usage Weighting

POST /chat/completions and POST /embeddings draw down your rate limit allowance at a per-model weight instead of a flat one unit per request. Each model has its own weight, calibrated to what a request against it costs us — so a flagship third-party model consumes far more of your _per_day / _per_week allowance than the same request against a ThreatWinds self-hosted model, and the third-party models differ from each other by tier.

The weight is charged in the usage event that decrements chat_completions_per_day / chat_completions_per_week (or the embeddings_per_* equivalents) — it does not change the limit values themselves. See Usage Limits for the per-tier allowance and Usage Tracking for monitoring consumption.

Note: weights are absolute units per request, not a multiple of a base model. There is no model that costs exactly 1 unit on a weighted endpoint today; a weight of 12 costs twelve units, 230 costs two hundred and thirty, and so on.

Which Endpoints Are Weighted

Endpoint Weighted? Notes
POST /chat/completions Yes Weight follows the requested model
POST /embeddings Yes Weight follows the requested model
POST /chat/count No Always 1 unit — a local tokenizer call, it never reaches a model backend
POST /audio/transcriptions No Limited per minute (audio_transcriptions_per_minute), unaffected by weighting
POST /audio/speech No Limited per minute (audio_speech_per_minute), unaffected by weighting
GET /models, GET /models/:id No Always 1 unit (models_per_minute)

Weight Table

Weights are per model, and a model is only reachable if it is currently served — check /models for the live set.

Self-Hosted Chat

Model Weight
silas-1.6 6
silas-1.7-pro 9
silas-1.6-pro 13

silas-1.6 is the lightest of the self-hosted chat models; the two Pro variants cost more per call because they draw longer reasoning chains.

Self-Hosted Embeddings

Model Weight
qwen3-embedding-8b 5
qwen3-vl-embedding-8b 12

Self-Hosted Audio

whisper-large-v3 (transcription) and kokoro-82m (speech) are priced at 1 for internal consistency, but that weight has no effect today — /audio/transcriptions and /audio/speech are not usage-weighted endpoints (see the table above). They remain governed entirely by audio_transcriptions_per_minute and audio_speech_per_minute.

Third-Party Generation

Each third-party model is weighted individually by what a call against it costs at the provider, so the charge follows the cost. The current catalogue and its weights:

Model Provider Weight
gpt-6-astra OpenAI 1150
claude-fable-5 Claude 1150
claude-fable-5-1 Claude 1150
claude-opus-5 Claude 580
gpt-6.1-sol OpenAI 230
claude-sonnet-5 Claude 230
gemini-3.1-pro Gemini 240
gemini-3.8-flash Gemini 85
gpt-6-luna OpenAI 12
gpt-5-nano (alias) OpenAI 12
gpt-5.4-nano (alias) OpenAI 12
gemini-3.5-flash-lite Gemini 40

gpt-5-nano and gpt-5.4-nano are aliases for gpt-6-luna; they carry its weight. Because the live set changes, treat /models as authoritative and this table as the current pricing, not a fixed menu.

Third-Party Embeddings

Model Weight
gemini-embedding-2 20

A third-party embedding call costs far less than a third-party generation, so it is not priced with it. Being third party is not on its own what sets a model’s weight — each model is priced individually for what a call against it actually costs.

What This Means For Your Allowance

The allowance itself did not change — only what it buys did. Your limit is denominated in units, not requests. How many requests it buys is the limit divided by the weight of the model you call: a weight of 6 costs six units per request, a weight of 230 costs two hundred and thirty, a weight of 1150 costs eleven hundred and fifty. Trading up to a heavier model therefore buys far fewer calls out of the same allowance, and trading down buys more.

Mixed usage draws from one pool. A week spent mostly on silas-1.6 (6) with a handful of gpt-6.1-sol calls (230) consumes the sum of both, each charged at its own weight.

Embeddings are metered separately, against embeddings_per_day / embeddings_per_week — the same arithmetic over a different pool. qwen3-embedding-8b costs five units per call there; gemini-embedding-2 costs twenty.

Your actual limits depend on your tier and are not reproduced in this documentation, because a number written here goes stale the moment the tier changes. Read them live:

curl -X GET \
  'https://apis.threatwinds.com/api/billing/v1/limits/ai-api' \
  -H 'accept: application/json' \
  -H 'Authorization: Bearer <YOUR_BEARER_TOKEN>'

See Usage Limits for the response shape and the -1 / 0 sentinels.

Rules

  • The weight follows the model you requested, not the one that served the request. model_id is set once, immediately after the request is parsed, and is never overwritten by a backend failover — even if ThreatWinds capacity forces your request onto a different pod. If our capacity forces a switch, that’s our cost to absorb, not yours.
  • Only chat completions and embeddings are weighted. Token counting (POST /chat/count) always costs exactly 1 unit — it’s a local tokenizer call and never reaches a model backend, so there’s nothing to weight. Transcription and speech keep their existing per-minute rate limits, untouched by this change.
  • A failed request is never charged. If the response status is 4xx/5xx, nothing is deducted from your allowance. A 503 model_warming_up — common, since inference pods scale to zero when idle — costs nothing; retry after the delay in the Retry-After header.
  • The one exception is a streaming response that fails mid-stream. Once the first SSE byte has been flushed to the client, the HTTP response is already committed to 200 OK; a later upstream failure is delivered as a trailing error event inside the stream (see Streaming Errors) rather than an HTTP error status — and the request is charged, because partial output was already delivered.

Example

{
  "model": "gpt-6-astra",
  "messages": [{"role": "user", "content": "Summarize this alert."}]
}

This request costs 1150 units against chat_completions_per_day and chat_completions_per_week — the weight gpt-6-astra carries, regardless of which upstream account or pod actually processed it.

{
  "model": "silas-1.6",
  "messages": [{"role": "user", "content": "Summarize this alert."}]
}

This request costs 6 units — the weight of the lightest self-hosted chat model.