Start here
List every model a key can run
/v1/modelson https://api.auray.ai/v1Every model a key can run, and what each one would do with a request.
Every model a key can run, and what each one would do with a request. connected means a request dispatches — for anyone while the row's charges is open, and only for a caller a pass or an offer covers while it is covered_only (this platform has stopped charging for the model's product: any other request is refused 503 api_disabled before anything is charged); described means it answers 501 model_not_connected today; undescribed means the address is served but this platform has not read the model's documentation, so a submit answers 404 model_not_described and no field list is published; paused means a submit is refused 503 before anything is charged — the product's switch, the model's own pause or its family's — and the row carries the code and the reason that submit would answer; retired means the address answers 410 model_deprecated, with the successor to use. Our own models, the ones behind the apps (kind: ours), are listed beside the rest of the catalogue. The chat slots (kind: chat, called at /v1/chat) and the embedding model (kind: embedding, called at /openai/v1/embeddings) are rows too, listed when asked for with kind — the default is the addresses, as it always was. A model we have hidden is in no row and no count.
Filter with status, kind, category, operation (what an address can be asked to do, as each row's operations names it), endpoint_id (either spelling of an id) and q (a case-folded substring over slug, address and category). Page with limit and cursor; expand=openapi embeds each row's contract and forces a page of at most 25; include=input adds the field list. total, described, connected, paused, chat and embedding count the whole catalogue and never move with a filter; filtered is the filtered set before paging.
#Authentication
Authorization: Bearer auray_sk_… — Any key. The read bucket paces it.
#Request
#Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
status | string | no | Return only models in this state. One of "connected", "described", "undescribed", "paused", "retired". |
kind | string | no | Return only models of these kinds, as one of the four or a comma-separated list of them: ours the models behind the apps, resold the rest of the catalogue, chat a chat slot, embedding the embedding model. Left out, the listing is the addresses (ours,resold), as it always was; kind=ours,resold,chat,embedding lists every model. Anything else is refused 400 invalid_kind. |
category | string | no | Return only models filed under this task, e.g. text-to-image. The vocabulary is derived from the models that exist rather than declared, so a refusal carries the full list in categories. |
operation | string | no | Return only the addresses whose capability offers this operation — one id of the vocabulary every model's capability is written in, e.g. t2v (text to video), first-frame, talking-photo, lip-sync or story. Each row's operations lists what it is offered for. A chat slot and the embedding model are no catalogue row and match none. Anything else — a misspelt id, an empty value, a comma-separated list — is refused 400 invalid_operation, which carries the whole vocabulary in operations. |
address | string | no | Only the model at this address — the string a job prints as model and a submit is posted to. The same filter as endpoint_id, under the name the rest of the API uses; it wins when both are sent. |
endpoint_id | string | no | Return only the model with this address (bria/fibo-edit/blend, with or without a leading slash) or this slug (bria-fibo-edit-blend). An address nobody serves returns an empty list rather than a 404 — it is a filter. |
include | string | no | Add each model's field list. Off by default: across the catalogue it is tens of thousands of characters. One of "input". |
expand | string | no | Embed each row's full OpenAPI 3.1 contract, the same document GET /models/{address}/openapi.json serves. The documents average 22 kB, so this sets limit to 10 by default and caps it at 25. One of "openapi". |
limit | integer | no | How many models to return. Omit it and the whole catalogue comes back in one response, which is what this endpoint has always done — paging is opt-in so that callers written before it existed keep getting a complete list. 1 to 1000. |
cursor | string | no | Resume after this id. Pass back the next_cursor of the previous page and stop when it is null. It is a position in the sorted list, not a reference, so a page still resolves when the model it was cut at has since been withdrawn. |
q | string | no | A case-folded substring matched against the slug, the address and the category. |
#Example request
curl https://api.auray.ai/v1/models \
-H "Authorization: Bearer $AURAY_API_KEY"import { createClient } from "@auray/client";
const auray = createClient(); // reads AURAY_API_KEY
const page = await auray.platform.models.list({ limit: 20 });
console.dir(page, { depth: null });from auray_client import Client
auray = Client() # reads AURAY_API_KEY
page = auray.platform.models.list(limit=20)
print(page){
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "search_models",
"arguments": {
"limit": 20
}
}
}const res = await fetch("https://api.auray.ai/v1/models", {
method: "GET",
headers: { Authorization: `Bearer ${process.env.AURAY_API_KEY}` },
});
console.log(await res.json());import os, requests
r = requests.get(
"https://api.auray.ai/v1/models",
headers={"Authorization": f"Bearer {os.environ['AURAY_API_KEY']}"},
)
r.raise_for_status()
print(r.json())package main
import (
"fmt"
"io"
"net/http"
"os"
)
func main() {
req, err := http.NewRequest("GET", "https://api.auray.ai/v1/models", nil)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("AURAY_API_KEY"))
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(res.Status, string(out))
}<?php
$ch = curl_init("https://api.auray.ai/v1/models");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer " . getenv("AURAY_API_KEY"),
],
]);
$response = curl_exec($ch);
echo curl_getinfo($ch, CURLINFO_HTTP_CODE), " ", $response, PHP_EOL;require "net/http"
uri = URI("https://api.auray.ai/v1/models")
req = Net::HTTP::Get.new(uri)
req["Authorization"] = "Bearer #{ENV.fetch("AURAY_API_KEY")}"
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }
puts res.code, res.bodyimport java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class Main {
public static void main(String[] args) throws Exception {
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.auray.ai/v1/models"))
.header("Authorization", "Bearer " + System.getenv("AURAY_API_KEY"))
.GET()
.build();
HttpResponse<String> response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.statusCode() + " " + response.body());
}
}using System.Net.Http.Headers;
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", Environment.GetEnvironmentVariable("AURAY_API_KEY"));
using var request = new HttpRequestMessage(HttpMethod.Get, "https://api.auray.ai/v1/models");
using var response = await client.SendAsync(request);
Console.WriteLine($"{(int)response.StatusCode} {await response.Content.ReadAsStringAsync()}");#Responses
#200 OK
The catalogue.
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
object | string | no | — | One of "list". |
data | object[] | no | — | |
data[].id | string | no | — | The catalogue slug to put in model. |
data[].address | string | yes | — | The address: what a job prints as model, what /v1/jobs?model= filters on, and what is posted to. id is the catalogue slug, kept as an alias. A chat slot's is its own name, which is what a chat turn prints as model; POST /v1/chat and /openai/v1 also accept it as auray-ai/<slot>, as every model behind the apps is addressed under auray-ai/. |
data[].kind | string | no | — | Which kind of model it is: one behind the apps (ours), the rest of the catalogue (resold), a chat slot or the embedding model. One of "ours", "resold", "chat", "embedding". |
data[].status | string | no | — | connected dispatches; described is 501 model_not_connected; undescribed is 404 model_not_described; paused is refused 503 with code and reason; retired is 410 model_deprecated with successor. One of "connected", "described", "undescribed", "paused", "retired". |
data[].charges | string | yes | — | Who a run is charged to: anyone (open), or only a caller a pass or an offer covers (covered_only) while we have stopped the product's charges. A covered job runs; any other is refused 503 api_disabled before anything is charged. Said on every row, whatever its status. One of "open", "covered_only". |
data[].code | string | no | — | For paused and retired: the error code a submit would answer, e.g. model_disabled, api_disabled, model_deprecated. |
data[].reason | string | no | — | For paused and retired: our note for it, or null when there is none — code is then the whole answer. May be null. |
data[].successor | string | no | — | For retired: the address to use instead, when one is named. May be null. |
data[].provider | string | no | — | Which adapter would run it. Null when none can. May be null. |
data[].base_url | string | no | — | The host endpoint is called on: the execution host for an address, this API for a chat slot or the embedding model. |
data[].endpoint | string | no | — | The address to POST to on the execution host, with a leading slash — /auray-ai/krea-2-turbo/text-to-image. It was the constant /external until every model got an address of its own. |
data[].category | string | no | — | What the model does, e.g. image-to-video. unknown for a model nothing has filed yet. |
data[].modality | string | no | — | On an address: what it makes. A plan opens catalogue models by this (limits.external.modalities on GET /v1/plans); a model the account's plan leaves out is refused 403 model_not_in_plan before anything is charged — unless a pass the account holds for it covers the job: a catalogue model's pass runs it on any plan (passes on GET /v1/me). A trainer is what it trains. One of "image", "video", "audio", "3d", "text", "other". |
data[].licence | object | no | — | On an address: the licence that limits where it may be served, or null. A model under one is refused 428 region_required until the account declares its country, and 451 region_blocked where the licence excludes it. May be null. |
data[].licence.id | string | no | — | |
data[].licence.name | string | no | — | |
data[].licence.excludes | string | no | — | The territories the licence excludes, in words. |
data[].lifecycle | object | no | — | On an address: how its jobs live — our figures where we set one, the model's compiled ones elsewhere. |
data[].lifecycle.queue | string | no | — | What a full platform does with a job: parks it in the queue, or refuses at once. A queue option sent to a model that refuses is answered 422 queue_not_offered on the queue hosts. One of "waits", "refuses". |
data[].lifecycle.cancel | string | no | — | What a stop does: nothing, because the model cannot be stopped once it starts (none — the charge stands and you stop watching), the job is stopped and refunded in full (full), or it is stopped and what already ran is kept, the rest refunded (keeps_progress). One of "none", "full", "keeps_progress". |
data[].lifecycle.waitable | boolean | no | — | Whether ?wait= and auray.run may hold a request open on it. |
data[].lifecycle.wait_ceiling_seconds | integer | no | — | The longest such a wait, in seconds; 0 when it is not waitable. |
data[].lifecycle.poll_seconds | integer | no | — | How often to come back when polling. |
data[].lifecycle.stall_ceiling_seconds | integer | no | — | Past this age a job nobody has heard from is reaped and refunded — the reap in force, which we may lengthen. A catalogue model's video asked for more seconds than the length this figure is set for is given longer, in proportion to the seconds asked; a model behind the apps (ours) keeps this figure. Each job's own give_up_after_seconds, on its submit and on every read, is the figure to wait by. |
data[].lifecycle.expected_seconds | integer | no | — | How long one usually takes, for an estimate; 0 means not known. |
data[].presentation | object | no | — | On an address: how the desktop presents it — ours where we set it, null for the compiled presentation. |
data[].presentation.featured_order | integer | no | — | Its place in Playground's hero, 1 first, ahead of the models behind the apps. May be null. |
data[].presentation.default_for_app | string | no | — | The app it opens for somebody who never chose a model there; only ever that app's own model. One of "photo", "video", "music", "threed", null. May be null. |
data[].presentation.cover_url | string | no | — | Its cover, on our media origin. May be null. |
data[].chat | object | no | — | Where a catalogue language model also answers as a chat model: present only on the catalogue's language models that are chat models another company runs, and only while those are in force at the chat doors. They are then run by this row's address at POST /chat, POST /chat/conversations and MCP's chat, and a text request to /openai/v1/chat/completions is a chat turn — priced by the token as POST /chat prices one. The row's endpoint stays its queue address, where it runs as a job as before. |
data[].chat.tools | boolean | yes | — | Whether it is offered tools at the chat doors: it completed the tool round trip. |
data[].chat.context_window | integer | yes | — | The model's own context window, in tokens. |
data[].chat.max_output_tokens | integer | yes | — | The most one turn on it writes; a plan's own ceiling can only lower it. |
data[].operations | string[] | no | — | What the address can be asked to do: the operations its one capability record offers it for, in the record's order — what ?operation= filters on. On every address; absent on a chat slot and the embedding model. An operation the model has and is not offered yet is in no list. |
data[].input | object[] | no | — | Only with include=input. |
data[].input[].name | string | no | — | |
data[].input[].type | string | no | — | |
data[].input[].required | boolean | no | — | |
data[].storyboard_input | object[] | no | — | Only with include=input, and only on an address that takes a second request shape — our video, auray-ai/minimax-h3/text-to-video, which takes a storyboard (a body naming segments) beside a clip: that shape's fields, as its document publishes them under components.schemas.Storyboard. |
data[].storyboard_input[].name | string | no | — | |
data[].storyboard_input[].type | string | no | — | |
data[].storyboard_input[].required | boolean | no | — | |
data[].openapi | object | no | — | The model's own OpenAPI 3.1 document. Only with expand=openapi. |
next_cursor | string | no | — | Pass as cursor for the next page, or null when this page reached the end. Always present, including on an unpaged response. May be null. |
filtered | integer | no | — | How many models matched the filters, before paging. The only one of the three counts that moves when a filter does. |
total | integer | no | — | Every address in the catalogue that is listed, whatever its status. The chat slots and the embedding model are counted apart, in chat and embedding. |
described | integer | no | — | How many of total have a published field list. |
connected | integer | no | — | How many of them can run today. |
paused | integer | no | — | How many listed addresses a submit would refuse 503 today. |
chat | integer | no | — | How many chat slots can run today. |
embedding | integer | no | — | How many embedding models can run today. |
#403 Forbidden
#Status codes
| Status | Meaning |
|---|---|
200 | The catalogue. |
403 | Forbidden |
Every refusal names its code, and every code is explained at Errors.