AI Agents Self-Register for API Keys and Provision Keys
Agents can self-register for a BazaarLink API key via POST /api/v1/agents/register, pay via OKX x402, or receive spend-capped keys from a Management API Key.
Updated 2026-10-01. BazaarLink has reopened agent self-registration. An agent can get its own API key by calling
POST https://bazaarlink.ai/api/v1/agents/register. For centralized control with budget caps and expiry times, you can still use a Management API Key to issue keys programmatically. This article covers both approaches.
The problem: manual intervention is the bottleneck for scaling AI agents
In most AI agent architectures there is a bottleneck that is easy to overlook: issuing API keys. Every time a new agent instance is deployed, someone has to log in, create a key, copy and paste it, and set the environment variable. When the number of agents grows from one to ten to hundreds, this process becomes a real obstacle.
There are two solutions: have the agent call the registration endpoint itself to get a key, or have a human authorize once and let a program issue keys afterward. Both are described below. Pick one based on your scenario, or use both together.
Approach A: the agent registers and gets a key itself
The registration endpoint is on the website host bazaarlink.ai (not the api. gateway host). It requires no login and no Authorization header. A single POST returns a key:
curl -X POST https://bazaarlink.ai/api/v1/agents/register \
-H "Content-Type: application/json" \
-d '{"name": "research-agent"}'
Accepted fields: name (required), description, referral_code. The 201 response includes api_key, credits, claim_token (valid for 7 days, so a human can claim the account later), upgrade_url, free_model: "auto:free" and base_url. The api_key appears only once, so store it immediately.
import httpx
from openai import OpenAI
r = httpx.post("https://bazaarlink.ai/api/v1/agents/register", json={"name": "research-agent"}, timeout=30)
r.raise_for_status()
data = r.json()
client = OpenAI(api_key=data["api_key"], base_url=data["base_url"]) # base_url is https://api.bazaarlink.ai/v1
resp = client.chat.completions.create(
model=data["free_model"], # auto:free
messages=[{"role": "user", "content": "Hello!"}],
)
import OpenAI from "openai";
const res = await fetch("https://bazaarlink.ai/api/v1/agents/register", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ name: "worker-1" }),
});
const data = await res.json();
const client = new OpenAI({ apiKey: data.api_key, baseURL: data.base_url });
An account registered this way is an unpaid account. It uses the existing free model mechanism (auto:free) and is subject to the general rate and daily limits. There is no separate free quota for agents. The number of registrations from the same IP or cloud provider is capped; exceeding the cap returns HTTP 429, so retry according to Retry-After.
To use paid models: pay with OKX at registration (x402)
If an agent needs paid models, it can add credit at registration: POST https://bazaarlink.ai/api/v1/agents/register/x402, with name and amountUsd. The first request returns HTTP 402 with the payment options (network eip155:196, asset USD-T0, payTo). The agent signs the payment, then resends the request once with the X-PAYMENT header. The payment is USD₮0 on X Layer, settled through OKX's x402 facilitator. The payer does not need OKB for gas (signing with OKX Wallet or any EVM wallet works).
The platform charges a top-up service fee, so the credited amount is lower than the amount paid. The response lists paidUsd, creditedUsd and serviceFeeUsd separately. To add more credit later, call POST https://bazaarlink.ai/api/x402/topup with that account's API key.
Approach B: one management key, then everything programmatic
The flow has only two steps:
- A human does this once: after logging in, go to /keys and create a Management API Key. This key is used to manage other keys; it is not used to call models.
- The program does this many times: your orchestrator or CI/CD uses this management key to call
POST /v1/keys, issue a dedicated key for each agent, and set the spend cap and expiry time at the same time.
A standard sk-bl- key cannot call this endpoint. It must be a management key. This separation of permissions is intentional.
curl https://api.bazaarlink.ai/v1/keys \
-H "Authorization: Bearer $BAZAARLINK_MANAGEMENT_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "ResearchAgent-v2",
"limit": 30,
"limit_reset": "monthly",
"expires_at": "2027-01-01T00:00:00Z"
}'
The key field in the response is the only chance to see the plaintext key. The system stores only a hash afterward, and even you cannot retrieve it later. Hand it to the agent or write it into your secret manager right away.
Complete implementation example: Python
import os
import httpx
from openai import OpenAI
MGMT_KEY = os.environ["BAZAARLINK_MANAGEMENT_KEY"] # Created by a human, stored only in the orchestrator
BASE = "https://api.bazaarlink.ai/v1"
def provision_agent_key(agent_name: str, monthly_usd: float) -> str:
"""Issue a dedicated key for one agent, with a monthly spend cap."""
r = httpx.post(
f"{BASE}/keys",
headers={"Authorization": f"Bearer {MGMT_KEY}"},
json={"name": agent_name, "limit": monthly_usd, "limit_reset": "monthly"},
timeout=30,
)
r.raise_for_status()
return r.json()["key"] # Shown only once
# The orchestrator issues the key when the agent starts
api_key = provision_agent_key("ResearchAgent-v2", 30.0)
client = OpenAI(api_key=api_key, base_url=BASE)
response = client.chat.completions.create(
model="auto:free",
messages=[{"role": "user", "content": "Hello!"}],
)
TypeScript / Node.js example
import OpenAI from "openai";
const BASE = "https://api.bazaarlink.ai/v1";
async function provisionAgentKey(name: string, monthlyUsd: number) {
const res = await fetch(`${BASE}/keys`, {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.BAZAARLINK_MANAGEMENT_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ name, limit: monthlyUsd, limit_reset: "monthly" }),
});
const data = await res.json();
return data.key as string;
}
const apiKey = await provisionAgentKey("worker-1", 10);
const client = new OpenAI({ apiKey, baseURL: BASE });
const out = await client.chat.completions.create({
model: "auto:free",
messages: [{ role: "user", content: "Hello!" }],
});
What you can bind at issuance time
| Field | Purpose |
|---|---|
limit + limit_reset | Spend cap (US dollars) and reset period; accepts daily / weekly / monthly |
expires_at | Expiry time (ISO string, must be in the future), suitable for temporary test keys |
organizationId / teamId / orgMemberId | Bind the key to an organization, team or specific member so that costs are assigned directly to that party |
keyType | Defaults to standard; use management only when issuing another management key |
Once the limit is reached, requests with that key receive HTTP 402, and other agents are not affected. This is the mechanism that keeps a runaway agent from burning through the entire account.
Use cases: which architectures benefit most
1. Multi-Agent systems (AutoGen, CrewAI, LangGraph)
Each role (Researcher, Writer, Critic) gets one key and one budget. Usage is tracked separately, and if something goes wrong you revoke only that key.
2. Automated deployment pipelines (CI/CD)
Issue a new key with expires_at on each deployment. The key expires automatically when the deployment finishes, so you do not need to keep shared long-term credentials in a secret manager.
3. AI features in SaaS products
Issue each end customer's agent its own key. Usage metering and cost allocation then come naturally.
4. Development and testing
Issue temporary keys for local testing with an expiry of one day. They expire after testing without any manual cleanup.
auto:free: get the workflow running first
Once you have a key, you can use auto:free directly. It routes to the currently available free models, so you can run the whole chain before adding credit (still subject to the general rate and daily limits). When you need paid models, add credit. The program does not need to change.
Integration with mainstream agent frameworks
Note: Fully compatible with the OpenAI SDK
BazaarLink uses a standard OpenAI-compatible API. Any framework that uses the OpenAI SDK, including LangChain, LlamaIndex, AutoGen, CrewAI, LangGraph and Semantic Kernel, can integrate directly by setting
base_urlandapi_key.
FAQ
Q: Should I choose self-registration or management-key issuance?
Self-registration is the simplest: the agent makes one POST and gets a key. It suits a single agent or a quick trial, but the account is unpaid and has no configurable spend cap or expiry time. Management-key issuance requires a human to authorize once. After that, every key can have a spend cap and an expiry time bound at issuance, which suits multi-agent setups and production. You can use both together.
Q: Where should the management key be stored?
Only in the secret manager of the orchestrator or CI system. Do not hand it out to individual agents. An agent should receive only its own standard key, which has a cap.
Q: How do I track each agent's usage?
The Logs page in the dashboard shows the model, token count and cost of each call, grouped by key. The key name is the agent name you gave when issuing it. Organization users also get a monthly report split by member, which can be exported as CSV.
Q: Can I revoke keys programmatically?
Yes. The same management endpoints provide GET /v1/keys to list, PATCH to update, and DELETE to delete. This is useful for automatic cleanup when an agent's lifecycle ends.
Q: Is it suitable for production?
Yes. When keys are issued with a management key, you control key issuance, every key has a cap and an optional expiry time, and the blast radius of a problem is limited to a single agent. Self-registration suits a single agent or trial runs; for production, issuing keys with a management key is recommended.
TWD billing · Taiwan invoices · leading AI models · OpenAI-compatible API