# Cursor

> Route Cursor's chat and Composer through MirAPI by overriding the OpenAI base URL and adding deepseek-chat as a custom model.

Cursor is an AI code editor built on VS Code. Its built-in OpenAI integration points at OpenAI by default; by overriding the base URL and supplying a MirAPI key, you route Cursor's chat and Composer through MirAPI.

## What you need

| Element | Value |
|---|---|
| Base URL | `https://api.mirapi.ai/v1` (Override OpenAI Base URL) |
| API key | Your MirAPI key from the console |
| Model | `deepseek-chat` (added manually) |
| Protocol | OpenAI-compatible (`/v1`) |

## Configure

1. Open **Cursor Settings → Models**.
2. In **OpenAI API Key**, paste your MirAPI key.
3. Enable **Override OpenAI Base URL** and set it to:

```text
https://api.mirapi.ai/v1
```

4. Click **+ Add model** and enter `deepseek-chat`.
5. Toggle the model on so Cursor can use it.

:::note
Keep `/v1` in the base URL. Cursor appends the request path (for example `/chat/completions`) itself.
:::

## Verify with a message

Open a new chat, select `deepseek-chat`, and send:

```text
Reply with exactly: connected to MirAPI
```

The reply should contain `connected to MirAPI`. If the first message fails with 401, re-check the key and the base URL spelling.

## How it works

Cursor's **Override OpenAI Base URL** speaks the OpenAI Chat Completions protocol. MirAPI serves that protocol at `https://api.mirapi.ai/v1`, so Cursor's requests land on `POST /v1/chat/completions`. Responses stream as standard SSE (`data:` lines, ending with `data: [DONE]`); reasoning content arrives before the final answer.

MirAPI also serves the same models over the Anthropic (`/v1/messages`) and Gemini (`generateContent`) protocols; for Cursor, the OpenAI-compatible endpoint described here is the relevant one.

## Errors and billing

| Status | Meaning | What to do |
|---|---|---|
| 401 | Key missing, invalid, or unknown | Fix the key in Cursor settings |
| 403 | Key valid but rejected — balance exhausted, model not whitelisted, quota reached, or IP not allowed | Resolve the cause, then retry |
| 413 | Request too large | Reduce the size |
| 429 | Rate limited (no `Retry-After` header) | Retry with exponential backoff |
| 500 | Server error | Idempotent requests can be retried safely |

Every error message ends with a request ID; include it in any support ticket.

Chat usage is billed per token — input, output, and cache read, per 1M tokens. Reasoning tokens are billed as output. Prompt caching is automatic on OpenAI-compatible models; confirm hits via `usage.prompt_tokens_details.cached_tokens`. The balance is prepaid USD and never expires — when it runs out you get 403, and the same key resumes immediately after a top-up. Reconcile usage in the console billing log or via `GET /api/usage/token` (summary) and `GET /api/log/token` (per-request detail).

## Tool-specific pitfalls

- **The model list is manual.** Cursor cannot auto-discover MirAPI models; add every model you want by its exact `GET /v1/models` name. The `vendor/` prefix is console-only and is not part of the request name.
- **Some Cursor features use Cursor's own models** rather than your override — tab completions always, and the auto model picker in some cases. Confirm the model picker shows your MirAPI model in chat, Composer, and agent tasks.
- **403 with a valid key** usually means the model is not whitelisted for that key or the balance is exhausted. Top up or adjust the key's whitelist, then retry.
- **Keep `/v1`** — omitting it breaks the request path.

## Related links

- [Quickstart](/docs/quickstart)
- [OpenAI compatibility](/docs/openai-compat)
- [Models](/docs/models)
- [Billing](/docs/billing)
- [Authentication](/docs/api-reference/authentication)