API keys
Create a Fiber API key, pass it on every request, give each key its own credit limit, and manage sandbox keys, expiration, and revocation.
We authenticate the public API with API keys. One key lets you call search,
enrichment, MCP V2/Core, and the SDKs. Same org, same credits, same
chargeInfo. MCP V3 signs you in with OAuth instead. Create live keys in the
dashboard; pass them in the request (or a header); revoke them when a script
or teammate no longer needs access.
Live keys start with sk_live_. Sandbox keys start with sk_test_ and do
not charge credits on operations that support sandbox. The plaintext secret
is shown once at creation, so copy it then; later you only see a prefix.
What it does
- Mint a live key at fiber.ai/app/api (name it,
copy the secret, store it as
FIBER_API_KEY). - Send that key on every call — body/query
apiKey, orx-api-key/Authorization: Bearer. - Keep a sandbox key for local and CI work so tests do not draw down credits.
- List, limit, expire, or revoke keys with the API-key operations below (use a live key for those). The dashboard creates and revokes keys; per-key credit limits are set through the API today.
Chargeable product calls still consume credits on live keys. Key management itself is free. See Billing & credits.
Create and store a key
Sign in, open fiber.ai/app/api, and create a key.
Give it a name you will recognize later (prod-enrichment, local-dev). The
full secret appears once. After that the dashboard shows the prefix,
created date, and a revoke action.
export FIBER_API_KEY=sk_live_...Put the export in your shell profile or a secrets manager. Never commit the
value. For MCP server configs, prefer "x-api-key": "${env:FIBER_API_KEY}"
over pasting the secret into chat — see MCP for AI agents.
The first live key has to come from the dashboard (or sign-up). After you have one, you can mint additional sandbox keys from the API.
Passing the key
Include the key in one of these ways. If both body/query and a header are set, body/query wins.
| Where | When to use |
|---|---|
apiKey in the JSON body | POST from the SDKs and most app code |
?apiKey= query string | GET routes (credits, some enums) |
x-api-key header | MCP clients, HTTP MCP configs, proxies |
Authorization: Bearer … | Hosts that only expose a Bearer field (Codex CLI, some gateways) |
SDK calls take apiKey on the request object, not a constructor-level Bearer
token. Request schemas live on @fiberai/sdk/zod — parse before you call:
import { getOrgCredits } from "@fiberai/sdk";
import type { GetOrgCreditsData } from "@fiberai/sdk";
import { zGetOrgCreditsData } from "@fiberai/sdk/zod";
const creditsRequest: GetOrgCreditsData = zGetOrgCreditsData.parse({
query: { apiKey: process.env.FIBER_API_KEY! },
});
const credits: Awaited<ReturnType<typeof getOrgCredits>> =
await getOrgCredits(creditsRequest);
const available: number | undefined = credits.data?.output[0]?.available;Prefer a header over putting the secret in the URL:
curl -H "x-api-key: $FIBER_API_KEY" https://api.fiber.ai/v1/get-org-creditsA key in a shared chat transcript can leak. For Claude Code, Cursor, Codex, and anything that writes config to disk, put the key in a header or env var, not in the prompt.
Live vs sandbox
Live (sk_live_) | Sandbox (sk_test_) | |
|---|---|---|
| Where you create it | fiber.ai/app/api | createSandboxApiKey |
| Credits | Chargeable operations draw the org balance | No credit charge when sandbox is available |
| Use it for | Production apps, key management, real lookups | Local runs and CI against sandboxed operations |
Sandbox keys still have to be registered keys for your org — a random
sk_test_ string will not authenticate. Successful sandbox responses set the
x-fiber-sandbox: true header and return chargeInfo.method: "free".
Sandbox responses are made-up but consistent sample data: fictional
people and companies on example.com domains that line up across endpoints,
so a search result can be fed into a reveal and come back with matching
details. Sandbox covers search, natural-language search, typeaheads, Kitchen
Sink, contact reveal (including batch), live fetch, reverse lookups, email
and phone validation, social media lookup, company rankings and revenue,
reference lists, Tracker, Yelp, creating sandbox keys, and API request
history.
Not every public operation is sandboxed yet. Those return 501 with
"Sandbox mode is not yet available for this endpoint." Use a live key for
list / limit / expire / reset / revoke — those management calls are not
sandboxed. Creating a sandbox key is itself sandboxed.
Managing keys from the API
The API key tag is the spec. Each
operation also has agent markdown at /ai-docs/<operationId>.md. All of these
are free. Call them with a live key.
| Job | Operation | HTTP |
|---|---|---|
| List keys (metadata only) | getAllApiKeys | POST /v1/api-keys |
| Inspect one key | getCurrentApiKey | POST /v1/api-keys/current |
| Mint a sandbox key | createSandboxApiKey | POST /v1/api-keys/create-sandbox |
| Set a credit ceiling | updateApiKeyLimit | POST /v1/api-keys/limit |
| Set expiration | updateApiKeyExpiration | POST /v1/api-keys/expiration |
| Reset lifetime usage | resetApiKeyUsage | POST /v1/api-keys/usage/reset |
| Revoke | revokeCurrentApiKey | POST /v1/api-keys/revoke |
List and get return id, name, prefix, expiration, credit ceiling, credits
used, and whether the key is revoked — never the secret. Listing skips
revoked keys unless you pass includeRevoked: true. Revoke is permanent; mint
a replacement before you kill a key that is still in use. Targeting OTHER
plus targetApiKey acts on a different key in the same org (pass its prefix,
id, or the raw key); the default is the key you authenticated with. Key
management allows 30 requests per minute.
Expiration
operation | Takes | Effect |
|---|---|---|
set | expiresAt (a future ISO 8601 time) | Expire at an exact time |
extend / prepone | days (a whole number) | Move the expiration later or earlier |
remove | — | Never expire |
{ "apiKey": "sk_live_...", "operation": "extend", "days": 30 }You cannot create a live sk_live_ key through the API. That stays on the
dashboard.
Per-key credit limits
We let you give any key its own credit limit: a cap on how many credits that one key can spend, separate from your organization's balance. Use it to hand a key to a contractor, a cron job, or a customer without handing over the whole org balance.
- Keys are unlimited by default. A new key can spend whatever the org has until you set a limit.
- The limit is lifetime, not monthly. It counts every credit the key has spent since creation (or since its last usage reset) and does not reset with your billing cycle. For a monthly budget, see the recipe below.
- It sits on top of the org balance. A key under its limit still needs the organization to have credits. An empty org returns 402 no matter what the key's limit is.
Limits are managed through the API today, with any live key in the org. Every call is free.
Check a key's limit and usage
Inspect one key returns the key you authenticate with; List keys returns every key in the org. Each key carries two fields:
| Field | Meaning |
|---|---|
maxCredits | The key's limit. null means no limit |
creditsUsed | Credits the key has spent since creation or its last usage reset |
maxCredits - creditsUsed is what the key has left.
curl -X POST https://api.fiber.ai/v1/api-keys/current \
-H "x-api-key: $FIBER_API_KEY" -H "Content-Type: application/json" -d '{}'Set, change, or remove a limit
Call Set a credit ceiling with one of six operation values:
operation | Takes | Effect |
|---|---|---|
set | credits (0 or more) | Pin the limit to an exact number |
increase / decrease | credits (more than 0) | Move the current limit up or down |
multiply / divide | factor (more than 0) | Scale the current limit |
remove | — | No limit; the key can spend the whole org balance |
By default the call acts on the key you authenticate with. Pass
"target": "OTHER" plus targetApiKey (the other key's prefix, id, or raw
value) to change a different key in the same org.
# Cap the key you're calling with at 500 credits
curl -X POST https://api.fiber.ai/v1/api-keys/limit \
-H "x-api-key: $FIBER_API_KEY" -H "Content-Type: application/json" \
-d '{"operation": "set", "credits": 500}'
# Cap a contractor's key at 200 credits
curl -X POST https://api.fiber.ai/v1/api-keys/limit \
-H "x-api-key: $FIBER_API_KEY" -H "Content-Type: application/json" \
-d '{"target": "OTHER", "targetApiKey": "sk_live_ab12", "operation": "set", "credits": 200}'
# Give it 100 more
curl -X POST https://api.fiber.ai/v1/api-keys/limit \
-H "x-api-key: $FIBER_API_KEY" -H "Content-Type: application/json" \
-d '{"target": "OTHER", "targetApiKey": "sk_live_ab12", "operation": "increase", "credits": 100}'increase, decrease, multiply, and divide do nothing on a key with
no limit, so a typo can't accidentally lock an unlimited key. Use set
first, then adjust.
Setting a limit below what the key has already spent blocks the key right away. Reset its usage if you want it to start fresh under the new limit.
What happens at the limit
Once creditsUsed reaches maxCredits, every call from that key returns
403, even if the organization still has credits:
{
"error": "API_KEY_CREDIT_LIMIT_REACHED",
"message": "This API key has reached its credit limit. Raise or remove the limit to keep using it."
}Match on error, not message. Retrying won't help. To unblock the key,
either:
- Raise the limit with
increaseor a higherset, - Remove the limit with
remove, or - Reset usage with Reset lifetime usage, which sets
creditsUsedback to 0 and keeps the limit as-is.
Other keys in the org keep working.
The limit is checked before each request, not against the cost of that request. A key at 499 of 500 credits can still run one more operation, and a large one can carry it past 500. If you need a hard ceiling, set the limit a little below your real threshold.
Recipe: a monthly budget per key
There is no automatic monthly reset yet. To get one, set the key's limit to
its monthly allowance, then reset its usage on the first of each month from a
scheduler:
# Run on the 1st of every month (cron: 0 0 1 * *)
curl -X POST https://api.fiber.ai/v1/api-keys/usage/reset \
-H "x-api-key: $FIBER_API_KEY" -H "Content-Type: application/json" \
-d '{"target": "OTHER", "targetApiKey": "sk_live_ab12"}'The key then gets a fresh allowance each month and stops at 403 if it burns through it early.
When to use a limit
- Contractors and agencies. Cap what an outside party can spend. Going over their limit stops their key, not your account.
- Cron jobs and automation. A runaway loop hits its own limit instead of draining the org.
- Per-environment budgets. Give
staginga small limit andproda large one. - Keys you hand to your customers. If you build on Fiber, mint one key per customer and cap each one at what they paid for.
- Trials. Hand out a key with a fixed allowance that stops when it's used up.
Using it effectively
- One key per environment or workload. Revoking
stagingthen does not take down production. - Export
FIBER_API_KEY. MCP, the plugin, and OpenFiber all read that name. - Cap a key when a contractor or a cron job should not be able to spend the whole org balance. See Per-key credit limits.
- More keys don't mean more throughput. Rate limits are shared by every key in your organization. See Rate limits.
- Know which error is which. Key problems and org problems return different codes:
| Status | Cause | Fix |
|---|---|---|
| 401 | No key was sent | Send the key in the body, query, or a header |
| 402 | The org is out of credits or its billing period expired | Top up or renew. See Billing & credits |
403 API_KEY_CREDIT_LIMIT_REACHED | This key hit its own credit limit | Raise, remove, or reset. See What happens at the limit |
| 403 (other) | Key is invalid, expired, or revoked, or the operation isn't on your plan | Check the key, or contact your account manager |
| 429 | Rate limit | Back off and retry. See Rate limits |
Every status and what to do about it is in Errors & status codes.
Use cases
Ship a Node or Python job. Create a live key, put it in the environment,
call @fiberai/sdk / fiberai, and trust chargeInfo on the response. Start
from SDKs.
Wire Claude, Cursor, or Codex. Same key, as an x-api-key header on MCP
V2 or Core. Chat UIs that only offer OAuth should use MCP V3 instead — no key.
Walkthrough: MCP.
Keep CI off the credit balance. Authenticate with a live key, mint a sandbox key over the API, then call operations that support sandbox. If an operation is not sandboxed yet, you get 501 — switch that call to a live key or skip it in CI.
Give a team or workload its own budget. Mint a key per environment, team, or script and set each one's ceiling. A runaway batch job then burns its own allowance and stops at 403 instead of draining the organization's balance. Read each key's remaining budget with Inspect one key, and raise the ceiling from your automation when a team needs more.
Credits
Creating, listing, updating, and revoking keys is free. Calls you make with
a live key bill like any other operation — chargeInfo is authoritative.
Billing & credits.
Related: Build with Fiber · SDKs · MCP · Developing with AI agents