# Supported providers

Ten providers, three request shapes. The **model name** selects the provider on
the OpenAI-compatible path, you do not pass a provider parameter.

| Provider key | Label | Request shape | Base URL to set |
|---|---|---|---|
| `openai` | OpenAI | `/v1/chat/completions`, `/v1/responses` | `https://www.spendline.ai/v1` |
| `anthropic` | Anthropic | `/v1/messages` | `https://www.spendline.ai` |
| `google` | Google Gemini | `/v1/chat/completions` | `https://www.spendline.ai/v1` |
| `xai` | xAI | `/v1/chat/completions` | `https://www.spendline.ai/v1` |
| `mistral` | Mistral | `/v1/chat/completions` | `https://www.spendline.ai/v1` |
| `deepseek` | DeepSeek | `/v1/chat/completions` | `https://www.spendline.ai/v1` |
| `qwen` | Alibaba Qwen | `/v1/chat/completions` | `https://www.spendline.ai/v1` |
| `together` | Together AI | `/v1/chat/completions` | `https://www.spendline.ai/v1` |
| `fireworks` | Fireworks AI | `/v1/chat/completions` | `https://www.spendline.ai/v1` |
| `groq` | Groq | `/v1/chat/completions` | `https://www.spendline.ai/v1` |

Anthropic is the only provider with its own protocol path. Everything else goes
through the OpenAI-compatible forwarder.

## Model → provider routing

Routing is decided in two steps:

1. **Model catalog lookup.** If Spendline's catalog knows the model and names a
   provider it can forward to, that provider wins.
2. **Model-name pattern match**, when the catalog has no usable answer.

The pattern rules, in the order they are applied:

| Model name contains / starts with | Routes to |
|---|---|
| `anthropic`, `claude` | `anthropic` |
| `google`, `gemini` | `google` |
| `xai`, `grok` | `xai` |
| `mistral`, `codestral`, `ministral`, `devstral`, `pixtral`, `magistral`, `open-mixtral` | `mistral` |
| `deepseek` | `deepseek` |
| `qwen`, `dashscope` | `qwen` |
| `groq`, or a `-versatile` / `-instant` / `-specdec` suffix | `groq` |
| `fireworks`, or a `llama-v3pN` pattern | `fireworks` |
| `together`, `meta-llama/` | `together` |
| any other `llama` or `mixtral` | `together` (most common OpenAI-compatible host) |
| `openai`, `gpt`, or starts with `o1` / `o3` / `o4` | `openai` |

An empty model name defaults to `openai`. Order matters: platform-specific
markers beat generic family names.

For the open-weight hosts (Together, Fireworks, Groq) the model name picks the
platform, and a stored provider key with a custom base URL decides the actual
host the request is sent to.

Do not hardcode this table. Resolve it at runtime from the live listing below if
you need certainty for a specific model.

## Live capability listing

Machine-readable, no auth required:

```
GET https://www.spendline.ai/agents/capabilities.json
```

Returns the provider list, request shapes, attribution headers and the response
contract as JSON. Use this rather than hardcoding, and rather than scraping this
page.

## Request shapes, exactly

| Shape | Endpoint | Streaming |
|---|---|---|
| OpenAI chat-completions | `POST /v1/chat/completions` | Yes |
| Anthropic messages | `POST /v1/messages` | Yes |
| OpenAI Responses | `POST /v1/responses` | **No**: `stream: true` is rejected |

## Not proxied

Embeddings, image generation, audio/speech, vector and knowledge-base search,
and Google's native `generateContent` shape. Leave those pointed directly at
the provider and say so in your integration report.

## Custom base URLs

Together, Fireworks, Groq, DeepSeek, Qwen, OpenAI, Google, xAI and Mistral
provider keys may carry a custom base URL (for a self-hosted or regional
endpoint). Anthropic may not, it uses its own protocol path and a base URL
there would be silently ignored, so it is rejected instead.
