Bring your own providers
Use your own proxies, language models and captcha solvers: configuration, fallback, billing, health checks and how credentials are kept.
Kaabist buys three things on your behalf, each billed per use: proxies to reach sites from (per megabyte), language models that help heal broken locators and recognise unfamiliar pages (per token), and captcha solvers (per solve). If you already have an account with a vendor, you can register it with Kaabist and your jobs use it instead, and that item disappears from your bill.
#When to use it
Bring your own provider when:
- you already pay a proxy vendor, or need exits in a network you control (an office address a site has allow-listed, a residential pool you negotiated);
- your organisation has a contract with a model vendor, or a rule that page content may only be sent to the model you chose;
- you have a captcha-solving balance you want to use up.
Stay on the platform's providers when you have no such account: they need no configuration, pick a
proxy pool per site, and fall back automatically. Bring-your-own (BYO) providers are part of the
Developer plan and above, and need a verified payment method (403 plan_required or
403 payment_method_required otherwise).
#Supported vendors
| Kind | Vendors |
|---|---|
| Proxy | Any HTTP, HTTPS or SOCKS5 proxy (static, list, gateway), with presets for Bright Data, Oxylabs, Decodo (Smartproxy), IPRoyal and Webshare |
| LLM | OpenAI, Anthropic, Google Gemini, Azure OpenAI, and any OpenAI-compatible server |
| Captcha | 2Captcha, CapSolver |
#Registering a provider
Every provider is created with POST /v1/byo-providers and an admin key, as
{ "kind", "name", "config" }. Creating it tests it straight away:
// Credentials are write-only: sealed under your organisation's key, never returned or logged.
const provider = await kaab.byoProviders.create({
kind: "proxy",
name: `my-proxy-${Date.now().toString(36)}`,
config: { type: "static", url: proxyUrl, pool: "datacenter", country: "DE" },
});
console.log(`${provider.id}: ${provider.status} ${JSON.stringify(provider.config_public)}`);
The examples on this page use placeholders: never paste a real credential into a ticket or a chat.
#Proxies
A single endpoint:
{ "type": "static", "url": "http://USER:[email protected]:3128", "pool": "datacenter" }
A list. Each job sticks to one address for its whole run, and jobs spread across the list:
{ "type": "list", "urls": ["http://USER:[email protected]:3128", "http://USER:[email protected]:3128"], "pool": "datacenter" }
A vendor's rotating gateway. With a preset, Kaabist writes the job's country and a per-job session into the credential in that vendor's own format, so each job keeps one exit IP:
{ "type": "gateway", "vendor": "brightdata", "url": "http://brd-customer-ID-zone-ZONE:[email protected]:33335", "pool": "residential", "country": "DE" }
{ "type": "gateway", "vendor": "oxylabs", "url": "http://USER:[email protected]:7777", "pool": "residential" }
{ "type": "gateway", "vendor": "decodo", "url": "http://USER:[email protected]:7000", "pool": "residential" }
{ "type": "gateway", "vendor": "iproyal", "url": "http://USER:[email protected]:12321", "pool": "residential" }
Webshare's proxy list is fetched from its API with your key:
{ "type": "list", "vendor": "webshare", "api_key": "WEBSHARE_API_KEY", "pool": "datacenter" }
A gateway without a preset can still be steered: {country} and {session} in the URL are
filled in per job, for example http://acme-{country}-{session}:[email protected]:8000.
Proxy hosts must be public addresses. A proxy on a private network is refused (422 ssrf_blocked).
#Language models
{ "kind": "llm", "name": "openai", "config": { "vendor": "openai", "api_key": "sk-…", "model": "gpt-4.1" } }
{ "kind": "llm", "name": "claude", "config": { "vendor": "anthropic", "api_key": "sk-ant-…", "model": "claude-sonnet-5-5" } }
{ "kind": "llm", "name": "gemini", "config": { "vendor": "gemini", "api_key": "AIza…", "model": "gemini-2.5-flash" } }
{ "kind": "llm", "name": "azure", "config": { "vendor": "azure_openai", "api_key": "…", "base_url": "https://RESOURCE.openai.azure.com", "model": "DEPLOYMENT" } }
{ "kind": "llm", "name": "gateway", "config": { "vendor": "openai_compatible", "api_key": "…", "base_url": "https://llm.example.com/v1", "model": "MODEL" } }
base_url is required for Azure OpenAI and OpenAI-compatible servers. Supported models are listed
per vendor. Models marked capable heal locators and classify pages; basic models (smaller,
cheaper ones, and any model behind an OpenAI-compatible server until it is listed) are accepted and
marked unsupported_for_healing in config_public: they classify pages only. A model never decides
anything by itself: every selector it suggests is checked against the page before it becomes a
candidate.
#Captcha solvers
{ "kind": "captcha", "name": "solver", "config": { "vendor": "2captcha", "api_key": "…" } }
{ "kind": "captcha", "name": "solver", "config": { "vendor": "capsolver", "api_key": "…" } }
#Using a provider in a job
Name it in the job's (or the program's) options:
{
"program": "acme-prices",
"options": {
"proxy": { "mode": "byo", "byo_id": "byo_…", "fallback": "none" },
"llm": { "byo_id": "byo_…" },
"captcha": { "byo_id": "byo_…" }
}
}
Or set organisation defaults once in the panel (Settings → Providers), and jobs that name none
use them: proxy.mode: "byo" without a byo_id uses the default proxy, and every job uses the
default model and solver.
A job naming a provider that is failing its health checks is refused with
422 byo_provider_failing; one naming a provider of another kind, or another organisation's, with
422 validation_failed. A schedule whose provider is failing skips that run (byo_unavailable).
#What fallback means
When your proxy cannot be reached:
"none"(the default): the job fails withbyo_proxy_unreachable. Your traffic never leaves through an exit you did not choose."platform": the job continues through Kaabist's own proxies, the result carries the warningbyo_fallback_used, and that job's proxy traffic is billed at the platform's rate.
#Billing
A BYO provider removes only its own item from the job's bill: a BYO proxy makes the proxy line
zero, a BYO model the llm line, a BYO solver the captcha line. Compute is always billed. The
breakdown in meta.credits.breakdown shows each line, including the zeroed ones. You pay your
vendor directly for what they served.
#Tests and health
POST /v1/byo-providers/{id}/test tests a provider again on demand and answers
{ ok, latency_ms, detail, egress_ip? }:
- a proxy is dialled from Kaabist's egress network and fetches an echo page; the answer includes
the exit IP it saw (
egress_ip); - a model is asked to classify a small canned page;
- a solver reports its balance.
// Probes the proxy from Kaabist's egress network and stores the verdict.
const result = await kaab.byoProviders.test(provider.id);
console.log(`ok=${result.ok} latency=${result.latency_ms} ms: ${result.detail}`);
const checked = await kaab.byoProviders.get(provider.id);
console.log(`${checked.id} is ${checked.status} (checked ${checked.last_health_at})`);
Kaabist repeats the check every hour. One failure makes a provider degraded; jobs still run.
Three failures in a row make it failing: jobs naming it are refused, the event byo.unhealthy
is sent to your webhooks and your organisation's owners and admins get an e-mail. Two passes in a
row make it healthy again (byo.recovered).
When your own model fails (a refused key, an exhausted quota), healing continues without it, and
the proposal's evidence says why (byo_llm_auth_failed, byo_llm_quota_exceeded, …). When your
own solver refuses its key or runs out of balance, a job with policies.captcha: "solve" fails
with byo_captcha_auth_failed or byo_captcha_balance, because nobody but you can fix that.
#How your credentials are kept
- Credentials are write-only. Kaabist encrypts them with your organisation's key the moment they
arrive and never returns them: not in
GET, not in errors, not in logs. You can replace them withPATCH; you cannot read them back. APATCHthat changes only, say, the country keeps the stored credentials, and re-tests the provider. - The plaintext exists only inside the processes that use it: the egress gateway, and the worker or healer that calls your model or solver.
- What Kaabist learns about a site through your providers stays with your organisation: it never improves the platform-wide site profile.
- A provider cannot be deleted while an organisation default or an active schedule still uses it
(
409 byo_in_use).
#Worked example
Send a job through your own proxy and check what the bill says:
- Register the proxy as in the first snippet. The answer is the provider,
healthywhen its first test passed, with your URL nowhere in it:config_publicshowstype,poolandcountry. - Test it.
okistrueandegress_ipis your proxy's exit address, not Kaabist's. - Run a job on a product page through it:
{ "url": "https://shop.example.com/p/1", "extract": { "title": "h1" }, "options": { "max_tier": "http", "proxy": { "mode": "byo", "byo_id": "byo_…", "fallback": "none" } } } - The job succeeds, and
meta.credits.breakdown.proxyis0: you paid your vendor for those bytes, not Kaabist.
#Pitfalls
fallback: "platform"changes where your traffic exits. Choose it only when finishing the job matters more than the exit; the warningbyo_fallback_usedtells you when it happened.- One shared session per gateway. A gateway without a preset or a
{session}placeholder may rotate the exit IP mid-job, which logs a site out. Use a preset, or put{session}in the URL. - Basic models do not heal. A provider marked
unsupported_for_healingclassifies pages but never proposes a locator; pick a capable model if you rely on healing. - Failing providers block jobs. After three failed checks, jobs that name the provider are
refused and schedules skip their runs. Subscribe to
byo.unhealthyandbyo.recovered. - Deleting a provider in use. Remove it from the organisation defaults and from active
schedules first (
409 byo_in_use).
#Reference
- API: create, test, update, delete, list
- BYO provider schema, job options
(
proxy,llm,captcha) - Error codes (
byo_*), events (byo.unhealthy,byo.recovered), plans - Concepts: egress and proxies, credits and billing