# Base URLs and authentication

> The gateway's base URLs for each SDK, the headers ACOG reads your gateway key from, request limits and request IDs.

Product: AI Cost Optimizer Gateway (ACOG). Web version: https://tessarac.com/docs/acog/api/base-urls-and-authentication. Last updated: 2026-10-16.

## Base URLs

| Deployment | Gateway | Management API |
|---|---|---|
| Hosted | `https://gateway.acog.tessarac.com` | `https://acog.tessarac.com/api` |
| Self-hosted | `https://<your-acog-host>/gateway` | `https://<your-acog-host>/api` |

On the hosted service the gateway has its own address, with nothing between your application and ACOG but a load balancer. The console's address also serves the gateway, at `https://acog.tessarac.com/gateway`, and integrations made before October 2026 may use it. That path goes through the edge network in front of the console: a request that sends nothing back for 60 seconds is closed with `504`, and some errors arrive as an HTML page. Move to `gateway.acog.tessarac.com`; nothing else changes, and the same keys work on both.

What you configure depends on the path your SDK appends:

| Client | Base URL to configure | Why |
|---|---|---|
| OpenAI SDKs and OpenAI-compatible tools | `https://gateway.acog.tessarac.com/v1` | The OpenAI client appends `/chat/completions` to a base that already includes `/v1` |
| Anthropic SDKs and Anthropic-compatible tools | `https://gateway.acog.tessarac.com` | The Anthropic client appends `/v1/messages` itself |
| Native provider SDKs | `https://gateway.acog.tessarac.com/<provider>` | See [Native provider routes](https://tessarac.com/docs/acog/api/native-routes.md) |

The two shapes are not tied to providers: ACOG translates between them, so an OpenAI SDK can call a Claude model and an Anthropic SDK can call a GPT or Gemini model.

## Endpoints

| Method | Path (after the gateway base) | Page |
|---|---|---|
| `POST` | `/v1/chat/completions` | [Chat Completions](https://tessarac.com/docs/acog/api/chat-completions.md) |
| `POST` | `/v1/messages` | [Messages](https://tessarac.com/docs/acog/api/messages.md) |
| `POST` | `/responses` | [Responses](https://tessarac.com/docs/acog/api/responses.md) |
| `POST` | `/v1/embeddings` | [Embeddings](https://tessarac.com/docs/acog/api/embeddings.md) |
| `GET` | `/v1/models` | [Models](https://tessarac.com/docs/acog/api/models.md) |
| `GET` | `/v1/acog/batches/{id}` | [Batches](https://tessarac.com/docs/acog/api/batches.md) |
| any | `/anthropic/…`, `/openai/…`, `/vertex/…`, `/bedrock/…`, `/azure/…`, `/custom/…` | [Native provider routes](https://tessarac.com/docs/acog/api/native-routes.md) |

## Authentication

Every request carries a gateway key (`acog_…`). Create one on the **Developer** page; see [API keys](https://tessarac.com/docs/acog/administer/api-keys.md).

On the compatible endpoints (`/v1/…` and `/responses`), ACOG reads the key from the first of these that is present:

1. `Authorization: Bearer acog_…`
2. `x-acog-key: acog_…`
3. `x-api-key` or `api-key`, but only when the value starts with `acog_`

So with the Anthropic SDK, pass the gateway key as `auth_token` (Python) or `authToken` (TypeScript), which is sent as a bearer token, rather than as `api_key`. A provider key in `x-api-key` is never treated as a gateway key.

Native routes read the key from the header their provider's SDK uses. See [Native provider routes](https://tessarac.com/docs/acog/api/native-routes.md#authentication).

### Your provider credentials are never forwarded

ACOG removes `x-api-key`, `api-key` and any `Authorization` header that is not a gateway key before forwarding a request, and authenticates to your provider with your connection's own credentials.

### What a failed authentication looks like

| Status | `error.type` | Meaning |
|---|---|---|
| `401` | `unauthorized` | No key was found, or the key is unknown, disabled, expired, or used from an address outside its IP allowlist. The message does not say which. |
| `403` | `forbidden` | The key is valid but lacks the gateway access scope (`proxy`). |
| `503` | `service_unavailable` | ACOG could not reach its key store. Retry. |

A disabled key stops working within about five seconds.

## Request limits

| Limit | Value |
|---|---|
| Request body | 64 MiB. Larger requests are refused with `413 request_too_large`. |
| Waiting for a non-streaming reply | Up to 10 minutes without data on `gateway.acog.tessarac.com`; 60 seconds on `acog.tessarac.com/gateway`. Self-hosted, 2 minutes unless your operator sets `ACOG_UPSTREAM_READ_TIMEOUT_SECS`, and no longer than your load balancer allows. |
| Waiting between streamed chunks | The same limit applies to silence from the provider. ACOG sends a keep-alive comment every 15 seconds, so a stream stays open for as long as the model keeps working. |

Rate limits and budgets are your organization's own. See [Rate limits](https://tessarac.com/docs/acog/govern/rate-limits.md) and [Budgets](https://tessarac.com/docs/acog/govern/budgets.md).

## Request IDs

Every response carries `x-request-id`. Send your own `x-request-id` and ACOG uses it; otherwise it generates one. Quote it when you contact support.

## Useful request headers

| Header | Effect | Page |
|---|---|---|
| `x-acog-channel` | Pin the request to one platform | [Routing and failover](https://tessarac.com/docs/acog/providers/routing-and-failover.md#pin-a-request-to-one-platform-x-acog-channel) |
| `x-acog-batch` | Run the request at batch prices | [Batches](https://tessarac.com/docs/acog/api/batches.md) |
| `x-acog-cache-control` | Control the response cache | [Caching](https://tessarac.com/docs/acog/optimize/caching.md#controlling-the-response-cache-per-request) |
| `x-acog-label` | Tag the request for reports (a ticket number, a cost center) | [Request headers](https://tessarac.com/docs/acog/reference/request-headers.md) |

The full list is in [Request headers](https://tessarac.com/docs/acog/reference/request-headers.md).
