Zerker Agent Catalog
Every agent is registered before it is routed.
The catalog is the tenant-scoped record of every agent behind Gateway. Routing, observability, and the x402 gate take a catalog ID, not a URL, and resolve it at request time.
The record
One required field.
Registering an agent needs a name. Upstream, credential, protocol, price, and rate limit are optional and can be added later. An entry with no upstream is still useful: inventory what exists before deciding what routes.
Register
$ curl localhost:8080/v1/agents \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "support-bot",
"upstream_url": "https://api.example.com"
}'
What comes back
201 Created
{
"id": "agt_019842c1-7f3e-7a91-b8d0-3c6e2f19ab44",
"name": "support-bot",
"status": "active",
"protocol": "http",
"created_at": "2026-07-14T09:22:41Z"
}
The agt_ ID is server-assigned, a UUIDv7, and never changes. Every other surface uses it as the handle, even when the name, upstream, or credential changes.
The mechanic
status is derived, never written.
Zerker computes status from the configuration. An agent is active because it has an upstream to send traffic to, not because someone set a flag.
| State | What produces it | Invocable |
|---|---|---|
pending |
No upstream_url set — catalogued, not yet wired |
No |
active |
upstream_url is set |
Yes |
inactive |
DELETE — soft, the record is kept for audit |
No |
Suspension is not a status. It is a separate flag. Pausing an agent blocks calls without touching its configuration, and unpausing restores it exactly.
Credentials
Credentials never live on the agent.
An agent record holds a credential_ref, not a credential. The secret goes in once through /v1/credentials, is envelope-encrypted under a per-tenant key, and is injected at call time. No endpoint returns it.
$ curl /v1/credentials/cred_019842c4-1a08-7bd2-9f41-77c0e5b3d612 { "id": "cred_019842c4-1a08-7bd2-9f41-77c0e5b3d612", "name": "upstream-api-key", "last4": "9f2a", ← metadata only; the secret is not a field "created_at": "2026-07-14T09:22:41Z" }
The secret is never returned to a caller or written to a record. Rotate it once, and every agent that references it picks up the new value.
When you get it wrong
What the catalog refuses.
How the catalog answers on the bad path.
| What you did | What you get | Why |
|---|---|---|
Registered a name already used in your tenant |
409 |
Names are unique per tenant, so a name is safe to use in your own tooling |
| Asked for an ID belonging to another tenant | 404 — never 403 |
A 403 would confirm the record exists. The catalog will not tell you that. |
| Invoked an agent with no upstream | Refused — it is pending |
A catalogued agent is not a routable one until you say where traffic goes |
| Deleted a credential an agent still references | 409 |
Deleting it would break invocation silently, at request time, in production |
Sent PATCH with a field omitted |
Unchanged |
Updates are tri-state — absent, null, and a value are three
different instructions, so "clear this" is never a guess
|
Sent PATCH with a field set to null |
Cleared |
Where the line falls
The catalog is open source.
Registering, listing, updating, soft-deleting, credential storage, and per-tenant isolation are Apache-2.0. What we sell sits above the catalog.
| Capability | Tier |
|---|---|
The full /v1/agents and /v1/credentials API |
OSS |
| Envelope-encrypted, per-tenant credential isolation | OSS |
| Governance and a control plane across tenants | Commercial |
Next
The catalog says what exists. Routing says where it goes.
Once an agent has an upstream, the proxy takes over: transactional and streaming calls, SSRF checks, and credential injection on the way out.