# Provision models via API

> Provision providers and models through the Catalog API: upsert provider, set credential, upsert model with pricing and capabilities, assign to a project, and verify.

The Admin Dashboard is the usual surface for connecting providers and enabling models, but automation needs the same outcome without clicking through forms. The Catalog API is that path: upsert a provider, store its credential, upsert a model with pricing and capabilities, assign the model to a project so a project gateway can route to it, then verify with a read-back and an inference call. This guide walks that sequence end to end with illustrative HTTP requests. For the dashboard equivalent, see <Link to="/agent-router-enterprise/guides/operate-and-govern/provision-models-and-providers/">Provision models and providers</Link>.

:::tip Two API surfaces
This guide uses the [Management API](/reference/api/) (Catalog and project assignment) to provision configuration. Live prompts use the [Gateway APIs](/reference/supported-apis/) on the data plane (`/v1/chat/completions`, `/v1/models`, and related paths). The final verification step switches to that gateway surface; the provisioning steps do not.
:::

**Persona:** Platform operator or platform engineer automating catalog provisioning against the management API.

**Estimated time:** 15 to 25 minutes once you have an admin API key, a provider credential, and the customer and project identifiers for assignment.

## When this guide applies

This guide is the right reference in any of these situations:

| Situation | Why this guide helps |
| :---- | :---- |
| A script or pipeline must provision providers and models without the Admin Dashboard | The Catalog write RPCs are the programmatic surface for the same configuration |
| An internal source of truth syncs the model catalogue into Agent Router | Upsert and assign map cleanly onto a repeatable reconciliation loop |
| You need pricing and capability fields set at create time, not only toggled later in the UI | UpsertModel accepts pricing and capabilities in one request |
| You have the OpenAPI or SDK reference but no ordered how-to | This guide sequences the calls and shows how to verify the result |

If you prefer the Admin Dashboard, use [Provision models and providers](/agent-router-enterprise/guides/operate-and-govern/provision-models-and-providers/) instead. For managing the broader configuration baseline as code, see [Manage configuration as code](/agent-router-enterprise/guides/operate-and-govern/manage-configuration-as-code/).

## Outcomes

By the end of this guide:

- A provider record exists with a stored credential.
- A model record exists under that provider, with pricing and capabilities set.
- The model is assigned to a project so the project gateway can route to it.
- You have confirmed the configuration with Catalog read-backs and a gateway inference call.

## Prerequisites

- An API credential with administrative scope for Catalog writes, issued from the Admin Dashboard or an equivalent control-plane path. Bearer auth on every request below.
- The management API base URL for the deployment (the host that serves `/v1/catalog/...`). Replace `https://management.example.com` in the examples with that host.
- Upstream provider credentials (API key, bearer token, or whatever the provider expects) and the provider's API base URL.
- The customer and project identifiers used when assigning a model to a project.
- For the final inference check: a **client** API key minted for that project (CreateClientWithKey), not a CreateApiKey user token. See [Which API key for which surface](/reference/api/#which-api-key-for-which-surface).

The `tare api catalog` CLI exposes the same operations as flags. This guide uses HTTP so the request bodies are explicit; either surface is valid.

## Step 1: upsert the provider

Create or fully replace the provider record with [UpsertProvider](/reference/api/catalog/agentrouter-catalog-v-1-catalog-service-upsert-provider/). The `id` is a canonical slug: lowercase alphanumeric only (`[a-z0-9]+`), no hyphens.

```bash
curl -sS -X POST "https://management.example.com/v1/catalog/providers" \
  -H "Authorization: Bearer ${ADMIN_API_KEY}" \
  -H "Content-Type: application/json" \
  -d '{
    "id": "acmeopenai",
    "displayName": "Acme OpenAI",
    "baseUrl": "https://api.openai.com/v1",
    "supportedAuthSchemes": ["bearer"]
  }'
```

Required fields are `id`, `displayName`, and `baseUrl`. `supportedAuthSchemes` is optional (for example `["bearer"]`).

## Step 2: set the provider credential

Store or rotate the upstream credential with [SetProviderCredential](/reference/api/catalog/agentrouter-catalog-v-1-catalog-service-set-provider-credential/). The plaintext is never returned; the provider's `credential_suffix` reflects the last four characters after a successful write.

```bash
curl -sS -X POST "https://management.example.com/v1/catalog/providers/acmeopenai/credential" \
  -H "Authorization: Bearer ${ADMIN_API_KEY}" \
  -H "Content-Type: application/json" \
  -d '{
    "credential": "'"${PROVIDER_API_KEY}"'"
  }'
```

Credential rotation uses the same call with the new value. In-flight requests that already held the old credential complete with it; subsequent requests use the new one.

## Step 3: upsert the model (pricing and capabilities)

Create or fully replace the model with [UpsertModel](/reference/api/catalog/agentrouter-catalog-v-1-catalog-service-upsert-model/). Pricing fields are decimal USD strings. Capabilities declare what the model supports (for example `chat` or `embeddings`); that is the API counterpart of choosing a model mode in the UI.

```bash
curl -sS -X POST "https://management.example.com/v1/catalog/models" \
  -H "Authorization: Bearer ${ADMIN_API_KEY}" \
  -H "Content-Type: application/json" \
  -d '{
    "providerId": "acmeopenai",
    "name": "gpt-4o",
    "upstreamModel": "gpt-4o",
    "inputPerMillion": "2.50",
    "outputPerMillion": "10.00",
    "cacheReadPerMillion": "1.25",
    "maxCostPerRequest": "",
    "maxContextTokens": 128000,
    "capabilities": ["chat"]
  }'
```

Required fields are `providerId` and `name`. `upstreamModel` defaults to `name` when empty. Capture the model id returned in the response; you need it for project assignment in the next step.

For an embedding model, set `capabilities` to include `embeddings` and verify with the embeddings endpoint instead of chat completions.

## Step 4: assign the model to a project

:::note Projects are the isolation boundary
A **project** owns the models, API keys, and gateway URL an application calls. Catalog enablement alone does not make a model visible on a project gateway—you must assign it. A default project is created during onboarding and is enough for a first verification; creating additional projects and granting models in the Admin Dashboard is covered in [Create a project and grant models](/agent-router-enterprise/guides/operate-and-govern/project-and-data-plane-management/create-a-project/). For the full concept, see [Key concepts → Projects](/product-architecture/key-concepts/#projects).
:::

Grant access with [AssignModelToProject](/reference/api/catalog/agentrouter-catalog-v-1-catalog-service-assign-model-to-project/). The call is idempotent: re-assigning the same model is a no-op.

```bash
curl -sS -X POST \
  "https://management.example.com/v1/customers/${CUSTOMER_ID}/projects/${PROJECT_ID}/models" \
  -H "Authorization: Bearer ${ADMIN_API_KEY}" \
  -H "Content-Type: application/json" \
  -d '{
    "modelId": "'"${MODEL_ID}"'"
  }'
```

`modelId` is the catalog model id from the UpsertModel response. Without this assignment, a project-scoped gateway may not list or route to the model even though the catalog record exists. In the Admin Dashboard, enablement and project scoping are the UI counterparts of the upsert-plus-assign sequence.

## Step 5: verify

Confirm configuration first, then traffic.

### Read-back

1. Fetch the provider: `GET /v1/catalog/providers/{id}` ([GetProvider](/reference/api/catalog/agentrouter-catalog-v-1-catalog-service-get-provider/)). Confirm `baseUrl` and that `credential_suffix` is set.
1. Fetch the model: `GET /v1/catalog/models/{id}` ([GetModel](/reference/api/catalog/agentrouter-catalog-v-1-catalog-service-get-model/)). Confirm pricing, `maxContextTokens`, and `capabilities`.
1. List project models: `GET /v1/customers/{customer_id}/projects/{project_id}/models` ([ListProjectModels](/reference/api/catalog/agentrouter-catalog-v-1-catalog-service-list-project-models/)). Confirm the new model appears.

```bash
curl -sS "https://management.example.com/v1/catalog/providers/acmeopenai" \
  -H "Authorization: Bearer ${ADMIN_API_KEY}"

curl -sS "https://management.example.com/v1/catalog/models/${MODEL_ID}" \
  -H "Authorization: Bearer ${ADMIN_API_KEY}"

curl -sS \
  "https://management.example.com/v1/customers/${CUSTOMER_ID}/projects/${PROJECT_ID}/models" \
  -H "Authorization: Bearer ${ADMIN_API_KEY}"
```

### Inference

The steps above used the **management** (Catalog) API. End-to-end verification switches to the **gateway** inference surface: a different host and a **project client** key (CreateClientWithKey), not the admin credential used for Catalog writes. Gateway paths, formats, and auth are documented in [Gateway APIs](/reference/supported-apis/).

Use the gateway base URL for the deployment (for Fully Managed, often `https://api.router.tetrate.ai/v1`). First list the models routable for that client key with [`GET /v1/models`](/reference/supported-apis/#models-api-v1models). Each returned `id` is a value you can pass as `model` on an inference call. Confirm the model you just provisioned and assigned appears in the list.

```bash
curl -sS "https://api.router.tetrate.ai/v1/models" \
  -H "Authorization: Bearer ${CLIENT_API_KEY}"
```

Then send a Chat Completions request ([`POST /v1/chat/completions`](/reference/supported-apis/#chat-completions-api-v1chatcompletions)) using one of those `id` values:

```bash
curl -sS -X POST "https://api.router.tetrate.ai/v1/chat/completions" \
  -H "Authorization: Bearer ${CLIENT_API_KEY}" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-4o",
    "messages": [{"role": "user", "content": "ping"}]
  }'
```

A successful response confirms credentials, catalog configuration, and project assignment end to end. If the model is missing from `GET /v1/models`, the usual causes are a missed upsert or project assignment. An upstream authentication error on the completion call usually points at the provider credential. For more gateway call shapes, see [Make an API call](/agent-router-service/quickstarts/make-an-api-call/).

## What to do next

Use the dashboard for the same catalog and grant work when you prefer UI, or stay on the API and IaC path below. Catalog method detail is in [CatalogService](/reference/api/catalog/agentrouter-catalog-v-1-catalog-service/).

Where to go next

  <Link to="/agent-router-enterprise/guides/operate-and-govern/provision-models-and-providers/" className="tare-nav-card">
    Provision models and providers
    The Admin Dashboard workflow for providers and model enablement.
  </Link>
  <Link to="/agent-router-enterprise/guides/operate-and-govern/project-and-data-plane-management/create-a-project/" className="tare-nav-card">
    Create a project and grant models
    Grant catalog models to a project, then provision its gateway and keys.
  </Link>
  <Link to="/agent-router-enterprise/guides/operate-and-govern/manage-configuration-as-code/" className="tare-nav-card">
    Manage configuration as code
    How the admin API fits UI and IaC ownership of the catalogue.
  </Link>
