# Set up a self-hosted provider

Last validated Apr 15, 2026

\[Missing snippet: aperture\_release\_note.mdx]

Configure a self-hosted LLM server as a provider in Aperture so your team can access private models through your tailnet. Any server that exposes an OpenAI-compatible chat completions endpoint works with the default configuration. Aperture supports both `/v1/chat/completions` and `/chat/completions` paths. Common servers include llama.cpp, vLLM, and Ollama.

\[Missing snippet: aperture\_any\_provider.mdx]

## Prerequisites

Before you begin, you need:

* An Aperture instance accessible from your device. Refer to [get started with Aperture][kb-aperture-get-started] if you have not set this up.
* A self-hosted LLM server accessible from the Aperture host (in the tailnet or on localhost).

## Configure the provider

Add your self-hosted server as a provider in your [Aperture configuration][kb-aperture-configuration]:

```json
{
  "providers": {
    "private": {
      "baseurl": "http://100.64.0.1:8080/v1",
      "models": ["qwen3-coder-30b", "llama-3.1-70b"]
    }
  }
}
```

Set `baseurl` to the full URL of your server's API endpoint, including the path prefix if your server uses one (for example, `http://100.64.0.1:8080/v1` for a vLLM server that serves at `/v1`). If your server serves at the root path without a version prefix, set `baseurl` to just the host and port (for example, `http://100.64.0.1:8080`). To find the correct model names, query your server's model list endpoint (typically `GET /v1/models`) and use the `id` field from the response.

> **Note:**
>
> Whether to include `/v1` in `baseurl` depends on how your LLM clients connect to Aperture. Most clients (Codex, OpenAI-compatible tools) are configured with `http://<aperture-hostname>/v1` as the base URL, which sends `/v1/chat/completions` in the request path. Because Aperture appends the full request path to `baseurl`, including `/v1` in the self-hosted `baseurl` when the client also sends `/v1` produces a doubled path (`/v1/v1/chat/completions`). If your clients use the standard `/v1` base URL, set the self-hosted `baseurl` to just the host and port (for example, `http://100.64.0.1:8080`). The configuration example above includes `/v1` in `baseurl`, which works when clients connect to Aperture without `/v1` in their base URL (sending `/chat/completions` instead of `/v1/chat/completions`). Refer to [how Aperture builds upstream URLs][kb-aperture-url-construction] for details.

Self-hosted providers use `openai_chat` compatibility and `bearer` authorization by default, so no additional flags are needed for servers that expose an OpenAI-compatible API. If your server uses a different API format, set the appropriate [compatibility flags][kb-provider-compatibility].

If your server does not require authentication, omit the `apikey` field. If your server requires a key, add `"apikey": "<your-key>"` to the provider block.

After configuring the provider:

1. [Grant model access][kb-grant-model-access] to the users or groups that need these models.
2. [Set up LLM clients][kb-use-your-tools] to connect coding tools through Aperture.

## Verify the provider

\[Missing snippet: aperture\_verify\_provider.mdx]

## Next steps

* [Grant model access][kb-grant-model-access] to users or groups that need these models.
* [Set up LLM clients][kb-use-your-tools] to connect coding tools through Aperture.
* Refer to the [provider compatibility reference][kb-provider-compatibility] for the full list of compatibility flags and configuration options.

[kb-aperture-configuration]: /docs/aperture/configuration

[kb-aperture-get-started]: /docs/aperture/get-started

[kb-aperture-url-construction]: /docs/aperture/configuration#how-aperture-builds-upstream-urls

[kb-grant-model-access]: /docs/aperture/how-to/grant-model-access

[kb-provider-compatibility]: /docs/aperture/provider-compatibility

[kb-use-your-tools]: /docs/aperture/use-your-tools
