---
url: https://lettuceai.app/docs/host-api
title: "Host API — LettuceAI"
description: "Expose your configured models as a local OpenAI-compatible HTTP server so other devices and apps on your network can use them."
---

Menu 

# Host API

The Host API turns LettuceAI into a local OpenAI-compatible HTTP server. Other apps and devices on your network can point their OpenAI client at your machine and use any model you have configured in the app, with your provider credentials, your routing, and your rate limits.

Nothing is exposed unless you explicitly enable the server, pick which models to share, and (recommended) set a bearer token.

## What it is

Internally the server is a small Axum HTTP service that translates OpenAI-style requests into calls against your configured providers. Only models you mark as exposed are visible. Each exposed model gets its own API model ID (the name other clients use) and an optional display label.

## Enabling the server

Open **Settings > Advanced > Host API** and configure:

-   **Enable API Server.** Master on/off toggle.
-   **Bind address.** Defaults to `0.0.0.0` so other devices on your LAN can connect. Set it to `127.0.0.1` to limit access to the same machine.
-   **Port.** Defaults to `3333`. Any port from 1 to 65535.
-   **Bearer token.** A shared secret clients must send in the `Authorization` header. Use the **Generate Token** button to produce a random 48-character hex token.
-   **Exposed models.** Pick any text-capable models you have configured. For each one, set the API model ID (lowercased, dash-separated) and an optional friendly label.

Press **Apply & Restart Server** to save the config and start (or stop) the listener. The status banner at the top shows whether the server is running and the base URL clients should use. When you bind to `0.0.0.0`, the banner shows your machine's LAN address (instead of `0.0.0.0`) so you can copy a URL other devices can actually reach.

Desktop only, starts with the app

The Host API runs on desktop builds only. If it is enabled and has a token saved, it starts automatically when LettuceAI launches, so it is ready without reopening this page.

Set a token

With no token, anyone who can reach the bind address can use your models and burn your credits. Generate a token before exposing the server beyond `127.0.0.1`.

## Authentication

Every request to `/v1/models` and `/v1/chat/completions` must include the bearer token:

```
Authorization: Bearer YOUR_TOKEN
```

The `/health` endpoint is open and reports the server status, whether auth is required, and the list of exposed model IDs.

## CORS

The server returns permissive CORS headers (any origin, any method, any header), so browser-based clients on the same network can call it directly. The bearer token still gates access.

## Endpoints

-   `GET /`: basic service info (status, auth type, available endpoints). No auth required.
-   `GET /health`: status, exposed model IDs, auth info. No auth required.
-   `GET /v1/models`: OpenAI-style model list of everything you have exposed.
-   `POST /v1/chat/completions`: OpenAI-style chat completions. Supports `stream: true` for server-sent events.

## Streaming

Set `stream: true` in the request body and the server replies with SSE chunks in the standard OpenAI format (`data: {...}` lines, ending with `data: [DONE]`). If the client sends `stream_options.include_usage`, a final usage chunk is emitted before the terminator. Keep-alive pings hold the connection open during slow upstream responses.

## Example: curl

From another machine on your network:

```
curl http://192.168.1.42:3333/v1/chat/completions \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "my-exposed-model-id",
    "messages": [{"role": "user", "content": "Hello"}],
    "stream": false
  }'
```

## Example: OpenAI SDK

Any OpenAI-compatible client works. Point its base URL at your machine and pass the bearer token as the API key:

```
from openai import OpenAI

client = OpenAI(
    base_url="http://192.168.1.42:3333/v1",
    api_key="YOUR_TOKEN",
)

resp = client.chat.completions.create(
    model="my-exposed-model-id",
    messages=[{"role": "user", "content": "Hello"}],
)
print(resp.choices[0].message.content)
```

## How model IDs work

The model ID a client sends is the **API Model ID** you set in the exposed-models list, not the underlying provider model name. This lets you rename things (for example, expose`claude-sonnet-4-5` as just `sonnet`) and swap the backend later without breaking client config.

## Per-request overrides

Standard OpenAI sampling fields sent in the request body are honored and override the model's saved settings for that call: `temperature`, `top_p`, `max_tokens` (or `max_completion_tokens`), `frequency_penalty`, and `presence_penalty`. If a field is omitted, the model's configured value is used.

## HTTPS and certificates

The Host API serves plain **HTTP** only; there is no option to serve it over HTTPS. Keep it on your trusted local network, and rely on the bearer token for access control. If you need TLS, place it behind your own reverse proxy.

This is separate from connecting LettuceAI _out_ to a self-signed endpoint (for example a local provider behind HTTPS). For that, import the certificate under **Settings > Security > Trusted Certificates > Custom Root CAs**, or enable **Allow Invalid TLS** on that specific provider under **Settings > Providers**.

## Stopping the server

Toggle **Enable API Server** off and press **Apply & Restart Server**. The listener shuts down immediately. Disabling does not lose your config: bind address, port, token, and exposed models stay saved for next time.

[

PreviousSprout Hardware Probe

](/docs/sprout)[

NextImage Generation

](/docs/images)
