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.
How it works
Section titled “How it works”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.
Add and manage keys
Section titled “Add and manage keys”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.
Provider not listed
Section titled “Provider not listed”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.
Status of each key
Section titled “Status of each 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.
| Status | Meaning |
|---|---|
| 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. |
kenari balance backup
Section titled “kenari balance backup”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.
Fallback order
Section titled “Fallback order”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.
Use it as usual
Section titled “Use it as usual”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.
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"} ] }'Models that are not in kenari’s catalog
Section titled “Models that are not in kenari’s catalog”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-0731byok/groq/llama-4-70bbyok/ollama-local/qwen3:32b| Segment | Rule |
|---|---|
byok | literal, lowercase |
<provider> | your key’s provider type, not its label. Matched case-insensitively |
| the rest | forwarded 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.
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"} ] }'Three steps from key to answer
Section titled “Three steps from key to answer”- Open /byok, click Tambah, pick the provider, paste the key, Simpan. The key is checked immediately.
- On the new key’s row, click Lihat model, find the model you want, copy its full id.
- Paste that id into your application’s model field.
When something goes wrong
Section titled “When something goes wrong”| Case | Status | Code |
|---|---|---|
| Incomplete id format | 400 | byok_malformed_model_id |
| No key for that provider | 400 | byok_provider_not_found |
| Keys exist but none are usable (disabled or cooling down) | 403 | byok_credential_unavailable |
| The API key carries a spend limit | 403 | byok_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.
API keys with a spend limit
Section titled “API keys with a spend limit”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.