Models & catalogue
Read-only endpoints describe everything the marketplace serves: the models, the endpoints behind
each model, the providers, the families, the published benchmarks, the per-endpoint measurement
series, the live status board, and public usage statistics. Only
GET /models/user requires a key, to read the presented account's own
preferences; every other route here serves without one, and unauthenticated requests are
rate-limited per client address (see Errors & rate limits). Every
listed price is the provider's declared price in USD per stated unit, as an exact decimal
string: tokens, characters, images, audio seconds, video seconds and megapixels are different meters. Every measured figure — uptime, the two
timings, throughput, tool-call success — is measured by Heimdallm from its own traffic and is null
until its window holds enough samples; a value a provider did not declare is absent rather than
guessed. The timings are reported separately and never merged: ttft_* is time to first token, which
exists only for streamed requests, and response_* is the whole request through to the last byte.
Throughput is reported over the last day alone, and only over streamed generations long enough to
have an output rate — a buffered response has no generation phase at all, and a two-token answer
measures scheduler jitter rather than the model.
GET /models
GET https://api-staging.heimdallm.com/api/v1/models
Every model with at least one live endpoint, newest first, narrowed by every filter present.
Without limit the whole filtered list comes back in one response. Each model's summary uses one
live endpoint, selected by the lowest prompt-token price a request is charged, then completion-token
price, then endpoint id; unknown token prices sort last. Charged, not listed: an endpoint declaring a
discount is compared at the price a customer pays, so the summary quotes the endpoint that request
costs least on. This selects a representative endpoint for media,
not the lowest price per image or video second. Filters do not change that summary selection.
Compare the endpoints listing for prices in the unit you need. Query parameters:
| Parameter | Type | Meaning |
|---|---|---|
family | string | Only models of one family, by id. |
q | string | Case-insensitive substring match against the model id or its display name. |
supported_parameters | string | Comma-separated parameter names. A model matches when every named one is declared by at least one of its live endpoints — not necessarily the same one. |
input_modalities, output_modalities | string | Comma-separated modalities the model must declare, all of them. |
context | integer | Minimum context length in tokens, against the model's own declared window. |
min_price, max_price | string | Prompt price bounds, USD per million tokens as an exact decimal string. At least one live endpoint's price must fall inside the bound given. |
min_output_price, max_output_price | string | The same bounds on completion price. |
providers | string | Comma-separated provider slugs. At least one live endpoint must belong to one of them. |
model_authors | string | Comma-separated authors, matched against the model's own declared author. |
zdr | boolean | true keeps only models with at least one endpoint the ZDR fold keeps. false filters nothing. |
region | string | Comma-separated country codes or datacenter regions. At least one live endpoint must declare a matching datacenter. |
min_age_days, max_age_days | integer | Age bounds in days since the model's declared release date. |
min_tool_success_rate, max_tool_success_rate | number | Bounds, 0-100, on measured tool_call_success_1d. At least one live endpoint must clear its own sample gate and meet the bound; an endpoint whose figure is null matches neither one. |
sort | string | newest (default), oldest, price-low-to-high, price-high-to-low or context-high-to-low. |
limit, offset | integer | Pagination, applied after every filter above. /models/count is always the unfiltered count. |
category, arch, distillable, min_intelligence_index, max_intelligence_index, min_coding_index, max_coding_index, min_agentic_index, max_agentic_index | string / number | Accepted, never rejected — but this catalogue computes none of them. Naming one answers "data": [] with unsupported_filters listing which ones the request sent, whatever every other filter present would otherwise have matched. |
Every filter combines with AND semantics — a model must satisfy all of them to appear. A filter
this catalogue does not compute is never dropped from that AND: it cannot be evaluated, so it
cannot be satisfied, and the whole request answers empty rather than narrowed by the filters that
could run. GET /models?context=8192&category=roleplay answers { "data": [], "unsupported_filters": ["category"] }, not the models context alone would have kept. unsupported_filters is a
top-level array beside data, present only when the request named one of the filters above this
catalogue does not compute.
{
"data": [
{
"id": "deepseek/deepseek-v4-flash-0731-abliterated",
"canonical_slug": "deepseek/deepseek-v4-flash-0731-abliterated",
"hugging_face_id": "cebeuq/DeepSeek-V4-Flash-0731-abliterated",
"name": "DeepSeek: DeepSeek V4 Flash 0731 (abliterated)",
"created": 1785611388,
"expiration_date": null,
"description": "An abliterated rebuild of DeepSeek V4 Flash 0731...",
"context_length": 131072,
"architecture": {
"modality": "text->text",
"input_modalities": ["text"],
"output_modalities": ["text"],
"tokenizer": "DeepSeek",
"instruct_type": null
},
"hugging_face": {
"id": "cebeuq/DeepSeek-V4-Flash-0731-abliterated",
"read_at": 1789030800,
"availability": "public",
"languages": ["en", "zh"],
"weights_revision": "0e9e39f249a16976918f6564b8830bc894c89659",
"weights_updated_at": 1785697788,
"downloads": 128473,
"likes": 941
},
"pricing": {
"prompt": "0.0000001",
"completion": "0.0000004",
"input_cache_read": "0.000000037",
"overrides": [{ "min_prompt_tokens": 200000, "prompt": "0.0000002" }],
"discount": 0
},
"top_provider": {
"context_length": 131072,
"max_completion_tokens": 32768,
"is_moderated": false
},
"per_request_limits": null,
"supported_parameters": ["max_tokens", "response_format", "seed", "stop", "temperature", "tools"],
"default_parameters": { "temperature": 1, "top_p": 1 },
"family": {
"id": "deepseek/deepseek-v4-flash-0731",
"name": "DeepSeek: DeepSeek V4 Flash 0731"
},
"author": "deepseek",
"tags": ["abliterated", "moe"],
"endpoint_count": 1,
"links": {
"details": "/api/v1/models/deepseek/deepseek-v4-flash-0731-abliterated/endpoints"
},
"supported_voices": null,
"supported_dimensions": null,
"supported_languages": null
}
]
}
| Field | Type | Notes |
|---|---|---|
id | string | author/slug — what you pass as model in a request. |
canonical_slug | string | Equal to id. |
hugging_face_id | string | null | The weights repository on Hugging Face, exact casing; null when the weights are not published. |
hugging_face | object | What the repository hugging_face_id names states about the weights, and the moment that statement was read: id and read_at, plus availability, languages, papers, datasets, weights_revision, weights_updated_at, downloads, likes and evaluations where the repository states them. Present only where a reading of the repository exists. (Heimdallm) |
name | string | Display name, conventionally Author: Model Name. |
created | integer | Release date, Unix seconds. The list is sorted on it, newest first. |
expiration_date | string | null | The date after which the model may be removed, YYYY-MM-DD in UTC, from the deprecation_date its provider document declares. null is a model with no announced end. |
description | string | null | Provider-written description. |
context_length | integer | The model's context window in tokens. |
architecture | object | modality (e.g. text->text, text+image->text), and input_modalities / output_modalities over the declared modality vocabulary. tokenizer is the tokenizer family the summary endpoint declares, null where it declares none. instruct_type is always null: no provider declaration carries a prompt-template name. |
pricing | object | The summary endpoint's prices as a request is charged them, USD per unit as decimal strings, each key naming the unit it meters: prompt and completion per token, input_cache_read per cached prompt token, input_cache_write per cache-write token, input_cache_write_1h per token written to a cache that holds it for an hour where the endpoint prices that lifetime apart from its default one, internal_reasoning per reasoning token, request per request, image per image supplied in the prompt, image_output per output image, image_output_token per output image token, image_megapixel per megapixel of image output, video_second per second of video output, mesh_output per delivered mesh, audio_second per second of audio, audio_output per audio token generated in a reply, character per character synthesized. overrides beside them carries the prices that apply only under a stated condition — see conditional prices. A key is present only where the endpoint declared that price; an undeclared unit is unknown, never 0. A rate can carry more than 24 decimals where a discount multiplied a declaration's own precision; a charge is that rate times the units consumed, floored once at the ledger's 24 decimals. A price per audio input token is never published, because the marketplace holds no price in that unit. discount beside the units is the fraction the quoted endpoint took off its own list to reach these figures, so a list price is price / (1 - discount); it is always present, 0 where nothing is taken off and negative where the endpoint charges above its list. The endpoint quoted is the one a request costs least on, and its context window, tokenizer and controls above come from the same endpoint as these prices. |
top_provider | object | The summary endpoint's context_length and max_completion_tokens; is_moderated is always false. |
per_request_limits | null | Always null. |
supported_parameters | string[] | Union of the request parameters declared by the model's live endpoints, sorted. |
reasoning | object | Optional declared controls from the same endpoint as the model summary price. Every member is optional: supported_efforts lists an explicit domain strongest first; mandatory: false declares an off control; default_effort and default_enabled describe known defaults; supports_max_tokens: true declares a token budget. An absent domain is unknown, never a promise of every API effort. Switches and budgets can be present without effort choices. See reasoning controls. |
default_parameters | object | The sampling the model's author recommends: temperature, top_p, top_k, repetition_penalty. Always present, {} where nothing is known, and a member nobody stated is absent rather than null. |
family | object | { id, name } of the model's family. (Heimdallm) |
author | string | The creator of the weights — never the serving provider. (Heimdallm) |
tags | string[] | Short provider-declared tags. (Heimdallm) |
endpoint_count | integer | Live endpoints currently serving this model. (Heimdallm) |
links.details | string | Path of the endpoints listing for this model. |
supported_voices | string[] | null | The voices a speech model loaded, as the union across its live endpoints. null says the model synthesizes no speech; null on one that does says no live endpoint of it has declared an envelope. What a single endpoint speaks is speech_envelope on the endpoints listing. |
supported_dimensions | integer[] | null | The truncated vector widths a dimensions request on this model may name, read off its cheapest embeddings endpoint. null says the model produces no embeddings; null on one that does says its cheapest endpoint declares no width. (Heimdallm) |
supported_languages | string[] | null | The languages a language request on this model may name, read off its cheapest transcription or speech endpoint. null says the model transcribes or speaks nothing; null on one that does says its cheapest endpoint declares no list. (Heimdallm) |
default_parameters is what a request that leaves a member out is served with. The values are the
model author's own recommendation, read off the generation_config.json of the repository
hugging_face_id names, except where the provider declares the field themselves, which is published
exactly as they declared it. A serving endpoint applies a listed default to a member your request
omits — a member you send, whatever its value, is always what reaches the engine instead. A member
missing from default_parameters is served with whatever the engine runs, since the marketplace has
no recommendation to fill it with.
hugging_face is attribution rather than a marketplace figure. Every member inside it is what the
weights repository stated about itself at the moment read_at names, so you can tell a repository's
own claim from a figure this catalogue computes. The two absences say different things. The member
itself is absent on a model naming no repository and on one whose repository has not been read, so its
presence is the statement that a reading exists and read_at is when it was taken. Inside it, a fact
the repository states no value for is absent rather than null or an empty array, the only meaning
absence can carry within a single reading. A missing languages is a card that states none, never a
card nobody has read.
Reasoning controls
Read the endpoint metadata when choosing a deployment; the model summary describes only its selected
endpoint. supported_efforts is optional and never null. When present, it lists the explicitly
declared values in descending order. Its absence does not imply universal support or prove the
model cannot reason.
mandatory: false means the declaration includes none or a boolean thinking switch. Otherwise
mandatory is omitted: an absent disable declaration does not prove thinking is mandatory.
default_effort appears only for a valid declared default. default_enabled uses a declared boolean
default, or whether the effort default differs from none when there is no independent thinking
switch. A switch without a default does not inherit the effort default. Missing or conflicting
defaults stay absent.
A thinking switch or token budget can exist without an effort dial. supports_max_tokens: true
requires a declared integer or range budget. These fields describe declarations; they do not extend
an adapter's request handling. The generic OpenAI-compatible adapter forwards effort, but not the
nested enabled, budget or exclude fields. See chat forwarding.
Conditional prices
The native media scalar keys (image_output, image_output_token, image_megapixel, and
video_second) appear only for one unambiguous, unconditional output tariff. A conditional or
windowed tariff is omitted from those scalar keys. The image endpoints listing preserves the
structured tariff lines and their conditions; the general projection below cannot express every
media condition. An omitted scalar price is unknown, not free.
A pricing key is what a request carrying no stated condition pays. An endpoint that charges a
different rate under a condition publishes that rate in overrides. Each entry carries a price under
the same key name the object beside it uses. All conditions on an entry must match; among matching
entries, the last price for each key wins. Time-window rates follow default-rate overrides, so an
active window takes precedence even when the provider lists its default rate last. A prompt-length
override within a window carries both conditions:
"overrides": [
// A long prompt, charged at a higher prompt rate above the threshold.
{ "min_prompt_tokens": 200000, "prompt": "0.0000002" },
// A daytime rate on weekdays, as an HHMM UTC window that may wrap midnight.
{ "utc_start": 800, "utc_end": 1630, "utc_days": ["monday", "tuesday"], "completion": "0.0000008" }
]
min_prompt_tokens applies where the prompt is strictly longer than the figure. Only a lower
bound on prompt length and a UTC clock window are published: an endpoint may declare a condition on
another quantity, and a price shown without the condition it depends on would read as one every
request pays, so such a price is left out of overrides entirely rather than published bare. Cache-write
prices for unasked writes or lifetimes other than the default five minutes and the separately named
hour are also omitted from this projection because its keys cannot identify those qualifiers.
The prompt length is read twice, and a request is charged the tier it meets both times. The credit
hold reserves against the prompt estimate, measured over everything the endpoint will tokenize with
tools included, so a request over the threshold is held at the tier's rate rather than at the rate
beside it. The settlement reads the prompt count the endpoint reported with its usage, which is the
count the charge is taken over, so what is billed is the tier the measured prompt met rather than the
one the estimate predicted. A reply that reported no prompt count is charged the entry's own price
and its prompt is recorded unmeasured: a threshold nothing measured is unknown, not met. Prompt
length is the one condition evaluated on the token rails; the image and video rails resolve their
rendering settings when a render is quoted, before it is drawn.
One example per family of filters — every predicate inside one call combines with AND:
# Text search
GET /models?q=deepseek
# Capability, price and privacy together — an endpoint must satisfy all three
GET /models?supported_parameters=tools&max_price=1&zdr=true
# Modality and context floor
GET /models?input_modalities=text,image&context=32768
# Provider, author and datacenter region
GET /models?providers=impcc&model_authors=deepseek®ion=us
# Age and measured reliability
GET /models?min_age_days=30&min_tool_success_rate=90
# Ordering and pagination
GET /models?sort=price-low-to-high&limit=20&offset=20
# A filter this catalogue does not compute — accepted, answers empty, and says so
GET /models?category=roleplay
# { "data": [], "unsupported_filters": ["category"] }
GET /models/count
Returns { "data": { "count": 2 } }, where count is the length of the complete, unfiltered
GET /models list across all modalities. Pagination does not change this total;
a catalogue without served models returns zero.
GET /models/user
GET https://api-staging.heimdallm.com/api/v1/models/user
Requires an API key. The complete unfiltered GET /models list, narrowed by the
presented key's own account preferences. Today that is exactly one stored preference: the
workspace's default zdr routing preference. When
it is true, every model with no live endpoint the ZDR fold keeps is omitted.
A key whose workspace has not set this preference, or has set it false, sees the same list
GET /models serves. Returns 401 without a key.
{ "data": [/* ModelSummary, filtered */] }
GET /models/:author/:slug
GET https://api-staging.heimdallm.com/api/v1/models/deepseek/deepseek-v4-flash-0731-abliterated
Returns { "data": model }, where model is exactly the same object as the matching entry in
GET /models, including its pricing, supported parameters and family. The model must
be active and have a live endpoint belonging to an approved provider. An unknown model or one
without a served endpoint returns 404 with the standard error envelope.
The singular /model/:author/:slug spelling serves the same object and applies the same visibility rules.
SDK retrieval
GET https://api-staging.heimdallm.com/api/v1/models/deepseek%2Fdeepseek-v4-flash-0731-abliterated
The OpenAI Node and Python SDKs interpolate a model id into one path segment rather than two:
models.retrieve("deepseek/deepseek-v4-flash-0731-abliterated") requests
/models/deepseek%2Fdeepseek-v4-flash-0731-abliterated, one percent-encoded segment. This path
resolves through the same catalogue projection and the same visibility rules as
GET /models/:author/:slug — same 404 for an unknown or unserved id — but
answers the bare object those SDKs read directly off the result, not a data envelope:
{
"id": "deepseek/deepseek-v4-flash-0731-abliterated",
"canonical_slug": "deepseek/deepseek-v4-flash-0731-abliterated",
"object": "model",
"created": 1785611388,
"owned_by": "deepseek",
"hugging_face_id": "deepseek-ai/DeepSeek-V4-Flash-0731",
"name": "DeepSeek: DeepSeek V4 Flash 0731 (abliterated)",
"description": "A mixture-of-experts model tuned for speed.",
"context_length": 131072,
"architecture": {
"modality": "text->text",
"input_modalities": ["text"],
"output_modalities": ["text"],
"tokenizer": null,
"instruct_type": null
},
"hugging_face": {
"id": "deepseek-ai/DeepSeek-V4-Flash-0731",
"read_at": 1789030800,
"availability": "public",
"languages": ["en", "zh"],
"papers": ["2606.19348"],
"datasets": ["deepseek-ai/DeepSeek-ProverBench"],
"weights_revision": "0e9e39f249a16976918f6564b8830bc894c89659",
"weights_updated_at": 1785697788
},
"pricing": { "prompt": "0.0000001", "completion": "0.0000004", "discount": 0 },
"top_provider": { "context_length": 131072, "max_completion_tokens": 32768, "is_moderated": false },
"per_request_limits": null,
"supported_parameters": ["temperature", "top_p", "tools"],
"default_parameters": { "temperature": 1, "top_p": 1 },
"family": { "id": "deepseek/deepseek-v4-flash-0731", "name": "DeepSeek: DeepSeek V4 Flash 0731" },
"author": "deepseek",
"tags": ["abliterated", "moe"],
"endpoint_count": 1,
"links": { "details": "/api/v1/models/deepseek/deepseek-v4-flash-0731-abliterated/endpoints" }
}
object is always the literal "model" and owned_by equals author; every other field is the
same as the matching entry in GET /models. GET /models/:author/:slug keeps
answering { "data": model } unchanged — this path exists beside it for a client that cannot spell
two path segments.
GET /models/:author/:slug/endpoints
GET https://api-staging.heimdallm.com/api/v1/models/deepseek/deepseek-v4-flash-0731-abliterated/endpoints
One model with every live endpoint serving it, ordered by provider slug. family is the
{ id, name } pair the GET /models summary carries. benchmarks_note is the
grading disclosure every score in an endpoint's benchmarks is read under. 404 when the id names
no active model.
{
"data": {
"id": "deepseek/deepseek-v4-flash-0731-abliterated",
"name": "DeepSeek: DeepSeek V4 Flash 0731 (abliterated)",
"created": 1786677579,
"description": "...",
"architecture": {
"modality": "text->text",
"input_modalities": ["text"],
"output_modalities": ["text"],
"tokenizer": null,
"instruct_type": null
},
"family": {
"id": "deepseek/deepseek-v4-flash-0731",
"name": "DeepSeek: DeepSeek V4 Flash 0731"
},
"endpoints": [
{
"name": "ImpCC | deepseek/deepseek-v4-flash-0731-abliterated",
"model_id": "deepseek/deepseek-v4-flash-0731-abliterated",
"model_name": "DeepSeek: DeepSeek V4 Flash 0731 (abliterated)",
"provider_name": "ImpCC",
"tag": "impcc/fp4",
"provider_slug": "impcc",
"provider_id": "0b6f3c1e-8d2a-4f7b-9c1d-5e4a3b2c1d0e",
"context_length": 131072,
"max_completion_tokens": 32768,
"max_prompt_tokens": null,
"quantization": "fp4",
"supported_parameters": ["max_tokens", "seed", "stop", "temperature", "tools", "reasoning_effort"],
"refuted_reasoning_efforts": [],
"pricing": {
"prompt": "0.0000001",
"completion": "0.0000004",
"input_cache_write": "0.000000125",
"input_cache_write_1h": "0.0000002",
"discount": 0.1
},
"status": 0,
"uptime_last_1d": 99.8,
"uptime_last_7d": 99.5,
"ttft_last_30m": { "p50": 0.42, "p75": 0.55, "p90": 0.81, "p99": 1.9 },
"ttft_last_1d": { "p50": 0.45, "p75": 0.58, "p90": 0.86, "p99": 2.1 },
"response_last_30m": { "p50": 2.61, "p75": 3.4, "p90": 4.9, "p99": 8.1 },
"response_last_1d": { "p50": 2.74, "p75": 3.6, "p90": 5.2, "p99": 8.6 },
"throughput_last_1d": { "p50": 85.1, "p75": 92.4, "p90": 101.7, "p99": 118.2 },
"throughput_last_1d_samples": 214,
"render_timing": null,
"render_timing_samples": 0,
"render_timing_sizes": 0,
"supports_implicit_caching": false,
"health": "healthy",
"compliance": { "zdr": true, "zdr_status": "approved", "hipaa": null },
"data_policy": { "training": false, "retention_days": 0 },
"datacenters": [{ "country_code": "CA" }],
"tool_call_success_1d": 98.2,
"tool_call_success_1d_samples": 340,
"runaway_rate_1d": 1.4,
"runaway_rate_1d_samples": 620,
"benchmarks": [{ "dataset": "gsm8k", "score": 0.71, "sample_count": 400 }],
"capacity": { "current": 1, "total": 4, "updated_at": "2026-08-16T12:00:15Z" }
}
],
"benchmarks_note": "Scores are sampled and mechanically graded..."
}
}
Per endpoint:
| Field | Type | Notes |
|---|---|---|
name | string | Provider name | model id. |
model_id, model_name | string | The model this endpoint serves. |
provider_name | string | Display name; also what the inference response's provider field carries. |
provider_slug | string | The identifier used in provider preferences. (Heimdallm) |
provider_id | string | The provider's primary key. It holds when the provider's slug is changed, so a client that stores endpoints keyed by provider follows a renamed provider rather than seeing a new one. (Heimdallm) |
tag | string | slug or slug/quantization when a quantization is declared. |
context_length | integer | This endpoint's context window. |
max_completion_tokens | integer | null | Output cap, when declared. |
max_prompt_tokens | integer | null | Prompt cap declared on the endpoint's text input, when stated in tokens; null when not declared. |
quantization | string | null | int2 … fp32, or null when not declared. |
supported_parameters | string[] | Request parameters this endpoint declares support for. |
input_modalities | string[] | This endpoint's inputs, with current semantic qualification observations applied. |
declared_input_modalities | string[] | Inputs the provider's document lists, before qualification. |
capability_qualification | object[] | Current semantic observations per capability, each carrying its latest status and an unexpired decisive verdict. An entry is absent where a capability is untested, where its evidence does not apply, and where a check refuted something the endpoint's own document never declared: a refutation of an undeclared capability withholds nothing and is published as nothing. See reasoning routing for how a refuted reasoning level reads through it. |
reference_inputs | object | The image, video and speech reference inputs this endpoint accepts, each with its formats, roles and item limit. |
render_parameters | object | Full descriptors for every declared image/video render parameter this endpoint states a domain for, keyed by modality then name. |
image_envelope | object | null | The image sizes and formats this endpoint's image_generation route accepts; matched against size on a request. null on an endpoint that generates no images. |
video_envelope | object | null | This endpoint's declared video render limits — frame, max_seconds, frame_step, audio among them. null on an endpoint that generates no video. |
mesh_envelope | object | null | This endpoint's declared face range — max_faces, min_faces and texture. A floor as well as a ceiling, because a decimator handed a target below the surface it can close lands above the target in silence. null on an endpoint that generates no mesh. |
speech_envelope | object | null | What this endpoint speaks: its voices, codecs and speed range, and the only voices a speech request routed to it may name. null on an endpoint that synthesizes no speech. |
reasoning | object | This endpoint's optional declared reasoning controls, with the same fields and absence semantics as the model summary. |
video_generation | object | This endpoint's optional declared video controls, with the same fields and absence semantics as the model summary. |
refuted_reasoning_efforts | string[] | Currently declared levels of reasoning_effort whose latest per-level check refuted the value; empty when none is. The declaration in supported_parameters stands — a refuted level filters the value, not the name — so a request naming a listed level routes past this endpoint while the failed observation matches its serving revision and probe version and is less than 24 hours old. See reasoning routing. (Heimdallm) |
pricing | object | This endpoint's own prices as a request is charged them, the same keys as on GET /models, plus discount: the fraction taken off its list to reach them, so a list price is price / (1 - discount). Always present, 0 where nothing is taken off and negative where the endpoint charges above its list, so no reader has to tell a declared zero from a figure that failed to arrive. The endpoints array is ordered by this charged price, cheapest first. |
status | integer | 0 when health is healthy, -1 otherwise. |
uptime_last_5m, uptime_last_30m | number | null | Percent of counted attempts that succeeded in each window; null below 10 success/error attempts. Other outcomes do not count. |
uptime_last_5m_samples, uptime_last_30m_samples, uptime_last_1d_samples | integer | null | Counted attempts in the named window. 0 is a scanned empty window; null means it has not been computed. |
latency_last_30m | object | null | Alias of ttft_last_30m: p50/p75/p90/p99 time to first token in seconds, not whole-response latency. |
latency_last_30m_samples | integer | null | Streams carrying a first-token observation in the last 30 minutes; the figure is null below 5. |
throughput_last_30m | object | null | Recent completion tokens per second under the daily observation rules and a separate five-stream gate. Percentiles are performance floors: p90 is met or exceeded by 90% of qualifying streams; p99 is lower, not higher. The daily field retains ascending statistical percentiles. |
throughput_last_30m_samples | integer | null | Qualifying streams in the last 30 minutes, including counts below the gate. |
perf_last_30m_by_workload | null | Workload-specific performance is not measured. |
supports_tool_choice | boolean | tools is declared and neither a standing capability refutation nor measured tool fidelity below the routing floor withholds it. An inconclusive check does not clear a standing refutation. |
supports_voice_cloning | boolean | Whether the endpoint declares input_references on its speech output modality, which is a reference clip accepted for a voice. false on every endpoint whose document declares no reference clip. |
uptime_last_1d / _7d | number | null | Success rate (percent) over the window; null below 10 attempts in the window. |
ttft_last_30m / _1d | object | null | Time to first token in seconds: p50/p75/p90/p99 over the window; null below 5 samples. Only a streamed request has a first token, so an endpoint that never streams — an embeddings one — reports null. |
response_last_30m / _1d | object | null | Whole request in seconds, start to last byte, same percentiles and gate. Every completed request contributes, streamed or not; this is the only timing a buffered endpoint can offer. |
throughput_last_1d | object | null | Completion tokens per second during generation over the last day, same percentiles and gate. A generation contributes only if it streamed — a buffered response has no generation phase to measure — and carried at least 16 completion tokens, since on a shorter answer that phase is one gap between tokens, which times the scheduler and not the model. The 30-minute window uses the same observation rules and its own gate; sparse recent traffic leaves that window null. |
throughput_last_1d_samples | integer | null | Streams behind throughput_last_1d, published whether or not the figure is. 0 means the day held no stream long enough to time; a number below 5 beside a null figure means the endpoint is still earning the figure; null means nothing has been measured for this endpoint at all. (Heimdallm) |
render_timing | object | null | What a render costs an endpoint in seconds: fixed_seconds before it draws anything, plus seconds_per_megapixel for the size asked for, so the wait for a size can be worked out before asking. A percentile could not answer that — it reads as whichever size the endpoint served most, and that is the health check's cheapest one. null for everything that renders no images, and until the endpoint has served at least 2 distinct sizes and 5 renders across them. (Heimdallm) |
render_timing_samples / _sizes | integer | null | Renders behind render_timing, and the distinct geometries among them. Two counts because the fit has two gates: render_timing: null beside 40 samples and 1 size says the line is waiting on a second geometry rather than on more traffic. (Heimdallm) |
supports_implicit_caching | boolean | true when the endpoint declares a cache-read price. |
health | string | Judged on the endpoint's newest 20 counted attempts, not on a clock window, so it recovers as fast as new evidence arrives: healthy (≥ 90% of them succeeded), degraded (≥ 60%), down (below 60%), unknown (fewer than 5). A run of consecutive probe failures short-circuits it downwards before the sample turns over — two in a row is degraded, four is down — so an outage shows within minutes. One isolated failure moves nothing: at this scale it is noise, and a request that fails is retried once before it is counted at all. (Heimdallm) |
compliance | object | null | hipaa is the provider's declaration, null when not declared — and so is the whole object when nothing is declared. zdr is the marketplace's verdict on the provider's zero-data-retention declaration, not the declaration itself: true once the claim passed review, null while it is under review (or nothing is declared), false when review denied it or the provider declared false. Wherever a claim stands, zdr_status names the verdict: pending, approved or denied. See Data & privacy. (Heimdallm) |
data_policy | object | null | Declared training (prompts may train models) and retention_days. (Heimdallm) |
datacenters | object[] | null | Where inference runs: [{ "country_code": "CA" }]. (Heimdallm) |
tool_call_success_1d | number | null | Percent of the last day's counted tool requests that produced a tool call; null below 20 of them, meaning too few to measure rather than none answered. Requests the caller abandoned, requests whose stream broke, and requests whose outcome was never recorded are not counted either way. Measured over a whole day because the figure swings hour to hour, and an endpoint measuring under 85% stops receiving tool traffic until it measures above again. (Heimdallm) |
tool_call_success_1d_samples | integer | null | Demanded tool asks behind tool_call_success_1d: asks made under a required or named tool choice, which are the only ones the endpoint owns the outcome of. 0 means no such ask reached it in the day. (Heimdallm) |
runaway_rate_1d | number | null | Percent of the last day's long replies that ended still repeating their own tail. The one percentage here that reads worse the higher it is, uptime and tool_call_success_1d both reading better the higher they are. The denominator is the replies whose text was read — no embedding, transcription or render is in it — carrying at least 256 completion tokens, which is several times the roughly 64 tokens of repeated tail the reading needs before it says anything — below that, whether a reply looped is a fact about how long the answer happened to be rather than about the endpoint; null below 50 of them, meaning too few to measure rather than none looping. A reply that stopped of its own accord and one that ended by calling a tool are outside the numerator, and so is one the engine's own repetition detector ended, which stays in the denominator. The reading is taken as the reply passes, over a bounded window of its tail, and no reply text is retained. (Heimdallm) |
runaway_rate_1d_samples | integer | null | Long replies behind runaway_rate_1d, published whether or not the figure is: replies whose text was read, carrying at least 256 completion tokens. 0 means the day held no reply long enough to judge; a number below 50 beside a null figure means the endpoint is still earning the figure; null means nothing has been measured for this endpoint at all. (Heimdallm) |
benchmarks | object[] | This endpoint's published scores: { dataset, score, sample_count }. Earned per endpoint, not per model — the same weights at a different quantization score differently. Also available alone at GET /models/:author/:slug/benchmarks. (Heimdallm) |
capacity | object | null | The provider's own live report: total concurrent request slots across its replicas, current in use, updated_at when it was heard. null when it never reported or the last report is over a minute old. (Heimdallm) |
Capability evidence applies to its tested serving configuration and probe version for at most 24 hours. An inconclusive check cannot extend an earlier failure's expiry. HTTP refusals and aborted responses remain diagnostic observations: they do not prove that the endpoint lacks the feature. A request can be rejected because of marketplace translation or an unsuitable test.
Chat image-reading checks apply only to chat endpoints. They do not assess image references for video or image generation, embeddings or reranking. An absent qualification result means unverified, not unsupported; listed image inputs remain available unless an applicable check refutes them.
status, health and the uptime figures are what routing orders
endpoints by, and what the status page renders — there is no separate status API.
Reported capacity orders them too: endpoints with free slots are tried before endpoints that
report nothing, and saturated endpoints last.
GET /endpoints/zdr
GET https://api-staging.heimdallm.com/api/v1/endpoints/zdr
Every live endpoint the ZDR fold keeps, across the whole catalogue, in the same object
GET /models/:author/:slug/endpoints publishes per endpoint. An
endpoint appears here only for a ZDR claim whose provider passed marketplace review — a claim on a
provider still under review or one denied review is not here, exactly as provider.zdr and
GET /models?zdr=true read it. No key required.
{ "data": [/* one endpoint object per entry, as above */] }
GET /providers
GET https://api-staging.heimdallm.com/api/v1/providers
Approved providers, ordered by name.
{
"data": [
{
"id": "0b6f3c1e-8d2a-4f7b-9c1d-5e4a3b2c1d0e",
"name": "ImpCC",
"slug": "impcc",
"privacy_policy_url": "https://impcc.example/privacy",
"terms_of_service_url": null,
"status_page_url": null,
"headquarters": "CA",
"datacenters": ["CA"],
"website": "https://impcc.example",
"model_count": 3
}
]
}
| Field | Type | Notes |
|---|---|---|
id | string | The provider's primary key. It holds when slug is changed. |
name, slug | string | Display name and the identifier routing preferences use. |
privacy_policy_url, terms_of_service_url, status_page_url, website | string | null | As declared by the provider. |
headquarters | string | null | Two-letter country code. |
datacenters | string[] | null | Country codes across the provider's live endpoints. |
model_count | integer | Distinct models with at least one live endpoint at this provider. |
GET /families
GET https://api-staging.heimdallm.com/api/v1/families
Model families with at least one live endpoint. (Heimdallm extension — OpenAI-style clients can ignore it.)
{
"data": [
{
"id": "deepseek/deepseek-v4-flash-0731",
"name": "DeepSeek: DeepSeek V4 Flash 0731",
"author": "deepseek",
"hugging_face_id": "deepseek-ai/DeepSeek-V4-Flash-0731",
"models": ["deepseek/deepseek-v4-flash-0731-abliterated"],
"endpoint_count": 1,
"providers": ["impcc"]
}
]
}
| Field | Type | Notes |
|---|---|---|
id, name | string | The family — the base model the variants group under. |
author | string | Creator of the base weights. |
hugging_face_id | string | null | The base model's weights repository, when published. |
models | string[] | Served model ids in the family, sorted. Pass one as model. |
endpoint_count | integer | Live endpoints across the family. |
providers | string[] | Slugs of the providers serving any model in the family. |
GET /families/:author/:slug
GET https://api-staging.heimdallm.com/api/v1/families/deepseek/deepseek-v4-flash-0731
One family with the full summary of every served model in it, the shape
GET /models returns per model, and every live endpoint across those models. Each
endpoint row is exactly the row the endpoints listing publishes
for that endpoint, and it names its own model_id. Rows are ordered by model_id, then
provider_slug, then endpoint id. There is no family-level figure: uptime, timings, prices and scores
stay per endpoint. benchmarks_note is the grading disclosure every score in a row's benchmarks is
read under. A family none of whose models is served answers with empty models and endpoints
arrays rather than a 404, so a family link stays valid between listings.
{
"family": {
"id": "deepseek/deepseek-v4-flash-0731",
"name": "DeepSeek: DeepSeek V4 Flash 0731",
"author": "deepseek",
"hugging_face_id": "deepseek-ai/DeepSeek-V4-Flash-0731"
},
"models": [],
"endpoints": [],
"benchmarks_note": "Scores are sampled and mechanically graded..."
}
GET /models/:author/:slug/benchmarks
GET https://api-staging.heimdallm.com/api/v1/models/deepseek/deepseek-v4-flash-0731-abliterated/benchmarks
The published benchmark scores of one model's endpoints, with the grading disclosure. Scores attach to endpoints, not models — the same weights at a different quantization, or served with different settings, answer the same exam differently — and grading is mechanical, never by another model. The response is cached server-side for about a minute.
{
"data": [
{
"dataset": "gsm8k",
"score": 0.71,
"sample_count": 400,
"grading": "graded mechanically from sampled generations"
}
],
"note": "Scores are sampled and mechanically graded..."
}
| Field | Type | Notes |
|---|---|---|
dataset | string | The exam the score belongs to. |
score | number | Correct fraction, 0 to 1. |
sample_count | integer | How many items earned it. |
grading | string | How the score was produced — the disclosure line, human-readable. |
(The per-endpoint benchmarks array on the endpoints listing
carries the same scores without repeating the note.)
GET /models/:author/:slug/series
GET https://api-staging.heimdallm.com/api/v1/models/deepseek/deepseek-v4-flash-0731-abliterated/series?days=7
Per-endpoint hourly measurement series of one model over the last 7 days — the data behind the
model page's performance and price-history charts. days is 1 to 7, default 7. Hours are UTC
and sparse: an absent hour recorded nothing, so a quiet endpoint is honest about it. Each row
names its model_id, the one row shape the family series shares.
{
"data": {
"model_id": "deepseek/deepseek-v4-flash-0731-abliterated",
"window_days": 7,
"endpoints": [
{
"endpoint_id": "9e8d7c6b-…",
"model_id": "deepseek/deepseek-v4-flash-0731-abliterated",
"provider_slug": "impcc",
"provider_id": "0b6f3c1e-8d2a-4f7b-9c1d-5e4a3b2c1d0e",
"provider_name": "ImpCC",
"quantization": "fp4",
"hours": [
{
"hour": "2026-08-16T12:00:00.000Z",
"ok": 412,
"error": 3,
"ttft_p50": 0.41,
"ttft_p90": 0.79,
"throughput_median": 84.2
}
],
"prices": [
{
"captured_at": "2026-08-10T00:00:00.000Z",
"prompt": "0.0000001",
"completion": "0.0000004",
"cached_prompt": "0.000000037",
"request": null,
"image": null,
"audio": null,
"character": null,
"image_output": null,
"image_output_token": null,
"video_second": null
}
]
}
]
}
}
Per endpoint: hours (ascending) with request outcomes (ok, error) and, where samples
earned them, time-to-first-token percentiles in seconds and median completion tokens per second
— both null in an hour that did not stream enough to measure. prices (ascending) records
changes to the supported scalar prices a request is charged, as exact decimal strings, one member per
unit the change log keeps; a document that changes nothing but its discount moves the series. Native media rates use image_output, image_output_token, or video_second; image
retains the megapixel rate. Conditional, windowed, or ambiguous native tariffs have no scalar
history value. A price reading null on a point was unknown at that moment, not zero; older points
are not converted between units.
GET /models/:author/:slug/activity/series
GET https://api-staging.heimdallm.com/api/v1/models/deepseek/deepseek-v4-flash-0731-abliterated/activity/series?days=30
One model's billed usage per UTC day: requests, prompt and completion token sums, image requests
with the megapixels they drew, and audio seconds. days is 1 to 30, default 30; only days with
traffic appear. Every billed request counts, the platform's own paid probe traffic included, like
any other.
{
"data": {
"model_id": "deepseek/deepseek-v4-flash-0731-abliterated",
"window_days": 30,
"daily": [
{
"date": "2026-08-16",
"requests": 5120,
"prompt_tokens": 161052110,
"completion_tokens": 40881205,
"images": 0,
"megapixels": 0,
"audio_seconds": 0
}
]
}
}
GET /families/:author/:slug/series
GET https://api-staging.heimdallm.com/api/v1/families/deepseek/deepseek-v4-flash-0731/series?days=7
Per-endpoint hourly measurement series across every served model in a family over the last 7
days, the data behind the family page's performance and price-history charts. Each row is the row
the model series publishes for that endpoint and names its model_id. Rows are ordered by
provider_slug then endpoint id, and no bucket is merged across endpoints or models. days is 1
to 7, default 7. Hours are UTC and sparse.
{
"data": {
"family_id": "deepseek/deepseek-v4-flash-0731",
"window_days": 7,
"endpoints": [
{
"endpoint_id": "9e8d7c6b-…",
"model_id": "deepseek/deepseek-v4-flash-0731-abliterated",
"provider_slug": "impcc",
"provider_id": "0b6f3c1e-8d2a-4f7b-9c1d-5e4a3b2c1d0e",
"provider_name": "ImpCC",
"quantization": "fp4",
"hours": [
{
"hour": "2026-08-16T12:00:00.000Z",
"ok": 412,
"error": 3,
"ttft_p50": 0.41,
"ttft_p90": 0.79,
"throughput_median": 84.2
}
],
"prices": [
{
"captured_at": "2026-08-10T00:00:00.000Z",
"prompt": "0.0000001",
"completion": "0.0000004",
"cached_prompt": "0.000000037",
"request": null,
"image": null,
"audio": null,
"character": null,
"image_output": null,
"image_output_token": null,
"video_second": null
}
]
}
]
}
}
GET /families/:author/:slug/activity/series
GET https://api-staging.heimdallm.com/api/v1/families/deepseek/deepseek-v4-flash-0731/activity/series?days=30
A family's billed usage per UTC day, the model route's counts summed over every active model in
the family, a model with no live endpoint included. days is 1 to 30, default 30; only days with
traffic appear. Every billed request counts, the platform's own paid probe traffic included.
{
"data": {
"family_id": "deepseek/deepseek-v4-flash-0731",
"window_days": 30,
"daily": [
{
"date": "2026-08-16",
"requests": 5120,
"prompt_tokens": 161052110,
"completion_tokens": 40881205,
"images": 0,
"megapixels": 0,
"audio_seconds": 0
}
]
}
}
GET /providers/:slug/series
GET https://api-staging.heimdallm.com/api/v1/providers/impcc/series
Hourly request outcomes (ok, error) across one provider's live endpoints over the last 7
days — the data behind the provider page's availability chart. days is 1 to 7, default 7;
hours are UTC and sparse.
GET /status
GET https://api-staging.heimdallm.com/api/v1/status
The live status board — what the status page renders: one row per live endpoint with its health tier, uptime over 1 and 7 days, median response time (last 30 minutes, falling back to the last day), and the time and classification of its last error. Cached server-side for about half a minute. There is no separate status API beyond this one.
{
"data": [
{
"model_id": "deepseek/deepseek-v4-flash-0731-abliterated",
"endpoint_id": "9e8d7c6b-…",
"health": "healthy",
"uptime_1d": 99.8,
"uptime_7d": 99.9,
"response_p50": 2.6,
"response_1d_p50": 2.7,
"last_error": null,
"last_success_at": "2026-08-17T12:00:03Z"
}
]
}
last_error, when present, is { "at", "status_code", "error_type" } — status_code and
error_type are null when the failure did not come from an HTTP exchange.
GET /stats/public
GET https://api-staging.heimdallm.com/api/v1/stats/public
Marketplace-wide usage over the last 30 days. Every billed request counts — the platform's own paid
probe traffic included — and no monetary figure ever appears here. This is what the activity page
renders. The response is cached server-side for about a minute, and — unlike the other endpoints — it is
not wrapped in a data envelope. (Heimdallm extension.)
{
"totals": { "requests": 128441, "tokens": 5013882211, "models_served": 3 },
"window_days": 30,
"daily": [
{
"date": "2026-08-16",
"requests": 5120,
"prompt_tokens": 161052110,
"completion_tokens": 40881205,
"requests_by_api_type": { "chat": 4890, "images": 230 },
"tokens_by_api_type": { "chat": 201933315 }
}
],
"api_types": [
{ "api_type": "chat", "requests": 118200, "tokens": 5013882211 },
{ "api_type": "images", "requests": 10241, "tokens": null }
],
"models": [
{
"model_id": "deepseek/deepseek-v4-flash-0731-abliterated",
"author": "deepseek",
"name": "DeepSeek: DeepSeek V4 Flash 0731 (abliterated)",
"api_type": "chat",
"requests": 91002,
"tokens": 4410882140
}
],
"authors": [{ "author": "deepseek", "requests": 91002, "tokens": 4410882140, "share": 0.88 }]
}
| Field | Type | Notes |
|---|---|---|
totals | object | requests, tokens (prompt + completion, every request that reported either) and distinct models_served in the window. |
window_days | integer | Always 30. |
daily | object[] | Per-UTC-day series, oldest first; only days with traffic appear. requests_by_api_type and tokens_by_api_type split the day, and omit a type with none. |
api_types | object[] | One row per API type served in the window, most requests first. tokens is null for a type none of whose requests reported a token count. |
models | object[] | Top models by requests, at most 50. api_type is the one that served most of the model's requests; tokens is null where no request reported a count. |
authors | object[] | Requests and tokens per model author, most requests first; share is the fraction of the tokens reported across authors, and null for an author with none. |
Requests are the one measure every API type has. A token count exists only where an endpoint reported
one, so an image, video or 3D generation has tokens: null rather than a zero, and nothing about it is
ranked on tokens.
Video soundtrack controls
Video model summaries and endpoint rows may include video_generation.generate_audio.
supported_values lists the declared boolean choices; default is present only where a default is
known. Missing fields do not establish either choice or a universal default. The endpoint’s
video_envelope.audio says whether generated sound is a capability, not whether every returned clip
contains sound. See video generation.