Group and model availability API
GET /api/v1/channels/available includes cached group and model availability. Use the console API host https://platform.apixly.ai; this read does not submit a model request.
Request and authentication
The anonymous example returns active public groups, excluding exclusive and subscription-only groups. It needs no API key, request body or filter query. Save the response once, then use jq locally.
Optional authentication uses your console login JWT in Authorization: Bearer, not the sk-style API key used for generation. Set CONSOLE_JWT before the optional example. An invalid or expired JWT returns 401 and does not fall back to anonymous access; authenticated results include only groups you may access.
GET /v1/models/list is a separate inference-key endpoint: data[].pricing_options[].success_rate.percent belongs to that exact model and option’s group_id, group_name, priority and pricing. It is not a model-level combined rate; do not average options or substitute a whole-group rate. GET /v1/models/list still uses the inference API key and performs its existing eligibility, catalog and pricing queries. Only attaching cached statistics adds no SQL. Effective USD prices and user/group multipliers are unchanged. /api/v1/channels/available instead uses anonymous access or a console login JWT; these credentials are not interchangeable.
curl --fail-with-body --silent --show-error --max-time 10 \
-D availability.headers \
"https://platform.apixly.ai/api/v1/channels/available" \
-o availability.jsoncurl --fail-with-body --silent --show-error --max-time 10 \
-D availability.headers \
"https://platform.apixly.ai/api/v1/channels/available" \
-H "Authorization: Bearer $CONSOLE_JWT" \
-o availability.jsonFind groups and models
The response is {code: 0, message: success, data: [...]}. Each data entry contains platforms[]; read groups[].success_rate for the whole group, and supported_models[].success_rate_by_group_id["42"] for one exact requested model in group 42. JSON map keys are strings. Replace 42 with a visible groups[].id.
The same group/model can appear in multiple catalog entries. Deduplicate by group id and exact model name; do not add repeated rates or substitute the group total for a model rate. Missing fields or an empty data array do not prove an outage.
jq '.data[]?.platforms[]? | {
platform,
groups: [.groups[]? | {id, name, success_rate}],
models: [.supported_models[]? | {name, success_rate_by_group_id}]
}' availability.jsonWhat success means
The window covers 24 complete UTC hours, excluding the current hour. window_start is inclusive, window_end exclusive; updated_at is snapshot collection time. These are observed customer outcomes, not active probes or a guarantee of the next request.
A request counts once by its final customer outcome after failover. Active client cancellation and final 4xx (including 429) are excluded; final 503 is not excluded. Pending async work is separate. percent = 100 × succeeded / (succeeded + failed); excluded and pending are outside that denominator.
Missing data and hourly bars
- hourly has 24 chronological [S, F, E, P] slots from window_start: succeeded, failed, excluded, pending. Sum each position to the matching summary count. A slot without succeeded or failed has no eligible sample and is gray.
- A missing hourly array cannot be reconstructed by dividing the 24-hour summary. Keep real gaps; never fill them with green bars. percent: null, stale: true or missing statistics mean unknown, not 100% availability; the public pages hide unknown totals. updated_at may be null before the first snapshot is initialized.
- Known rates at least 90% are green, above 0% but below 90% amber, and 0% red. Gray describes missing eligible observations, not a confirmed failure.
Refresh and rate limits
The server refreshes statistics at startup and hourly. Keep the current in-memory view and refresh about once an hour; do not poll every second. Clear it when identity or visibility changes. Responses use Cache-Control: private, no-store and Vary: Authorization: do not put responses in HTTP caches or share authenticated results. Only statistics are cached snapshots; the catalog still checks access and reads catalog data.
429 includes Retry-After in seconds and Cache-Control: no-store. Wait at least that long, add jitter and back off; do not retry in a tight loop. The defaults below apply per gateway process, not to the whole cluster or to generation/billing limits. IP and authenticated-user limits both apply when signed in; shared NAT users share the IP bucket.
| Catalog protection | Current default |
|---|---|
| All catalog requests | 20 requests/s; burst 40 |
| Client IP | 2 requests/s; burst 20 |
| Verified JWT user | 1 request/s; burst 6 |
| Concurrent catalog requests | 8 per process; excess is rejected without queuing |
| Auth + handler context deadline | 2 seconds; cancellation is cooperative |
Illustrative response
This is a partial, illustrative response with invented identifiers and counts, not an observation or a live availability claim. Other catalog and pricing fields are omitted.
{
"code": 0,
"message": "success",
"data": [
{
"platforms": [
{
"platform": "openai",
"groups": [
{
"id": 42,
"name": "Example group",
"success_rate": {
"succeeded": 3,
"failed": 1,
"excluded": 1,
"pending": 1,
"hourly": [
[
0,
0,
0,
0
],
[
0,
0,
0,
0
],
[
0,
0,
0,
0
],
[
0,
0,
0,
0
],
[
0,
0,
0,
0
],
[
0,
0,
0,
0
],
[
0,
0,
0,
0
],
[
0,
0,
0,
0
],
[
0,
0,
0,
0
],
[
0,
0,
0,
0
],
[
0,
0,
0,
0
],
[
0,
0,
0,
0
],
[
0,
0,
0,
0
],
[
0,
0,
0,
0
],
[
0,
0,
0,
0
],
[
0,
0,
0,
0
],
[
0,
0,
0,
0
],
[
0,
0,
0,
0
],
[
0,
0,
0,
0
],
[
0,
0,
0,
0
],
[
0,
0,
0,
0
],
[
0,
0,
0,
0
],
[
1,
0,
0,
0
],
[
2,
1,
1,
1
]
],
"percent": 75,
"window_start": "2026-10-17T00:00:00Z",
"window_end": "2026-10-18T00:00:00Z",
"updated_at": "2026-10-18T00:01:00Z",
"stale": false
}
}
],
"supported_models": [
{
"name": "example-model",
"success_rate_by_group_id": {
"42": {
"succeeded": 3,
"failed": 1,
"excluded": 1,
"pending": 1,
"hourly": [
[
0,
0,
0,
0
],
[
0,
0,
0,
0
],
[
0,
0,
0,
0
],
[
0,
0,
0,
0
],
[
0,
0,
0,
0
],
[
0,
0,
0,
0
],
[
0,
0,
0,
0
],
[
0,
0,
0,
0
],
[
0,
0,
0,
0
],
[
0,
0,
0,
0
],
[
0,
0,
0,
0
],
[
0,
0,
0,
0
],
[
0,
0,
0,
0
],
[
0,
0,
0,
0
],
[
0,
0,
0,
0
],
[
0,
0,
0,
0
],
[
0,
0,
0,
0
],
[
0,
0,
0,
0
],
[
0,
0,
0,
0
],
[
0,
0,
0,
0
],
[
0,
0,
0,
0
],
[
0,
0,
0,
0
],
[
1,
0,
0,
0
],
[
2,
1,
1,
1
]
],
"percent": 75,
"window_start": "2026-10-17T00:00:00Z",
"window_end": "2026-10-18T00:00:00Z",
"updated_at": "2026-10-18T00:01:00Z",
"stale": false
}
}
}
]
}
]
}
]
}Public scope and page links
This API exposes only customer-visible groups, models and aggregate counts. It provides no account health, supplier identity, request trace or private error details. A group filter changes the display and never grants access.
Open /status for group availability or /models for model-by-group rates. On the console, /models?group=42 selects a visible group; replace 42 with an id from your response. Use https://platform.apixly.ai for these console pages and API paths; the app root domain has its own route handling.