> ## Documentation Index
> Fetch the complete documentation index at: https://docs.prem.io/llms.txt
> Use this file to discover all available pages before exploring further.

# OpenCode

> Connect OpenCode to Prem API through the local Confidential Proxy.

OpenCode is a coding assistant that runs in your terminal. This guide connects it to Prem API. Prem runs the model inside a secure enclave. Your prompts stay private on the way there.

> [!NOTE]
>
> OpenCode does not use the TypeScript SDK directly. It uses the OpenAI-compatible routes from the Confidential Proxy. The proxy is part of `@premai/api-sdk`.

> [tab] Confidential API
>
> Use the local Confidential Proxy for sensitive prompts and source code. [Go to the confidential setup](#confidential-api-setup).

> [tab] ZDR
>
> Use Zero Data Retention (ZDR) for OpenAI-compatible inference with non-sensitive data. [Go to the ZDR setup](#zdr-setup).

## Confidential API setup

This path uses the local Confidential Proxy to encrypt your prompts end-to-end before they leave your machine.

### Use the bundled launcher

`@premai/api-sdk` includes `confidential-opencode`. It automates the manual setup below: it starts or reuses the local proxy in Anthropic mode, lists your enabled models, lets you pick one, and launches the installed `opencode` command against the local endpoint.

It needs OpenCode 2, an interactive terminal, and the same endpoints and keys as the manual setup. The launcher reads the Prem API key from `API_KEY`, not `PREM_API_KEY`:

```bash theme={"system"}
export API_KEY="your-prem-api-key"
export CLIENT_KEK="your-64-character-hex-kek"
export PROXY_URL="https://gateway.prem.io"
export ENCLAVE_URL="https://conf-engine.prem.io"
npx -p @premai/api-sdk confidential-opencode
```

The launcher passes its provider configuration through `OPENCODE_CONFIG_CONTENT` and starts OpenCode with `--standalone`. It ignores the project `opencode.json` and turns off model fetching, sharing, and auto-update. It picks the model itself, so it drops `--model` and `-m` from the arguments you pass. It forwards the rest to OpenCode, which needs a subcommand before any flag. Use `confidential-opencode run <args>` when you pass a subcommand. Stop the proxy it started with `confidential-proxy stop`.

The manual steps below configure the same connection by hand. Use them when you want to control the `opencode.json` yourself.

## How the connection works

```mermaid theme={"system"}
flowchart TB
    subgraph Local["Your machine: plaintext is available"]
        O["OpenCode"] -->|"OpenAI-compatible request"| P["Confidential Proxy<br/>127.0.0.1:8787/v1"]
    end

    P -->|"Encrypt before network egress"| G["Prem API Gateway<br/>ciphertext and metadata"]
    G -->|"Route the encrypted payload"| E["Prem API Enclave (TEE)<br/>decrypt, infer, encrypt"]
    E -.->|"Encrypted response returns on the same path"| P
    P -.->|"Decrypt on your machine"| O
```

OpenCode and the Confidential Proxy stay on your machine. The Prem API Gateway sees only the sealed message. The Prem API Enclave opens it inside a Trusted Execution Environment (TEE).

## Before you start

Get these four things ready:

* **OpenCode.** Both OpenCode 1 and OpenCode 2 work with Prem API. Pick your version below.
* **A Prem API key.** This proves who you are. See [API Keys](https://docs.prem.io/api-keys.md).
* **A client Key Encryption Key (KEK).** This is a master key that protects your other keys.
* **A model** that your Prem account can use. See [Models & Pricing](https://docs.prem.io/models-and-pricing.md).

> [!NOTE]
>
> The API key and the KEK are two different secrets. The API key handles sign-in, limits, and billing. The KEK protects your encryption keys. Keep both safe.

### Which OpenCode version are you?

> [tab] OpenCode 1
>
> Install OpenCode 1:
>
> ```bash theme={"system"}
> curl -fsSL https://opencode.ai/install | bash
> ```
>
> This guide shows the OpenCode 1 configuration keys (`provider`, `options`, `permission`) in each setup step.

> [tab] OpenCode 2
>
> Install OpenCode 2:
>
> ```bash theme={"system"}
> curl -fsSL https://opencode.ai/v2/install | bash
> ```
>
> OpenCode 1 and OpenCode 2 both use the `opencode` command.
> You cannot install both side by side with the same command.
>
> This guide shows the OpenCode 2 configuration keys (`providers`, `package`, `settings`, `permissions`) in each setup step.

## 1. Set your secrets

Open a terminal. Set these values in the terminal that runs the proxy:

```bash theme={"system"}
export PREM_API_KEY="your-prem-api-key"
export CLIENT_KEK="your-64-character-hex-kek"
export PROXY_URL="https://gateway.prem.io"
export ENCLAVE_URL="https://conf-engine.prem.io"
```

Do you not have a KEK yet? Make one, one time only:

```bash theme={"system"}
openssl rand -hex 32
```

Store the KEK in a secret manager. Keep a backup. Use the **same** KEK every time. Do not make a new one each time you start the proxy.

> [!NOTE]
>
> `PROXY_URL` and `ENCLAVE_URL` show the current default endpoints. Check the [Prem dashboard](https://dashboard.prem.io) if the endpoints change.

## 2. Start the Confidential Proxy

Start the proxy in OpenAI mode. Keep this terminal open while you work:

```bash theme={"system"}
npx -p @premai/api-sdk@1.0.70 confidential-proxy \
  --host 127.0.0.1 \
  --port 8787 \
  --compat openai \
  --kek "$CLIENT_KEK"
```

The proxy now listens at `http://127.0.0.1:8787/v1`. OpenCode sends its requests there.

## 3. Do a proxy test

Send one request before you start OpenCode:

```bash theme={"system"}
curl http://127.0.0.1:8787/v1/chat/completions \
  -H "Authorization: Bearer $PREM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "deepseek-v4.1-flash-1017",
    "messages": [{"role": "user", "content": "Reply with OK."}],
    "max_completion_tokens": 128,
    "stream": false
  }'
```

Use a different model ID if your account does not have `deepseek-v4.1-flash-1017`.

Inspect the response `model` field. The requested model `deepseek-v4.1-flash-1017` resolves to the same ID. The response does not include an assurance-profile field. See [Platform Status](https://docs.prem.io/platform-status.md).

Do not continue if this request does not complete. See [Errors](https://docs.prem.io/errors.md) and [Rate limits](https://docs.prem.io/rate-limits.md).

## 4. Configure OpenCode

Create `opencode.json` in the project root:

> [tab] OpenCode 1
>
> ```json theme={"system"}
> {
>   "$schema": "https://opencode.ai/config.json",
>   "model": "prem-confidential/deepseek-v4.1-flash-1017",
>   "small_model": "prem-confidential/deepseek-v4.1-flash-1017",
>   "enabled_providers": ["prem-confidential"],
>   "share": "disabled",
>   "provider": {
>     "prem-confidential": {
>       "npm": "@ai-sdk/openai-compatible",
>       "name": "Prem API through the Confidential Proxy",
>       "options": {
>         "baseURL": "http://127.0.0.1:8787/v1",
>         "apiKey": "{env:PREM_API_KEY}",
>         "timeout": 600000,
>         "chunkTimeout": 60000
>       },
>       "models": {
>         "deepseek-v4.1-flash-1017": {
>           "name": "DeepSeek V4.1 Flash"
>         }
>       }
>     }
>   },
>   "permission": {
>     "edit": "ask",
>     "bash": "ask"
>   }
> }
> ```
>
> Here is what each part does:
>
> | Setting | What it does |
> | - | - |
> | `baseURL` | Sends OpenCode's requests to your local proxy. |
> | `apiKey` | Reads the Prem API key from your terminal. |
> | `model` and `small_model` | Uses Prem for big and small tasks. |
> | `enabled_providers` | Uses Prem only. No other provider. |
> | `share: disabled` | Does not create public chat links. |
> | `permission` | Asks you before it edits files or runs shell commands. |
>
> This follows the [OpenCode custom provider docs](https://opencode.ai/docs/providers/). Change `deepseek-v4.1-flash-1017` to the model your account uses. Change it in both `model` and `models`.

> [tab] OpenCode 2
>
> ```json theme={"system"}
> {
>   "$schema": "https://opencode.ai/config.json",
>   "model": "prem-confidential/deepseek-v4.1-flash-1017",
>   "share": "disabled",
>   "providers": {
>     "prem-confidential": {
>       "name": "Prem API through the Confidential Proxy",
>       "env": ["PREM_API_KEY"],
>       "package": "@opencode/ai/providers/openai-compatible",
>       "settings": {
>         "baseURL": "http://127.0.0.1:8787/v1"
>       },
>       "models": {
>         "deepseek-v4.1-flash-1017": {
>           "name": "DeepSeek V4.1 Flash"
>         }
>       }
>     }
>   },
>   "permissions": [
>     { "action": "edit", "resource": "*", "effect": "ask" },
>     { "action": "shell", "resource": "*", "effect": "ask" }
>   ]
> }
> ```
>
> Here is what each part does:
>
> | Setting | What it does |
> | - | - |
> | `baseURL` | Sends OpenCode's requests to your local proxy. |
> | `env` | Reads the Prem API key from your terminal. |
> | `model` | Uses Prem for all tasks. |
> | `share: disabled` | Does not create public chat links. |
> | `permissions` | Asks you before it edits files or runs shell commands. |
>
> This follows the [OpenCode 2 providers guide](https://opencode.ai/v2/docs/providers/). Change `deepseek-v4.1-flash-1017` to the model your account uses. Change it in both `model` and `models`.

## 5. Start OpenCode

Start OpenCode from the folder that has `opencode.json`:

```bash theme={"system"}
opencode
```

Send a short prompt, such as "Say hello." Watch the proxy terminal. You see the request arrive.

That is it. OpenCode now talks to Prem through the sealed path.

> [!TIP]
>
> Type `/models` in OpenCode to check the model. The provider shows as **Prem API through the Confidential Proxy**.

## What this setup protects

| Component | Reads your text | Notes |
| - | - | - |
| OpenCode | Yes | It reads your prompt, your code, and the tool results on your machine. |
| Confidential Proxy | Yes, on your machine | It seals requests and opens replies. |
| Prem API Gateway | No | It handles the sealed message and metadata only. |
| Prem API Enclave | Yes, inside the TEE | It opens the request, runs the model, and seals the reply. |
| External tool or MCP server | Depends on the tool | A tool reads the data that OpenCode sends to it. |

> [!WARNING]
>
> This setup protects the model path only. It does not put OpenCode, your code, shell commands, plugins, MCP servers, or local files inside the enclave.

## Good to know

**Tool calls run on your machine.** The model can ask OpenCode to run a tool. The model traffic uses the sealed path. But OpenCode runs the tool on your machine, outside the enclave. So keep the `edit` and `bash` permissions set to `ask`. Do not treat a private model as a private tool.

**Concurrent requests per key.** Each API key can run a limited number of requests at the same time, set by your [tier](https://docs.prem.io/tiers.md#concurrent-requests). The encrypted endpoint always streams, and each call holds a slot until its stream closes. Requests above the limit return `429`. Start with one OpenCode session and no parallel subagents. Need parallel workers? Run them one after another, or give each worker its own API key. See [Agents & Automation](https://docs.prem.io/agents.md).

## Troubleshooting

> [accordion] OpenCode cannot connect
>
> Check that the proxy runs at `127.0.0.1:8787`. Check that `baseURL` ends with `/v1`.

> [accordion] The proxy returns 401
>
> Check that `PREM_API_KEY` is correct. Check that the API key is active.

> [accordion] The API says model not found
>
> Change `deepseek-v4.1-flash-1017` to a model your account can use. Change it in `model` and in `models`.

> [accordion] The API returns 429
>
> Wait for active streams to finish. Reduce parallel work. Follow the `Retry-After` header if the response has one.

> [accordion] OpenCode shows a different provider
>
> Check that `enabled_providers` lists only `prem-confidential`. Restart OpenCode after you change `opencode.json`.

## Frequently asked questions

### Which OpenCode versions work with Prem API?

Both OpenCode 1 and OpenCode 2.
Pick your version at the top of the setup, and each configuration step shows the keys for your version.

### Does OpenCode use the Prem TypeScript SDK?

No. The local proxy gives OpenCode an OpenAI-compatible interface. OpenCode does not import the SDK.

### Is the API key the same as the KEK?

No. The API key handles access, limits, and billing. The KEK protects your encryption keys.

### Does this protect my whole OpenCode session?

No. It protects the model path. OpenCode and its local tools stay on your machine.

### Can OpenCode use tool calls?

Yes, when the selected model supports tool calls. The model traffic uses the encrypted path. OpenCode runs each tool outside the enclave.

## ZDR setup

> [!WARNING]
>
> ZDR is not confidential. Do not send secrets, private source code,
> personal data, or regulated data through this path.

ZDR uses a separate OpenCode provider. It does not use the Confidential Proxy, client KEK, or attestation path.

Confirm that `kimi-k3` appears in `GET /openai/models` for this key. Otherwise, use
an exact returned model ID. See [Models & Pricing](https://docs.prem.io/models-and-pricing.md).

## 1. Set your API key

```bash theme={"system"}
export PREM_API_KEY="your-prem-api-key"
```

OpenCode reads the key from this environment variable via the `{env:PREM_API_KEY}`
reference in the provider config below.

## 2. Configure OpenCode

Add the `prem-zdr` provider in `opencode.json` at the project root:

> [tab] OpenCode 1
>
> ```json theme={"system"}
> {
>   "$schema": "https://opencode.ai/config.json",
>   "model": "prem-zdr/kimi-k3",
>   "enabled_providers": ["prem-zdr"],
>   "share": "disabled",
>   "provider": {
>     "prem-zdr": {
>       "npm": "@ai-sdk/openai-compatible",
>       "name": "Prem ZDR",
>       "options": {
>         "baseURL": "https://gateway.prem.io/openai",
>         "apiKey": "{env:PREM_API_KEY}",
>         "timeout": 600000,
>         "chunkTimeout": 60000
>       },
>       "models": {
>         "kimi-k3": {
>           "name": "Kimi K3 (ZDR)"
>         }
>       }
>     }
>   }
> }
> ```
>
> | Setting | What it does |
> | - | - |
> | `baseURL` | Sends OpenCode's requests to the ZDR gateway. No `/v1` segment; `/openai` is the ZDR route. |
> | `apiKey` | Reads the Prem API key from the `PREM_API_KEY` environment variable. |
> | `model` | Uses `prem-zdr/kimi-k3` as the default model. |
> | `enabled_providers` | Uses Prem only. No other provider. |

> [tab] OpenCode 2
>
> ```json theme={"system"}
> {
>   "$schema": "https://opencode.ai/config.json",
>   "model": "prem-zdr/kimi-k3",
>   "share": "disabled",
>   "providers": {
>     "prem-zdr": {
>       "name": "Prem ZDR",
>       "env": ["PREM_API_KEY"],
>       "package": "@opencode/ai/providers/openai-compatible",
>       "settings": {
>         "baseURL": "https://gateway.prem.io/openai"
>       },
>       "models": {
>         "kimi-k3": {
>           "name": "Kimi K3 (ZDR)"
>         }
>       }
>     }
>   }
> }
> ```
>
> | Setting | What it does |
> | - | - |
> | `baseURL` | Sends OpenCode's requests to the ZDR gateway. No `/v1` segment; `/openai` is the ZDR route. |
> | `env` | Reads the Prem API key from the `PREM_API_KEY` environment variable. |
> | `model` | Uses `prem-zdr/kimi-k3` as the default model. |

Change `kimi-k3` to the model your key can use in both `model` and `models`.

Keep the provider names separate when both paths are configured:

| Path | Provider | Key | Data boundary |
| - | - | - | - |
| Confidential API | `prem-confidential` | `PREM_API_KEY` | Encrypted through the local proxy |
| ZDR | `prem-zdr` | `PREM_API_KEY` | Not confidential |

## 3. Verify

Run a model-list check, then a bounded request, then start OpenCode:

```bash theme={"system"}
# From the project folder containing opencode.json: OpenCode sees the provider
opencode models prem-zdr

# A real request through Prem ZDR
opencode run --model prem-zdr/kimi-k3 "Reply with exactly: PREM_ZDR_OK"

# Start OpenCode normally; Prem ZDR is the default
opencode
```

`opencode models prem-zdr` should list `prem-zdr/kimi-k3`. The bounded request should
return `PREM_ZDR_OK`. Use a model ID your key can use if your key does not have `kimi-k3`.

## Related

> [card] [Confidential Proxy](https://docs.prem.io/confidential-proxy.md)
>
> Learn the proxy modes, routes, keys, and daemon controls.

> [card] [Agents & Automation](https://docs.prem.io/agents.md)
>
> Review concurrency, retries, reasoning, and error controls.

> [card] [OpenAI-compatible clients](https://docs.prem.io/guides/openai-compatible-clients.md)
>
> Understand the compatibility layer that OpenCode uses.

> [card] [Security Model](https://docs.prem.io/security-model.md)
>
> Learn what the enclave protects and what stays outside the TEE.

> [card] [Production Checklist](https://docs.prem.io/production-checklist.md)
>
> Complete the key, reliability, capacity, and attestation checks.

> [card] [Platform Status](https://docs.prem.io/platform-status.md)
>
> Review current behavior, assurance gaps, and roadmap items.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.