The models endpoint

curl https://guardrails.vulnetix.com/openai/{orgUuid}/v1/models \
  -H "Authorization: Bearer $VULNETIX_API_KEY"

Returns the models at that provider that your organisation’s policy permits. Denied models are absent. In allowlist mode, only allowed models appear.

Why it matters

Many clients do not take a hard-coded model name. They ask the endpoint what is available and present a picker — Claude Desktop does exactly this, and so do most IDE integrations.

Filtering the list means those clients only ever offer models you have approved. A developer cannot select a model your policy would refuse, because they never see it. The 403 becomes unnecessary, because the mistake becomes unreachable.

That is a better control than blocking after the fact, and it costs you nothing.

It never calls the provider

The response is served from the model catalog, which is synced hourly. The gateway does not proxy this request upstream.

Two consequences:

  • No provider key is required. You can list models for a provider before you have stored a key for it. Only an explicit deny blocks the listing.
  • It is fast, and it cannot fail because the provider is down.

The shape depends on the provider’s surface

The list is rendered in the dialect the provider speaks, because a client that asks in one dialect cannot parse the other.

OpenAI-wire
curl https://guardrails.vulnetix.com/openai/{orgUuid}/v1/models \
  -H "Authorization: Bearer $VULNETIX_API_KEY"
{
  "object": "list",
  "data": [
    {
      "id": "gpt-4o-mini",
      "object": "model",
      "created": 1700000000,
      "owned_by": "openai"
    }
  ]
}
Anthropic-wire

Note the base URL has no /v1 — the Anthropic client appends it.

curl https://guardrails.vulnetix.com/anthropic/{orgUuid}/v1/models \
  -H "x-api-key: $VULNETIX_API_KEY"
{
  "data": [
    {
      "type": "model",
      "id": "claude-sonnet-5",
      "display_name": "Claude Sonnet 5",
      "created_at": "2026-01-15T00:00:00Z"
    }
  ],
  "has_more": false,
  "first_id": "claude-sonnet-5",
  "last_id": "claude-sonnet-5"
}
Note This is why Claude Desktop works. It populates its model picker from this endpoint, and it cannot parse an OpenAI-shaped list — an empty picker with no error would be the symptom. Serving the Anthropic shape is what makes that integration possible at all.

An empty list

If the endpoint returns no models, the usual causes in order of likelihood:

  1. You are in allowlist mode and have not allowed anything at that provider. One allow entry flips the provider to allowlist-only — see the flip.
  2. You denied every model.
  3. The catalog has not synced models for that provider yet.

Note that an empty list does not prevent inference. A model absent from the catalog still works, unless the provider is in allowlist mode — see provider catalog.

A denied provider

Listing is refused for a provider your organisation has denied:

{
  "error": {
    "message": "provider openai is denied by organisation policy",
    "type": "policy_violation",
    "code": "provider_denied"
  }
}