{"id":69,"date":"2026-09-16T22:56:37","date_gmt":"2026-09-16T14:56:37","guid":{"rendered":"https:\/\/wp.qoraapi.com\/connect-cursor-cline-continue-custom-api-endpoint\/"},"modified":"2026-09-20T03:22:50","modified_gmt":"2026-09-19T19:22:50","slug":"connect-cursor-cline-continue-custom-api-endpoint","status":"publish","type":"post","link":"https:\/\/qoraapi.com\/blog\/connect-cursor-cline-continue-custom-api-endpoint\/","title":{"rendered":"How to Connect Cursor, Cline and Continue to a Custom AI API Endpoint"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Cursor, Cline, and Continue.dev all speak the same protocol: an <strong>OpenAI-compatible API<\/strong>. If your provider exposes that interface, you can point every one of them at it with a single <code>base_url<\/code> change \u2014 no plugin fork, no custom client, no SDK rewrite. This guide walks through the exact steps for each tool, the configuration fields to set, and the pitfalls that catch people the first time they swap the endpoint.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The audience for this is developers who already use one of these editors daily and want to plug in their own key, route through a relay that gives them cheaper pricing, or use a model the editor does not expose by default. The change is small, the payoff is large, and the setup is roughly five minutes per tool.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"why-custom-endpoint\">Why connect a coding tool to a custom endpoint<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The default OpenAI key inside Cursor, Cline, or Continue gives you one provider&#8217;s models at one provider&#8217;s prices. A custom endpoint \u2014 typically a relay or an OpenAI-compatible gateway \u2014 opens four doors that matter in production:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n\n<li><strong>One key for many models.<\/strong> Use GPT, Claude, and Gemini behind a single API key, switching models by changing a string. Our guide to the <a href=\"https:\/\/qoraapi.com\/blog\/openai-compatible-api-guide\/\">OpenAI-compatible API<\/a> explains the contract that makes this possible.<\/li>\n\n<li><strong>Cost control.<\/strong> Routes through relays that offer cheaper rates, and routes the easy work \u2014 autocomplete, naming, simple refactors \u2014 to a smaller model while reserving flagship inference for hard problems. See our <a href=\"https:\/\/qoraapi.com\/blog\/reduce-ai-api-costs\/\">guide to reducing AI API costs<\/a> for the broader pattern.<\/li>\n\n<li><strong>Provider redundancy.<\/strong> If one upstream is throttled or degraded, you point the editor at another in seconds. See our guide on <a href=\"https:\/\/qoraapi.com\/blog\/ai-api-rate-limits-429-errors\/\">handling rate limits and 429 errors<\/a> for why this matters.<\/li>\n\n<li><strong>Centralised billing.<\/strong> One bill, one spend cap, one place to watch usage instead of separate statements per provider.<\/li>\n\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"what-openai-compatible-means\">What &#8220;OpenAI-compatible&#8221; means here<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">When a tool says it supports an &#8220;OpenAI-compatible endpoint&#8221;, it means the tool will send HTTP requests to whatever URL you give it, using OpenAI&#8217;s <code>Authorization: Bearer &lt;key&gt;<\/code> header and the same JSON request body OpenAI does. The provider on the other side is responsible for returning a response in the same shape, including streaming, function calling, and tool use.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">From your perspective, that means two fields do almost all the work:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n\n<li><strong><code>base_url<\/code><\/strong> \u2014 the URL of the OpenAI-compatible API. For <a href=\"https:\/\/qoraapi.com\/\" target=\"_blank\" rel=\"noopener\">qoraapi.com<\/a>, this is <code>https:\/\/qoraapi.com\/v1<\/code>. The path <code>\/v1\/chat\/completions<\/code> is appended by the tool.<\/li>\n\n<li><strong><code>api_key<\/code><\/strong> \u2014 the bearer token issued by that endpoint. For most relays, including Qora API, this is generated in the dashboard after sign-up.<\/li>\n\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">The third input is the <strong>model name<\/strong> \u2014 a string like <code>gpt-4o<\/code>, <code>claude-3-5-sonnet<\/code>, or a relay-specific alias \u2014 which the provider maps to the underlying model. Switching it is how you move from GPT to Claude to Gemini without changing any other field.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"cursor\">Connect Cursor to a custom endpoint<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Cursor exposes an &#8220;OpenAI API Key&#8221; field in its settings, and in newer versions a separate &#8220;Override OpenAI Base URL&#8221; toggle. The flow is:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n\n<li>Open Cursor, press <code>Ctrl+,<\/code> (or <code>Cmd+,<\/code> on macOS) to open Settings.<\/li>\n\n<li>Go to <strong>Models<\/strong> (or search &#8220;OpenAI API Key&#8221; in the settings search).<\/li>\n\n<li>Paste your custom endpoint&#8217;s API key into <strong>OpenAI API Key<\/strong>.<\/li>\n\n<li>If present, enable <strong>Override OpenAI Base URL<\/strong> and set it to your endpoint, e.g. <code>https:\/\/qoraapi.com\/v1<\/code>.<\/li>\n\n<li>Under <strong>Custom Models<\/strong> (or in <code>~\/.cursor\/config.json<\/code>), add the models you want, each one with the model string the relay exposes \u2014 for example <code>gpt-4o<\/code>, <code>claude-3-5-sonnet<\/code>, or a Qora-specific alias.<\/li>\n\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">Save and restart Cursor if a model does not appear in the model picker. Verify the setup by opening a chat and asking a one-line question \u2014 if you get a normal answer, the connection is good; if you get a 401 or 404, the key or the base URL is wrong.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"cline\">Connect Cline (VS Code) to a custom endpoint<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Cline is the VS Code extension that runs Claude or GPT inside your editor with full tool use. Its settings panel has first-class support for &#8220;OpenAI Compatible&#8221; providers, which is the option you want for any custom endpoint.<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n\n<li>In VS Code, click the Cline icon in the Activity Bar, then the gear icon to open Cline&#8217;s settings.<\/li>\n\n<li>Set <strong>API Provider<\/strong> to <strong>OpenAI Compatible<\/strong>.<\/li>\n\n<li>Fill in:\n<ul>\n\n<li><strong>OpenAI Base URL<\/strong>: <code>https:\/\/qoraapi.com\/v1<\/code><\/li>\n\n<li><strong>OpenAI API Key<\/strong>: your custom endpoint key<\/li>\n\n<li><strong>Model ID<\/strong>: the model string, e.g. <code>gpt-4o<\/code> or <code>claude-3-5-sonnet<\/code><\/li>\n\n<\/ul>\n\n<\/li>\n\n<li>If your endpoint advertises a different model set than OpenAI&#8217;s defaults, the <strong>Model ID<\/strong> must exactly match one the relay exposes \u2014 typos here are the most common reason for a &#8220;model not found&#8221; error.<\/li>\n\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">Cline uses the configured endpoint for both chat and tool calls (file edits, terminal commands), so getting the base URL right means everything else just works \u2014 including agent mode.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"continue\">Connect Continue.dev to a custom endpoint<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Continue is configured entirely through a JSON file, which gives you fine-grained control and is easy to script across a team. The default location is <code>~\/.continue\/config.json<\/code>.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>{\n  \"models\": [\n    {\n      \"title\": \"Qora GPT-4o\",\n      \"provider\": \"openai\",\n      \"model\": \"gpt-4o\",\n      \"apiBase\": \"https:\/\/qoraapi.com\/v1\",\n      \"apiKey\": \"YOUR_KEY\"\n    },\n    {\n      \"title\": \"Qora Claude 3.5 Sonnet\",\n      \"provider\": \"openai\",\n      \"model\": \"claude-3-5-sonnet\",\n      \"apiBase\": \"https:\/\/qoraapi.com\/v1\",\n      \"apiKey\": \"YOUR_KEY\"\n    }\n  ],\n  \"tabAutocompleteModel\": {\n    \"title\": \"Qora Autocomplete\",\n    \"provider\": \"openai\",\n    \"model\": \"gpt-4o-mini\",\n    \"apiBase\": \"https:\/\/qoraapi.com\/v1\",\n    \"apiKey\": \"YOUR_KEY\"\n  }\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The split between the main <code>models<\/code> array and <code>tabAutocompleteModel<\/code> is intentional: it lets a small, cheap model serve inline completions while the larger model handles chat \u2014 the same idea behind our guide to <a href=\"https:\/\/qoraapi.com\/blog\/reduce-ai-api-costs\/\">reducing AI API costs<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"model-identifiers\">Picking model identifiers<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The model string you pass to the editor is interpreted by your endpoint, not by the editor itself. Common identifiers across most OpenAI-compatible relays are:<\/p>\n\n\n\n<figure class=\"wp-block-table is-style-stripes\"><table><thead><tr><th>Family<\/th><th>Example model strings<\/th><\/tr><\/thead><tbody><tr><td>OpenAI GPT<\/td><td><code>gpt-4o<\/code>, <code>gpt-4o-mini<\/code>, <code>o1-mini<\/code>, <code>o1-preview<\/code><\/td><\/tr><tr><td>Anthropic Claude<\/td><td><code>claude-3-5-sonnet<\/code>, <code>claude-3-haiku<\/code>, <code>claude-3-opus<\/code><\/td><\/tr><tr><td>Google Gemini<\/td><td><code>gemini-1.5-pro<\/code>, <code>gemini-1.5-flash<\/code><\/td><\/tr><tr><td>Open weights<\/td><td><code>llama-3.1-70b<\/code>, <code>mistral-large<\/code>, <code>qwen-coder-32b<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">If a relay exposes its own aliases, those are usually listed in the dashboard. The simplest rule: copy the model string exactly as the relay documents it, and never assume the editor knows what your relay supports \u2014 it sends the string verbatim.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"verifying\">Verifying the connection works<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Before trusting the setup with real code work, send a known request through the same base URL the editor is using. This is the same flow used in our general <a href=\"https:\/\/qoraapi.com\/blog\/how-to-integrate-ai-api\/\">AI API integration guide<\/a>, and it catches almost every configuration mistake in a few seconds:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>curl https:\/\/qoraapi.com\/v1\/chat\/completions \\\n  -H \"Authorization: Bearer YOUR_KEY\" \\\n  -H \"Content-Type: application\/json\" \\\n  -d '{\n    \"model\": \"gpt-4o-mini\",\n    \"messages\": [{\"role\": \"user\", \"content\": \"Reply with the word OK.\"}]\n  }'<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">A correct response looks like a normal OpenAI chat completion object. If the editor still fails after this succeeds, the problem is on the editor side \u2014 most often a cached config, a base URL with a trailing slash, or a model name the editor pre-validated against OpenAI&#8217;s own list rather than your relay&#8217;s.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"pitfalls\">Common pitfalls and how to fix them<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n\n<li><strong>Trailing slash in the base URL.<\/strong> Most editors append <code>\/chat\/completions<\/code> automatically. A trailing slash on <code>https:\/\/qoraapi.com\/v1\/<\/code> turns into <code>https:\/\/qoraapi.com\/v1\/\/chat\/completions<\/code>, which usually 404s. Strip it.<\/li>\n\n<li><strong>Wrong model identifier.<\/strong> Editors often pre-fill the model picker with OpenAI&#8217;s defaults. If you typed <code>gpt4o<\/code> instead of <code>gpt-4o<\/code>, the relay will reject it. Copy the string from the relay&#8217;s model list.<\/li>\n\n<li><strong>Streaming stopped working.<\/strong> Some relays stream by default; some require a feature flag. If your editor streams against OpenAI but not against your relay, check whether the relay documents streaming support for that model.<\/li>\n\n<li><strong>Tool use or function calling fails.<\/strong> The OpenAI-compatible contract covers most of tool use, but coverage varies. If a tool call is silently dropped, try a smaller request first to isolate whether it is the tool or the model.<\/li>\n\n<li><strong>Editor still uses OpenAI after saving.<\/strong> Restart the editor, or fully quit and reopen. Some tools cache the config in memory until relaunch.<\/li>\n\n<li><strong>Account-wide key vs project-scoped key.<\/strong> A leaked editor key on a developer&#8217;s laptop can drain an account. Use the relay&#8217;s per-key spend caps and rotation to limit blast radius.<\/li>\n\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"checklist\">Setup checklist<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n\n<li>Verify the endpoint responds to a simple <code>curl<\/code> request with the same key the editor will use.<\/li>\n\n<li>Set the base URL to the OpenAI-compatible path (no trailing slash).<\/li>\n\n<li>Use a model identifier exactly as the relay documents it.<\/li>\n\n<li>Save and, if needed, restart the editor so it picks up the new config.<\/li>\n\n<li>Ask one trivial question to confirm chat works end-to-end.<\/li>\n\n<li>Try one tool-using task (a file edit, a terminal command) to confirm tools work.<\/li>\n\n<li>Set a spend cap on the key at the relay so a runaway loop cannot drain the account.<\/li>\n\n<li>Pin a smaller model for autocomplete to keep inline suggestion costs low.<\/li>\n\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"faq\">Frequently asked questions<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"faq-cursor-custom-api\">Does Cursor support a custom OpenAI endpoint?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Yes. Cursor has an &#8220;Override OpenAI Base URL&#8221; setting (alongside the OpenAI API Key field) that points the editor at any OpenAI-compatible endpoint. Combined with the &#8220;Custom Models&#8221; entry, you can use any model the relay supports without leaving Cursor.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"faq-cline-custom\">How do I use a custom API endpoint with Cline?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">In Cline&#8217;s settings, choose API Provider \u2192 <strong>OpenAI Compatible<\/strong>, then fill in the base URL (e.g. <code>https:\/\/qoraapi.com\/v1<\/code>), your API key, and the model ID the relay exposes. Cline will use the same endpoint for chat, tool calls, and agent mode.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"faq-continue-config\">Where is Continue&#8217;s config file?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The default location is <code>~\/.continue\/config.json<\/code>. Add entries under <code>models<\/code> with <code>provider: \"openai\"<\/code>, <code>apiBase<\/code> pointing at your endpoint, <code>apiKey<\/code> for the bearer token, and <code>model<\/code> set to the relay&#8217;s model string. Continue picks up changes on save.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"faq-same-key\">Can I use the same key across all three tools?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Yes. As long as the endpoint is OpenAI-compatible and the key is valid against it, the same bearer token works in Cursor, Cline, and Continue simultaneously. This is one of the main reasons to route through a single relay rather than juggling separate provider accounts.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"faq-switch-models\">How do I switch models inside the editor?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Change the model string in the editor&#8217;s model picker \u2014 Cursor, Cline, and Continue all keep the same base URL and key and only swap the model identifier. That single field decides whether you are talking to GPT, Claude, Gemini, or an open-weights model behind the relay.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"faq-safe-key\">Is it safe to paste my API key into an editor?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Editor settings files live on your local disk. Treat them like an <code>.env<\/code> file: do not commit them, do not share them, and rotate the key if a laptop is lost. On the server side, prefer per-tool scoped keys with spend caps so a leak cannot drain the account.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"faq-streaming\">Will streaming and function calling still work?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Usually yes \u2014 well-built OpenAI-compatible relays support both. If something breaks, isolate it: first verify a plain <code>curl<\/code> chat completion works, then enable streaming in the editor, then enable tool use. Each step pins down where the gap is.<\/p>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<p class=\"wp-block-paragraph\">Wiring Cursor, Cline, and Continue to a custom API endpoint is mostly a configuration change \u2014 a base URL, a key, and a model string. Once that is in place, the rest of the editor&#8217;s capabilities continue to work because the contract is the one OpenAI defined. If you want a single endpoint that gives you GPT, Claude, and Gemini under one key, create an account at <a href=\"https:\/\/qoraapi.com\/\" target=\"_blank\" rel=\"noopener\">qoraapi.com<\/a> and paste the base URL and key into whichever editor you use today.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Related reading<\/h3>\n\n\n<ul class=\"wp-block-list\"><li><a href=\"https:\/\/qoraapi.com\/blog\/openai-compatible-api-guide\/\">OpenAI-Compatible API: One Key for GPT, Claude &#038; Gemini<\/a><\/li><li><a href=\"https:\/\/qoraapi.com\/blog\/how-to-integrate-ai-api\/\">How to Integrate an AI API into Your Application<\/a><\/li><li><a href=\"https:\/\/qoraapi.com\/blog\/model-context-protocol-mcp\/\">What Is the Model Context Protocol (MCP)? Connect Your AI to Real Tools<\/a><\/li><li><a href=\"https:\/\/qoraapi.com\/blog\/ai-mobile-integration\/\">Integrating AI APIs into Mobile Apps<\/a><\/li><\/ul>\n\n","protected":false},"excerpt":{"rendered":"<p>Step-by-step setup for pointing Cursor, Cline and Continue.dev at an OpenAI-compatible endpoint: the exact settings fields, a verification curl, common pitfalls, and a model fan-out checklist.<\/p>\n","protected":false},"author":1,"featured_media":68,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3],"tags":[5,6,9,7,11],"class_list":["post-69","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-ai-api","tag-ai-api","tag-api-gateway","tag-developer-tools","tag-developers","tag-software-development"],"_links":{"self":[{"href":"https:\/\/qoraapi.com\/blog\/wp-json\/wp\/v2\/posts\/69","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/qoraapi.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/qoraapi.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/qoraapi.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/qoraapi.com\/blog\/wp-json\/wp\/v2\/comments?post=69"}],"version-history":[{"count":2,"href":"https:\/\/qoraapi.com\/blog\/wp-json\/wp\/v2\/posts\/69\/revisions"}],"predecessor-version":[{"id":238,"href":"https:\/\/qoraapi.com\/blog\/wp-json\/wp\/v2\/posts\/69\/revisions\/238"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/qoraapi.com\/blog\/wp-json\/wp\/v2\/media\/68"}],"wp:attachment":[{"href":"https:\/\/qoraapi.com\/blog\/wp-json\/wp\/v2\/media?parent=69"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/qoraapi.com\/blog\/wp-json\/wp\/v2\/categories?post=69"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/qoraapi.com\/blog\/wp-json\/wp\/v2\/tags?post=69"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}