EN ▾
Get API key

OpenCode with an OpenAI Compatible API: Setup

Getting opencode openai compatible api access working takes one custom provider entry. You define a custom provider in the config file with a base URL, a key and a model entry. This guide shows the exact values and how to test them first.

Updated

A terminal panel linked by a glowing cable to a server rack, representing a coding agent calling a custom API

Key points

  • Verify the endpoint with curl before you touch OpenCode, so you know whether a failure is the config or the API.
  • A custom provider needs three things: base URL, API key and a model ID, which is uncensored here.
  • Set the context limit to 100,000 tokens so the agent plans around the real window.
  • Streaming and tool calling are supported, which is what an agent loop needs.

What you need before you start

OpenCode is an open-source coding agent that runs in your terminal. It can talk to many model providers, and it lets you add your own provider if the endpoint follows the OpenAI chat format. This API does, so setup is a matter of filling in a few fields.

Gather these three values first:

  • Base URL: https://api.kimicode.top/v1
  • Model ID: uncensored
  • API key: create one on the API key page. New accounts can claim a $0.50 trial credit there with one click, which is plenty for the tests below. The trial key allows 2 concurrent requests and 60 requests per minute.

Keep the key in an environment variable instead of pasting it into files you commit:

export KIMICODE_API_KEY="your-key-here"

Step 1: test the endpoint with curl

Do this before configuring any tool. If curl works and OpenCode does not, you know the problem is in the config. If curl fails, you fix the key or the URL once, not in two places.

curl https://api.kimicode.top/v1/chat/completions \
  -H "Authorization: Bearer $KIMICODE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "uncensored",
    "messages": [{"role": "user", "content": "Say hello in five words."}],
    "max_tokens": 40
  }'

You should get a JSON object with a choices array and a usage block. A 401 means the key is wrong or missing the Bearer prefix. A 404 usually means the URL was mistyped or already includes /chat/completions.

A coding agent streams its answers and calls tools, so check those two as well:

curl -N https://api.kimicode.top/v1/chat/completions \
  -H "Authorization: Bearer $KIMICODE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "uncensored",
    "stream": true,
    "messages": [{"role": "user", "content": "Count from one to five."}]
  }'

You should see a series of data: lines, each with a small JSON delta, ending with the usage figures and a final marker. The -N flag turns off curl's buffering so chunks appear as they arrive.

Step 2: add a custom provider to OpenCode

OpenCode reads a JSON config file, opencode.json, from your project folder or from its global config directory. Custom OpenAI-style providers are declared with the AI SDK's OpenAI compatible package, a base URL and a list of models. The layout below follows OpenCode's public documentation at the time of writing. Field names can change between releases, so compare it with the provider section of the current OpenCode docs if something is rejected.

{
  "$schema": "https://opencode.ai/config.json",
  "provider": {
    "kimicode": {
      "npm": "@ai-sdk/openai-compatible",
      "name": "Kimicode API",
      "options": {
        "baseURL": "https://api.kimicode.top/v1",
        "apiKey": "{env:KIMICODE_API_KEY}"
      },
      "models": {
        "uncensored": {
          "name": "Uncensored",
          "limit": {
            "context": 100000,
            "output": 8192
          }
        }
      }
    }
  },
  "model": "kimicode/uncensored"
}

The key under models is the exact model ID sent to the server, so it must read uncensored. The last line selects the provider and model as the default, written as provider name, a slash, then model ID.

The {env:KIMICODE_API_KEY} form tells OpenCode to read the variable from your shell. If your version handles credentials through its own login command instead, use that route and leave the key out of the file. Either way, do not commit a real key.

Project config or global config

You can keep the provider block in two places. A file in the project root applies to that repository only, which suits a team that shares one setup. A file in your user config directory applies everywhere, which suits a personal default. Where both exist, the project file adds to or overrides the global one.

Prefer the global file for the provider definition and the environment variable for the key. Then every repository can use the endpoint, and nothing secret sits next to your source code. If several people work in one project, commit only the provider block without a key, and have each person set their own variable. This also makes it simple to rotate a key: change the variable, restart the terminal, and the config file stays untouched.

Step 3: pick the model and run a task

Start OpenCode in a project folder and open its model picker. Your custom provider should appear in the list with the display name you set. Select it, then give the agent a small, checkable job such as explaining a function or writing a unit test for a short file.

Start small for two reasons. First, you can see whether tool calls work: when OpenCode asks the model to read or edit a file, it does so through the tool calling interface. Second, a coding agent sends a lot of text per turn, including file contents and history, so a long session consumes tokens quickly. The next section puts numbers on that.

If the model does not show up, check that the file is valid JSON, that it sits where OpenCode looks for config, and that the provider name matches what you typed in the model field.

Testing tool calling and JSON mode directly

OpenCode relies on tool calling to read files, run commands and edit code, so it is worth confirming that the endpoint handles a tool definition before blaming the agent for a failure. This request offers one tool and asks a question that needs it.

curl https://api.kimicode.top/v1/chat/completions \
  -H "Authorization: Bearer $KIMICODE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "uncensored",
    "messages": [{"role": "user", "content": "What is in the file notes.txt?"}],
    "tools": [{
      "type": "function",
      "function": {
        "name": "read_file",
        "description": "Read a text file by path",
        "parameters": {
          "type": "object",
          "properties": {"path": {"type": "string"}},
          "required": ["path"]
        }
      }
    }],
    "tool_choice": "auto"
  }'

A good response contains a tool_calls entry naming read_file with a JSON argument string. The agent runs the tool, then sends the result back as a message with role set to tool, and the model continues from there. If you only see plain text, try a more direct prompt, since whether the model decides to call a tool is part of its behavior.

JSON mode is a separate switch. Adding "response_format": {"type": "json_object"} asks for valid JSON output, and it helps when another script has to parse what comes back. Mention JSON in your prompt as well, so the model knows what shape you expect.

Context size and what a session costs

The context window is 100,000 tokens, counting the prompt and the completion together. Setting limit.context to 100000 lets the agent know the real ceiling, so it can trim or summarize history before the server has to reject a request. A completion may use whatever room is left, and max_tokens is optional.

Billing is $0.15 per 1M input tokens and $0.50 per 1M output tokens. Agents are input heavy, because every turn resends the conversation. Here is a worked example for a moderate session:

  • 40 turns, each sending about 30,000 input tokens: 1,200,000 input tokens, which is 1.2 x $0.15 = $0.18.
  • Each turn returns about 800 output tokens: 32,000 output tokens, which is 0.032 x $0.50 = $0.016.
  • Total: $0.196, so roughly twenty cents for the whole session.

Your numbers will differ. Read the usage values in responses, or watch the X-Balance-USD header, which reports your remaining balance on each response. Credit is prepaid and never expires, and failed or refused requests are not charged. Details are on the pricing page.

Honest expectations for a coding agent

This is a general text model tuned to answer without content refusals for lawful adult use. It is not a model built specifically for code, and this page makes no benchmark claims. Whether it edits your repository reliably is something you should test on your own tasks, with version control on, before you hand it anything important.

It handles the plumbing an agent needs: tool calling with streamed tool_calls, tool results sent back as role: "tool" messages, and JSON mode through response_format. It is text only, with no images, so features that attach screenshots will not work.

Two limits matter for agents. A full key allows 8 concurrent requests and 300 requests per minute. Sub-agents or parallel tool runs that fire many calls at once can hit the concurrency cap, and a streamed request keeps its slot until the stream ends. When that happens you get HTTP 429 with the code concurrency. The code rate_limited means too many requests per minute. On temporary overload you may also see a 429 with Retry-After: 5. Reduce parallelism or wait and retry.

Troubleshooting

SymptomLikely causeFix
401 UnauthorizedEmpty or wrong key; the environment variable is not set in the shell that launched OpenCodeRun echo $KIMICODE_API_KEY in the same terminal, then restart OpenCode
404 Not FoundBase URL includes /chat/completions or lacks /v1Use exactly https://api.kimicode.top/v1
Model not foundModel key differs from uncensoredMatch the key in models to the ID returned by GET /v1/models
429 with concurrencyToo many requests at onceLower parallel tool calls, or wait for streams to finish
Request too largeBody over 8 MB or history near the window limitStart a fresh session or summarize history

For anything not covered here, the docs page has the full request reference, and the integration guide covers the same endpoint from the angle of other OpenAI-style clients.

Questions and answers

Does OpenCode support a custom base URL?

Yes. You declare a custom provider in opencode.json with a base URL, a key and a list of models. Check OpenCode's current docs for the exact field names, since they can change between versions.

Which model ID should I enter?

Enter uncensored, exactly as written. It must match the key in the models block and the ID returned by GET /v1/models.

Is there a free way to test the setup?

New users can claim $0.50 of trial credit with one click on the API key page after sign-up. It lasts 7 days, needs no card, and is limited to one per person.

Why do I get 429 errors during an agent run?

Agents often send several requests at once. The full key allows 8 concurrent requests and 300 per minute, and the trial key allows 2 and 60. Reduce parallelism or retry after the Retry-After delay.

Your key is one form away

Create an account, copy the key, change the base URL. That is the whole setup.

Get API key