Guides

Bring your own keys

Use your own Exa, Parallel or Keenable account through Mux.

If you already have an account with Exa, Parallel or Keenable (negotiated rates, existing credits, or a contract), you can connect your own provider key. Requests to that provider are then made with your key and billed by the provider directly. You keep Mux's unified API, fallbacks, per-key limits and usage tracking.

How it works

  1. You store a provider key for one or more of exa, parallel, keenable.
  2. When a request is served by a model from that provider, Mux calls the provider with your key.
  3. If your key fails (revoked, rate limited, out of credit at the provider), Mux retries the same model on Mux's own provider account and charges the normal list price, unless you set always_use. See below.

Provider keys are managed with a management key. They can't be set with a regular API key.

Add a provider key

PUT /v1/provider-keys/{provider}

Field Type Default Description
api_key string required Your key from the provider. 8 to 512 characters, no whitespace.
always_use boolean false If true, never fall back to Mux's shared key when yours fails.

{provider} is exa, parallel or keenable. Anything else returns 400 unknown_provider. Calling it again for the same provider replaces the stored key.

curl -X PUT https://api.getmux.io/v1/provider-keys/exa \
  -H "Authorization: Bearer $MUX_MGMT_KEY" \
  -H "Content-Type: application/json" \
  -d '{"api_key": "your-exa-key", "always_use": false}'

List and remove provider keys

curl https://api.getmux.io/v1/provider-keys \
  -H "Authorization: Bearer $MUX_MGMT_KEY"

DELETE /v1/provider-keys/{provider} returns { "deleted": true }, or 404 not_found if no key is stored for that provider. After deleting, requests to that provider are served and billed through Mux again.

Your keys are protected

  • Provider keys are encrypted at rest and are never returned by the API. Listings show only a hint, the last four characters, for example …1234.
  • To change a key, set a new one. To remove it, delete it.

Note: Mux doesn't test a provider key when you save it. A mistyped or revoked key is discovered the first time it is used, and then Mux falls back to its own account (or fails, if always_use is on). Check a new key by running a search and looking at attempts.

Fallback and always_use

With a provider key stored and always_use: false (the default), each request to that provider has up to two attempts:

  1. Your key. source: "byok".
  2. Mux's key, only if the first attempt failed. source: "platform", billed at the normal list price.

With always_use: true there is only the first attempt. If your key fails, that model fails, and if you passed a models list Mux moves on to the next model. Use always_use when you must never be billed through Mux for that provider, for example because of a data-handling agreement with the provider.

The response shows what happened:

"attempts": [
  { "model": "exa/auto", "source": "byok", "status": "error", "error": "exa 401: ..." },
  { "model": "exa/auto", "source": "platform", "status": "ok" }
],
"usage": { "cost_usd": 0.007, "results": 10, "latency_ms": 1210, "byok": false }

usage.byok is true only when your own key served the request.

Billing

  • The first 1,000,000 BYOK requests each month are free. The count is per account, per calendar month (UTC), across all providers.
  • After that, 5% of the model's list price per request, deducted from your credits. An exa/auto request for 10 results has a list price of $0.007, so the fee is $0.00035. The provider bills you separately for the search itself.
  • A failed BYOK call is refunded, and does not use up one of your free requests.
  • A fee is shown in your ledger as byok_fee.
  • BYOK fees don't count against an API key's credit limit.

When the fee applies but your balance can't cover it, the BYOK attempt is skipped. If the same request can't be served any other way either, you get 402 insufficient_credits. Within the free tier no credits are needed at all, so a BYOK request works even with a zero balance.

{
  "error": {
    "code": "insufficient_credits",
    "message": "Insufficient credits. Add credits at /v1/credits/checkout.",
    "needed_usd": 0.00035
  }
}

Not yet available

  • Validating a provider key against the provider when it is saved.

Errors

Status Code Meaning
400 unknown_provider The provider isn't exa, parallel or keenable.
400 invalid_request api_key is missing, too short or long, or contains whitespace.
403 wrong_key_type You used an API key instead of a management key.
404 not_found No key is stored for that provider (on delete).
503 byok_disabled Bring-your-own-key isn't enabled on this deployment.