FarcasterGateway

Farcaster Agent Catalog

Nothing routes to an agent the catalog doesn't know.

The catalog is the tenant-scoped system of record for every agent Farcaster fronts. Routing, observability, and the x402 gate don't take a URL — they take a catalog ID and resolve it at request time. Registration is the one step nothing else can skip.

shipped Apache-2.0 /v1/agents

The record

One required field. Everything else is layered on.

Registering an agent needs a name. The upstream, the credential, the protocol, the price, the rate limit — all optional, all addable later. An entry with no upstream yet is a legal, useful record: you can inventory what exists before you decide 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 immutable for the life of the record. It is the handle every other surface uses — which is why it never changes, even when the name, the upstream, or the credential does.

The mechanic

You never write status. It's derived.

Most catalogs let you flip a record to "active" and hope the configuration agrees. Farcaster computes status from the configuration itself, so the field cannot disagree with reality: an agent is not active because someone said so, it is active because it has somewhere to send traffic.

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 deliberately not a status. It's a separate boolean, so pausing a misbehaving agent blocks invocation without touching its configuration or its derived state — and unpausing restores exactly what was there, with nothing to reconstruct from memory.

Credentials

The secret is never on the agent.

An agent record holds a credential_ref, not a credential. The secret goes in once through /v1/credentials, is envelope-encrypted at rest under a per-tenant key, and is injected into upstream calls at invocation time. Reading it back is not a permission you can be granted — the endpoint does not return 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"
}

It is never echoed to the caller and never written to an invocation record. The separation is also what makes rotation survivable: replace the credential, and every agent pointing at it picks up the new secret without a single record being edited.

When you get it wrong

The refusals are part of the design.

What an API does on the bad path tells you more than what it does on the good one. These are the catalog's, and each one is a decision rather than a default.

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 free. All of it.

Registering, listing, updating, soft-deleting, credential storage, and per-tenant isolation are Apache-2.0 and stay that way. What we sell sits above the catalog, not inside it.

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

The full boundary →

Next

The catalog says what exists. Routing says where it goes.

Once an agent has an upstream, the proxy takes over — transactional and streaming invocation, SSRF-guarded, with the credential injected on the way out.