Home / Docs / Models

Models

List the models a key may use, with their prices, and read the public catalogue without a key.

Use this page to see which models your key can route to and what they cost. You can also read the public catalogue without a key.

List the models your key can use

GET /v1/models lists what this key may route to, in the OpenAI list shape.

curl
curl https://api.massrelay.ai/v1/models -H "Authorization: Bearer $RELAY_KEY"

Each entry carries a massrelay object with these fields:

  • provider — the provider that serves the model.
  • custody — whose key pays the provider for this route (see Bring your own key).
  • family — the model family.
  • prices — per million tokens, where a rate is known.
  • reasoning options — where the catalogue states them.

A model the workspace brought itself says ownedBy: workspace. Aliases are listed after the models and are marked alias; an alias is a name that routes, never a real model.

Note The listing is served for keys on the L1 routing layer. Other key layers get a 501 not_ported answer rather than a guess.

Read the public catalogue

GET /public/models and GET /public/models/{provider}/{model} need no credential. They show the catalogue with the price per million input and output tokens and, on the detail page, latency and uptime. A figure backed by too few calls is null, never a small number. Partner models appear with partner: true.

curl
curl https://api.massrelay.ai/public/models

A catalogue generated from the provider feeds is not available yet; today the catalogue is the one the router ships.

API reference

GET /v1/models

Authentication relay key (bearer)

Example request

curl
curl https://api.massrelay.ai/v1/models \
  -H "Authorization: Bearer $RELAY_KEY"
Python
import os, requests

r = requests.get(
    "https://api.massrelay.ai/v1/models",
    headers={"Authorization": f"Bearer {os.environ['RELAY_KEY']}"},
)
r.raise_for_status()
print(r.json())
TypeScript
const r = await fetch("https://api.massrelay.ai/v1/models", {
  method: "GET",
  headers: { Authorization: `Bearer ${process.env.RELAY_KEY}` },
});
if (!r.ok) throw new Error(`${r.status} ${await r.text()}`);
console.log(await r.json());

Response

FieldTypeDescription
object requiredstringThe kind of object returned, for example chat.completion. Always "list".
data requiredarray of objectThe list of items returned.
data[].id requiredstringA model id, or an alias name (after the models).
data[].object requiredstringThe kind of object returned, for example chat.completion. Always "model".
data[].massrelayobject
data[].massrelay.providerstring
data[].massrelay.custodystring
data[].massrelay.familystring
data[].massrelay.reasoning_optionsobject
data[].massrelay.price_bandsarray
data[].massrelay.ownedBystringPresent only for the workspace's own model. Always "workspace".
data[].massrelay.inputUsdPerMnumber
data[].massrelay.outputUsdPerMnumber
data[].massrelay.aliasbooleanPresent on an alias entry. Always true.
data[].massrelay.startTierobject
data[].massrelay.preferOwnModelsboolean
Example response (shape)
{
  "object": "list",
  "data": [
    {
      "id": "<id>",
      "object": "model",
      "massrelay": {
        "provider": "<provider>",
        "custody": "<custody>",
        "family": "<family>",
        "reasoning_options": "<reasoning_options>",
        "price_bands": [],
        "ownedBy": "workspace",
        "inputUsdPerM": 0,
        "outputUsdPerM": 0,
        "alias": true,
        "startTier": "<startTier>",
        "preferOwnModels": false
      }
    }
  ]
}

Common errors

  • 401 invalid_api_key
  • 403 insufficient_scope
  • 429 over the request rate; read Retry-After

Every error has the same JSON shape; see Errors and Limits.

Full schema (JSON)

Response schema

{
  "description": "Served for an L1 key; any other key layer answers 501 not_ported. The massrelay keys listed are those the handler inserts; a key appears only when its source row exists.",
  "type": "object",
  "required": [
    "object",
    "data"
  ],
  "properties": {
    "object": {
      "const": "list"
    },
    "data": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "id",
          "object"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "A model id, or an alias name (after the models)."
          },
          "object": {
            "const": "model"
          },
          "massrelay": {
            "type": "object",
            "additionalProperties": true,
            "properties": {
              "provider": {
                "type": "string"
              },
              "custody": {
                "type": "string"
              },
              "family": {
                "type": "string"
              },
              "reasoning_options": {},
              "price_bands": {
                "type": "array"
              },
              "ownedBy": {
                "const": "workspace",
                "description": "Present only for the workspace's own model."
              },
              "inputUsdPerM": {
                "type": "number"
              },
              "outputUsdPerM": {
                "type": "number"
              },
              "alias": {
                "const": true,
                "description": "Present on an alias entry."
              },
              "startTier": {},
              "preferOwnModels": {
                "type": "boolean"
              }
            }
          }
        }
      }
    }
  }
}

GET /public/models

Authentication public, no credential

Response

FieldTypeDescription
floor requiredinteger
models requiredarray of object
models[].provider requiredstring
models[].model requiredstringThe model id. In a request it is optional: without it the key's routing chooses.
models[].familystring or null
models[].contextWindowinteger or null
models[].priceInputPerMillionUsdnumber or null
models[].priceOutputPerMillionUsdnumber or null
models[].partner requiredboolean
Example response (shape)
{
  "floor": 0,
  "models": [
    {
      "provider": "<provider>",
      "model": "provider/model-id",
      "family": "<family>",
      "contextWindow": "<contextWindow>",
      "priceInputPerMillionUsd": "<priceInputPerMillionUsd>",
      "priceOutputPerMillionUsd": "<priceOutputPerMillionUsd>",
      "partner": false
    }
  ]
}
Full schema (JSON)

Response schema

{
  "description": "No credential. 404 when the public pages are switched off. `floor` is the k-floor: a figure backed by fewer calls is null, never a small number.",
  "type": "object",
  "required": [
    "floor",
    "models"
  ],
  "properties": {
    "floor": {
      "type": "integer"
    },
    "models": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "provider",
          "model",
          "partner"
        ],
        "properties": {
          "provider": {
            "type": "string"
          },
          "model": {
            "type": "string"
          },
          "family": {
            "type": [
              "string",
              "null"
            ]
          },
          "contextWindow": {
            "type": [
              "integer",
              "null"
            ]
          },
          "priceInputPerMillionUsd": {
            "type": [
              "number",
              "null"
            ]
          },
          "priceOutputPerMillionUsd": {
            "type": [
              "number",
              "null"
            ]
          },
          "partner": {
            "type": "boolean"
          }
        }
      }
    }
  }
}

GET /public/models/{provider}/{model}

Authentication public, no credential

Path parameters

provider requiredstring
model requiredstring

Response

FieldTypeDescription
provider requiredstring
model requiredstringThe model id. In a request it is optional: without it the key's routing chooses.
familystring or null
contextWindowinteger or null
priceInputPerMillionUsdnumber or null
priceOutputPerMillionUsdnumber or null
partner requiredboolean
latencyobject
latency.p50Msnumber or null
latency.p95Msnumber or null
latency.windowstring Always "24h".
uptimeobject
uptime.5mnull
uptime.30mnull
uptime.1dnumber or null
floorinteger
Example response (shape)
{
  "provider": "<provider>",
  "model": "provider/model-id",
  "family": "<family>",
  "contextWindow": "<contextWindow>",
  "priceInputPerMillionUsd": "<priceInputPerMillionUsd>",
  "priceOutputPerMillionUsd": "<priceOutputPerMillionUsd>",
  "partner": false,
  "latency": {
    "p50Ms": "<p50Ms>",
    "p95Ms": "<p95Ms>",
    "window": "24h"
  },
  "uptime": {
    "5m": null,
    "30m": null,
    "1d": "<1d>"
  },
  "floor": 0
}
Full schema (JSON)

Response schema

{
  "description": "404 {error:not_found} for a name the catalogue and the partner listing do not know. Latency and uptime are null below the k-floor.",
  "type": "object",
  "required": [
    "provider",
    "model",
    "partner"
  ],
  "properties": {
    "provider": {
      "type": "string"
    },
    "model": {
      "type": "string"
    },
    "family": {
      "type": [
        "string",
        "null"
      ]
    },
    "contextWindow": {
      "type": [
        "integer",
        "null"
      ]
    },
    "priceInputPerMillionUsd": {
      "type": [
        "number",
        "null"
      ]
    },
    "priceOutputPerMillionUsd": {
      "type": [
        "number",
        "null"
      ]
    },
    "partner": {
      "type": "boolean"
    },
    "latency": {
      "type": "object",
      "properties": {
        "p50Ms": {
          "type": [
            "number",
            "null"
          ]
        },
        "p95Ms": {
          "type": [
            "number",
            "null"
          ]
        },
        "window": {
          "const": "24h"
        }
      }
    },
    "uptime": {
      "type": "object",
      "properties": {
        "5m": {
          "type": "null"
        },
        "30m": {
          "type": "null"
        },
        "1d": {
          "type": [
            "number",
            "null"
          ]
        }
      }
    },
    "floor": {
      "type": "integer"
    }
  }
}