Skip to content
kenari.

BYOK (bring your own key)

BYOK means bring your own key: register your own provider key, then use it through kenari. Model usage through your own key does not touch your balance. You still get one endpoint, one kn-... key, and the same analytics as regular usage. Per-search web search fees still apply the same way they do on metered requests.

When you send a request with a kn-... key, kenari tries your BYOK key first for the requested model. Provider charges go to your own provider account. Model usage still appears in analytics with zero cost, so tokens and requests are visible as usual.

Open BYOK in the dashboard. Each provider you use appears as a card with rows in dispatch priority order.

  • Add API key: button at the top right of the page.
  • Periksa (Check): button on each row, runs a fresh check against the provider.
  • Edit, Disable/Enable, Delete, Raise priority, Lower priority: all live in the row action menu at the end. Priority controls live in the menu because they only matter when a card has more than one key.

When a key is added, kenari saves it and then runs the check in the background. The result is written to the row and drives the status line. Pressing Periksa runs the same check synchronously and updates the row immediately.

Choose Custom, fill in a provider name, the base URL of an OpenAI-compatible or Anthropic-compatible endpoint, and pick the API kind (OpenAI-compatible or Anthropic-compatible). Paste your key.

Each row has a single status on one line. The dot before the label uses three colors: brick for a key that will not serve requests, green for a key that will, ink-soft when neither can be promised yet.

StatusMeaning
Aktif (Active)The key passed the check and is ready to serve. The line may add “used 2 hours ago” or “never used”.
Jeda (Paused)The key is temporarily out of service, usually because of rate limiting, a provider incident, or exhausted quota. It recovers on its own after the cooldown ends.
Gagal (Failing)The provider rejected the key. Requests will not flow through it until you fix it.
Status tidak diketahui (Status unknown)The provider cannot be probed automatically, or the custom base URL does not expose a models endpoint. Such a key still flips to Aktif once a real request has actually succeeded through it.
Belum diperiksa (Not checked yet)A new key waiting for the first check to complete.
Nonaktif (Disabled)The key was turned off through the Disable action. It serves no requests until you turn it back on.

Each provider card has a Cadangan saldo kenari (kenari balance backup) toggle in its header. The toggle adds one kenari entry at the lowest priority as a backup. When the toggle is on and every key you have for that provider fails or hits a limit, kenari continues the request through its paid pool and charges your balance at PAYG rates. When the toggle is off, the request fails with your keys.

When the toggle is on but your balance is too low, the card shows a brick-colored warning next to the toggle and an Isi saldo (Top up) link to the top-up page. The backup cannot cover requests until balance is added, because the paid pool rejects requests when balance is insufficient.

Keys in a card are tried top to bottom. The first healthy key is used, and if it fails or hits a limit, kenari moves to the next one. The kenari entry, when present, is always last.

This priority order is the only built-in default. For per-step control (different model at each step, additional conditions), open Rute and build a named route. The route is sent as the model value, exactly like calling a normal model.

There is no code change. Send requests with a kn-... key as usual, and kenari chooses your BYOK key first when the requested model is available there.

Terminal window
curl https://kenari.id/v1/chat/completions \
-H "Authorization: Bearer kn-..." \
-H "Content-Type: application/json" \
-d '{
"model": "step-3-7-flash",
"messages": [
{"role": "user", "content": "Halo"}
]
}'

The above works for models in kenari’s catalog. To reach any model your own provider serves, including ones the catalog does not carry, send the model id with a byok/ prefix. No route to build, no model to register.

byok/<provider>/<model-id-at-your-provider>

Examples:

byok/openrouter/deepseek/deepseek-v4-flash-0731
byok/groq/llama-4-70b
byok/ollama-local/qwen3:32b
SegmentRule
byokliteral, lowercase
<provider>your key’s provider type, not its label. Matched case-insensitively
the restforwarded to your provider verbatim, slashes and colons included, case preserved

Requests on this path do not draw down your balance. The usage row is still recorded, at Rp 0.

Terminal window
curl https://kenari.id/v1/chat/completions \
-H "Authorization: Bearer kn-..." \
-H "Content-Type: application/json" \
-d '{
"model": "byok/openrouter/deepseek/deepseek-v4-flash-0731",
"messages": [
{"role": "user", "content": "Halo"}
]
}'
  1. Open /byok, click Tambah, pick the provider, paste the key, Simpan. The key is checked immediately.
  2. On the new key’s row, click Lihat model, find the model you want, copy its full id.
  3. Paste that id into your application’s model field.
CaseStatusCode
Incomplete id format400byok_malformed_model_id
No key for that provider400byok_provider_not_found
Keys exist but none are usable (disabled or cooling down)403byok_credential_unavailable
The API key carries a spend limit403byok_spend_capped_key

If you hold several keys for one provider, kenari walks them in the priority order set on /byok, the same fallback as above.

An API key that carries a spend limit cannot use BYOK models. A spend limit counts the Rupiah kenari records, and BYOK usage records Rp 0, so the limit would never be reached and would not bound anything.

To bound BYOK usage on a key you share, use a token limit. Tokens are the unit BYOK actually consumes.