---
key: agentOperators
path: /agent-operators
section: integrate
priority: 0.8
title: Agent operators
description: How the person or organisation behind paying agents opens a ZadQ account, verifies the responsible person, enrols each agent with a one-time code its runtime claims, approves every delegation with a passkey, and stops, renews or kills any agent, with every payment working the same when no proof is read.
---

# Agent operators

An agent operator is the person or organisation that answers for software
that pays: an agent whose payments bind its operator and spend its funds.
Each agent carries a human-backed agent credential that names the responsible
person of your account as its accountable principal, within the bounds you
approved. A seller reading it learns one thing: an accountable, verified
principal stands behind this payment, within declared bounds. Nobody learns
who.

This page follows the dashboard at `https://zadq.app` from the account to a live
bounded agent: what your runtime does, what each approval means, the seats
and caps, Stop, Renew and Kill, and what happens when no proof is read. The
seller's side of the same exchange is on the
[seller integration](/docs/integrate-seller) page; the free checks a paying
agent runs on a seller are on [buyer verification](/docs/verify).

## The account

Everything runs under one account, opened at
`https://zadq.app/#/sign-up?for=agent-operator`.

- **Create your account.** The responsible person gives their name and work
  e-mail, says who we contract with (an organisation or a sole trader), accepts
  the Terms and creates a passkey. The registration signs in.
- **Sign in with your passkey** from then on. The session is a cookie the
  dashboard's own code cannot read; nothing is kept in browser storage.
- **Next steps** (`https://zadq.app/#/account/next/agent-operator`) is the account's
  start page. Each step ticks itself from the account's state and links to its
  page; the step to do now carries the one action.

A wallet is never a login. An account that opened with a wallet before
passkeys adds a passkey at its next sign-in; the wallet then stays on the
account as a payTo binding, which signs only the writes that touch that
payTo address.

## From the account to a live agent

The steps, in the order Next steps shows them:

1. **Verify the responsible person.** Identity verification (KYC) runs once,
   on the identity provider's page, inside the issuer's boundary; no
   document is asked in the dashboard. The account keeps the session handle,
   the grade and the reuse window, never a document or a date of birth. One
   verification backs every product of the account until its reuse window
   closes; after that, you verify again.
2. **Choose a plan by seats.** A seat is one active agent. The plans come
   from the catalogue the dashboard reads, with no amount on them. Activating
   the product needs a passkey that supports the PRF extension; the Account
   page adds one.
3. **Add your invoicing details.** Legal name, registered address, and the EU
   VAT number or national tax number, before any payment.
4. **Pay the entry fee on the hosted checkout.** One checkout on the billing
   provider's page carries the plan's seats and the one-off entry fee; it
   comes back to the dashboard, and the product reads active once the
   provider's signed confirmation lands. An invoiced customer finds the fee
   on its next invoice, and the product is active meanwhile. Amounts live on
   the checkout page and in your operator agreement.
5. **Create an enrolment and give its code to your runtime.** See
   [Enrolment](#enrolment).
6. **Approve the delegation with your passkey.** See
   [Approvals](#approvals). Once your runtime reports the agent registered,
   it appears in Agents.

## Enrolment

An enrolment is one agent's way into a credential. You create it in
**Enrolments** with:

| Field | What it names |
| --- | --- |
| Name | The name your runtime knows the agent by, for example `trip-planner/concierge_agent` |
| Bundle | What the agent is delegated to do, chosen from the catalogue the issuer serves |
| Sellers | The counterparties the agent may pay, as `https` URLs or account identifiers in CAIP-10 form, when the bundle asks for them |
| Where | The countries the delegation covers, when the bundle asks for them |
| Limit | The most the agent may pay in one transaction, an amount and its unit, when the bundle carries one |
| Lease | How long the credential runs, within the bundle's bounds and 90 days at most; the form proposes the bundle's default |

Creating it shows a **one-time code** once: eight characters of Crockford
base32 (digits and capitals without I, L, O and U), written in two groups of
four, and a QR code of the **claim URL** `https://zadq.app/claim#<code>`, which carries
the code in its fragment. Neither is stored where it can be shown again. The
code ends after 24 hours if no runtime claims it; create a new enrolment then.

Your runtime then walks the enrolment on its own:

1. **Claim.** The runtime posts the code with a descriptor of itself (kind,
   version, instance reference) and receives a short-lived session credential
   scoped to that enrolment. A delegate approval lands in your **Approvals**.
2. **Wait.** The runtime polls the enrolment while you decide.
3. **Collect the material once.** After your approval, the next poll
   delivers the mint material exactly once; the service deletes it on
   delivery. Today the material is the agent's credential offer.
4. **Complete the issuance in its own process.** The credential is born in
   your runtime, next to the agent's key, from the responsible person's
   holder, which also lives in your own infrastructure. ZadQ holds no
   custody of either.
5. **Report.** The runtime reports the agent registered, optionally with a
   control hook (see [Kill](#stop-renew-and-kill)), or reports a failure with
   its reason code.

The enrolment reads one state at a time, and the dashboard says what is true
and what to do:

| State | What it means |
| --- | --- |
| `created` | The code waits for your runtime |
| `claimed` | Your runtime claimed it; the delegation waits in Approvals |
| `approved` | Your runtime collects the mint material on its next poll |
| `minting` | Your runtime is completing the issuance in its own process |
| `registered` | The agent is registered and listed in Agents |
| `expired` | The code ended before a runtime claimed it |
| `cancelled` | You cancelled it; nothing was minted and nothing is charged |
| `declined` | You declined the delegation; nothing was minted and nothing is charged |
| `failed` | Nothing was minted; the reason code says why, and the bundle's price line is credited |

You can cancel an enrolment until the runtime takes the material. A runtime
that missed the one-time material claims again, and you approve again;
nothing else changes.

## Approvals

**Approvals** is the responsible person's inbox. A request does nothing until
you approve it with your passkey, and it ends if you do not decide in time.
Each approval asks for a fresh passkey assertion. Three kinds arrive:

- **Delegate.** Your runtime claimed an enrolment. The request reads as one
  sentence: the agent's name, the bundle, its sellers, places and limit, the
  lease, and the price line it books. Approving books the bundle's price line
  and asks the issuer for the agent's offer.
- **Renew.** You asked to renew an agent from Agents. Approving books a lease
  year and asks the issuer to renew; your runtime completes it.
- **Present.** Your runtime asks the responsible person to prove a predicate
  to a verifier, such as an assurance grade threshold. The request carries
  the verifier's declaration (its origin, its challenge endpoint, the
  profile and the claim policy), never a challenge. Approving hands the
  declaration to the holder in your own infrastructure, which answers the
  verifier's challenge once. The result, `{session_id, request, envelope}`,
  passes through the approval once to your runtime's poll, about every
  second, and is deleted on delivery; your runtime validates it on its own
  verifier inside the challenge's ten seconds. The handshake binding is
  provisional.

A request ends in one of these states: approved, declined (nothing minted,
sent or charged), expired before you decided (the same; the runtime can ask
again), or failed, with its reason. An issuer refusal reads failed and
nothing is minted.

## Your runtime's calls

The dashboard's own calls run under the passkey session. Your runtime's calls
run under the session credential it received at the claim, sent as a bearer.
The shapes follow the platform API contract (v1.2):

| Step | Call | Answer |
| --- | --- | --- |
| Claim | `POST /v1/enrolments/claim` with `{code, runtime}` | `{enrolment_id, ...}` and the runtime's session credential |
| Wait and collect | `GET /v1/enrolments/{id}`, polled | `{state}`; once approved, `{state, mint}` exactly once, then `204` |
| Report | `POST /v1/enrolments/{id}/registered` · `POST /v1/enrolments/{id}/failed` with `{reason_code}` | the agent's id, or the failed state |
| Ask for a presentation | `POST /v1/approvals` with `{kind: "present", purpose, declaration}` | `202 {id, state, expires_at}` |
| Wait for the result | `GET /v1/approvals/{id}?wait=…` | `{state}`; once approved, `{state, result}` exactly once, then `204` |

Errors read `{error, detail}` with a stable code.

## Seats and caps

The Agents page shows three counters:

- **Seats in use**, against your plan's seats. An unclaimed enrolment holds a
  seat too.
- **The issuer's cap**: ten active agents per person. You can hold the lower
  of your seats and that cap at once.
- **Mints this hour**, renewals included, under the issuer's own hourly cap.

Reaching a limit is said on the request that met it, with its code
(`seats_exhausted`, `person_cap_reached`, `mints_per_hour_reached`); the
approval stays pending, nothing is retried behind your back and the agents
already live are unaffected. Creating, approving and renewing also wait on
the verification (`kyc_required`), the entry fee (`entry_fee_due`) and an
active product (`product_inactive`). A suspended product keeps its agents
listed and usable.

## Stop, Renew and Kill

**Agents** lists every agent your runtimes registered, with its bundle,
sellers, places, limit, lease end, runtime and state: `registered`, then
`usable` once the runtime reports its scope anchored, `expiring` near the
lease end, and the ended states `revoked` and `expired`.

- **Stop the agent.** Asks the issuer to revoke the agent's credential; it
  then presents nowhere. A seat frees up and nothing is refunded. Stopping
  needs nothing from your runtime.
- **Renew the lease.** Opens a renew approval in your inbox. The agent stays
  usable on its current credential until your runtime reports the renewed
  one; the new lease end then shows in Agents. An agent whose lease has
  ended is past renewal: enrol a new agent to continue.
- **Kill the agent.** Offered only when the runtime registered a control
  hook. The dashboard calls that hook, and the agent revokes its own
  credential with the custody your runtime holds, through the network's
  privacy relay. Without a hook, Stop is the switch.

**Withdraw consent** on the Verification page revokes everything the
responsible person's verification backs: every agent of the account stops,
enrolments in progress end, and the product waits for a new verification.
Revoked agents stay revoked.

## Graceful degradation

Every payment keeps working when no proof is read. An agent that holds no
credential, or whose credential cannot be presented, keeps paying every
seller that has not chosen to require attested agents: nothing blocks by
default. Whether a seller welcomes, prefers or requires attested agents is
that seller's own choice, and a seller that reads no proof treats the
payment exactly as before; its badge and its verdict fall back to `unknown`.

The dashboard follows the same rule. When the service is unreachable, the
pages show the last known state and retry by themselves; your agents and
their credentials keep working meanwhile, because their custody is in your
runtime.

## What the account holds

The account's name and its passkeys' public keys; the responsible person's
name and work e-mail; the invoicing details; any payTo bindings; the
verification's session handle, grade and reuse window; the product's state
and plan; the price lines' states; and for each enrolment, approval and agent
its name, bundle, parameters, lease, runtime descriptor and state, with an
activity log of reason codes. Never a document, a key, an agent's custody or
a proof kept after delivery, and nothing that tells a seller who stands
behind an agent.

Next: [buyer verification](/docs/verify) describes the free checks an agent
runs on the sellers it pays, and [agent tools and badge](/docs/tools) the
tools that run them.
