---
title: "Attach a managed-provider backend to the model (platform admin)"
method: POST
path: "/v1/admin/inference/catalog/{modelId}/backends"
tags: ["Internal"]
---

# Attach a managed-provider backend to the model (platform admin)

`POST /v1/admin/inference/catalog/{modelId}/backends`

Adds one managed third-party backend (bedrock/openrouter/openai/anthropic) to the catalog row. Self-hosted capacity is NOT created here: pool:// endpoints are registrar-owned by serving deployments and attaching one by hand is refused. New backends start healthy at the given weight (default 0, the overflow tail), so attaching never moves traffic by itself.

## Path parameters

- `modelId` string, required

## Request body

- CreateInferenceCatalogBackendRequest
  - `auth` 'none' | 'bedrock_api_key' | 'api_key' | 'anthropic' — Auth STYLE the gateway applies to this backend's requests. anthropic sends x-api-key + anthropic-version headers (required by Anthropic- dialect upstreams); api_key sends Authorization: Bearer.
  - `endpoint` string, required
  - `maxConcurrency` integer
  - `nativeFamilies` string[], required
  - `provider` 'bedrock' | 'openrouter' | 'openai' | 'anthropic', required — Managed providers only; self-hosted capacity attaches through serving deployments
  - `ref` string, required — Provider-side model id
  - `transport` 'direct' | 'tunnel' | 'privatelink'
  - `weight` integer — Starting weight; 0 keeps the backend in the overflow tail so attaching moves no traffic

## Response `200`

Attached

- InferenceCatalogModel — The endpoint-level routing view of one catalog model.
  - `backends` InferenceCatalogBackend[], required
    - `accelerator` string — Hardware class tag, when known
    - `endpoint` string, required — pool://<poolId> for self-hosted capacity; an external URL for managed providers
    - `healthy` boolean, required — false = excluded from routing entirely (the kill switch)
    - `maxConcurrency` integer — Per-backend in-flight cap; 0 = model default
    - `maxPromptBytes` integer
    - `minPromptBytes` integer
    - `nativeFamilies` string[]
    - `pools` object[] — Self-hosted only: the deployments registering into this pool
      - `deploymentId` string
      - `nodePool` string
      - `status` string
      - `version` string
    - `provider` string, required — selfhosted|bedrock|openrouter|openai|anthropic (openrelay pools report selfhosted)
    - `ref` string, required — Provider-side model id / deployment id
    - `standby` boolean — true = held out of even the overflow tail (an unramped rollout green)
    - `transport` string — direct|tunnel|privatelink
    - `version` string — Low-cardinality rollout tag, when set
    - `weight` integer, required — Live routing weight (0 = overflow tail)
  - `enabled` boolean
  - `modelId` string, required
  - `routing` object
    - `families` object
    - `maxAttempts` integer
    - `strategy` string — first_healthy|weighted|sticky (empty = gateway default)
  - `status` string
  - `updatedAt` string

## Other responses

- `400` — The request is invalid
- `401` — Missing or invalid API key
- `403` — API key lacks the required scope
- `404` — Resource not found
- `409` — The request conflicts with existing state
- `503` — A required integration (e.g. payments) is not configured

## Changes

- **2026-08-26** `9dad68d3afa1` — 1 info
  - endpoint added

[Change history](https://skmtc.dev/openrelay/apis/openrelay-api/changes/v1/admin/inference/catalog/:modelId/backends/post.md)

---

[API](https://skmtc.dev/openrelay/apis/openrelay-api.md) · [All operations](https://skmtc.dev/openrelay/apis/openrelay-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/openrelay/openrelay-api/revisions/3dc47c9667e8/schema)
