# Center for developers and agents

> Center exposes booked real-world service outcomes to agents — refundable until completed,
> receipts forever after. RWA made ownership programmable. Center makes completion programmable.

HTML: https://trycenter.com/developers

This is the machine twin of the HTML page. Status labels here are generated from the same
source the page renders from, so they always match.

## Status vocabulary

- **LIVE** — Built and serving today.
- **PREVIEW** — Specced and in build; request access. Shapes may change before GA.
- **SPECCED** — Designed in a committed spec. Not built yet.

## What Center sells

Not listings, not introductions, not leads. The unit is a CONFIRMED BOOKED APPOINTMENT with a
real local service professional: real availability, the price the pro actually published, and
quotes captured verbatim. Job money stays consumer-to-pro and off-platform; Center charges the
agent for the booked outcome.

## Three ways in

### Human developers — PREVIEW
Two HTTP contracts. Book takes a published price in one round-trip. Quote buys a round of real
bids when nobody can price the job blind. Both answer `402 Payment Required` with a fee
envelope before doing any work, and both are idempotent by construction. Not callable without an
early-access key.

### Agent builders — LIVE
Every public pro page ships a machine-readable agent card at `/{handle}/agent.json` naming
that pro's real services and prices, a Streamable-HTTP MCP server, and a web-chat endpoint.
This is live today — you can add a working tool before the platform contracts open.

### Autonomous agents — LIVE
Start at https://trycenter.com/ai-info.md for what Center is, canonical URLs, and explicit
anti-invention guardrails. Then https://trycenter.com/llms.txt indexes everything else.

## Quickstart (no key required)

```
curl https://trycenter.com/llms.txt
curl https://trycenter.com/ai-info.md
curl https://trycenter.com/developers.md
curl https://trycenter.com/developers/contracts/book.json
curl https://trycenter.com/developers/contracts/quote.json
```

## Book and Quote

An accepted bid is a listed price of one — for that buyer, valid until it expires. That is why there are two names and one mechanic.

No fee schedule is signed, so `feeMinor` is `null` in the examples rather than an invented
number. Fees: TBD.

## Contract: Book — the price is published — PREVIEW

`POST /v1/agent/bookings` · `Authorization: Bearer <agent_key>`

One round-trip purchase against live inventory. It is bookable because the pro published a price
for it — that published price IS the test, which is why the contract is called Book. If the pro
has not opted in, has no published price, or the slot is not genuinely open, it is absent from
their price list rather than padded with a "call to check".

Request:

```json
{
  "idempotencyKey": "agt_9f2c1e07",
  "businessId": "biz_7d31",
  "serviceId": "svc_a410",
  "durationMin": 90,
  "startAt": "2026-09-01T17:00:00Z",
  "principal": {
    "name": "Alex",
    "phone": "+16025550111",
    "attestPrincipalControl": true
  },
  "notes": "gate code 4411"
}
```

Response `201`:

```json
{
  "bookingId": "bk_5c22",
  "status": "held",
  "startAt": "2026-09-01T17:00:00Z",
  "endAt": "2026-09-01T18:30:00Z",
  "service": {
    "name": "Water heater replacement",
    "durationMin": 90,
    "priceMinor": 22000
  },
  "business": {
    "name": "Desert Plumbing",
    "areaLabel": "Scottsdale"
  },
  "feeMinor": null,
  "priceMinor": 22000,
  "confirmation": {
    "pending": "principal_confirm",
    "holdExpiresAt": "2026-09-01T17:30:00Z"
  },
  "receipt": {
    "jws": "eyJhbGciOiJFUzI1NiIs"
  },
  "links": {
    "status": "/v1/agent/bookings/bk_5c22"
  }
}
```

One round-trip buys the slot and the receipt; it does not skip the consumer. `held` becomes
`confirmed` only when the principal confirms on their own phone. No confirmation means the hold
lapses at `holdExpiresAt` and the fee auto-refunds.

Errors:

- `400` — `attestPrincipalControl` was not `true`, or a duration the pro does not list
- `402` — payment required; the fee envelope is in the body
- `409` — `slot_taken`; filled between read and commit. A paid-but-stale retry auto-refunds
- `422` — `idempotency_conflict`; same key, different payload

Idempotency: `idempotencyKey` is required and immortal per agent account. Replay returns the
same body — same bookingId, same receipt — never a second booking or charge.

## Contract: Quote — request a quote — PREVIEW

`POST /v1/agent/quotes` · `Authorization: Bearer <agent_key>`

For work nobody can price blind. Center calls several pros in parallel, discloses it is an AI on
the first breath, captures each answer verbatim, and returns bids carrying the pro's own pricing
and an expiry. Most rounds complete in 15–45 minutes. Fees: TBD.

Request:

```json
{
  "idempotencyKey": "agt_qte_41d8",
  "need": "smart toilet installation",
  "quantity": "4",
  "deadline": "before Sep 1",
  "areaLabel": "Scottsdale",
  "maxPros": 3,
  "principal": {
    "name": "Alex",
    "phone": "+16025550111",
    "attestPrincipalControl": true
  },
  "webhookUrl": "https://agent.example/cb",
  "media": [
    "https://agent.example/bathroom1.jpg"
  ]
}
```

Response `202`:

```json
{
  "quoteId": "qte_88a1",
  "status": "collecting",
  "prosContacted": 3,
  "resultsBy": "2026-09-01T19:10:00Z",
  "links": {
    "poll": "/v1/agent/quotes/qte_88a1"
  }
}
```

Terminal result — the webhook POST body and the poll body are the SAME document:

```json
{
  "quoteId": "qte_88a1",
  "status": "complete",
  "bids": [
    {
      "bidId": "bid_01",
      "pro": {
        "businessName": "Desert Plumbing",
        "areaLabel": "Scottsdale",
        "verified": [
          "gbp_connected"
        ]
      },
      "disposition": "quoted",
      "quoteVerbatim": null,
      "quotePerUnitVerbatim": "650 a toilet",
      "quoteTotalVerbatim": "2,600",
      "availabilityVerbatim": "week of the 24th",
      "capturedAt": "2026-09-01T18:41:12Z",
      "expiresAt": "2026-09-02T18:41:12Z",
      "book": {
        "businessId": "biz_7d31"
      }
    },
    {
      "bidId": "bid_02",
      "pro": {
        "businessName": "Canyon Rooter",
        "areaLabel": "Scottsdale",
        "verified": []
      },
      "disposition": "interested_no_quote",
      "quoteVerbatim": null,
      "quotePerUnitVerbatim": null,
      "quoteTotalVerbatim": null,
      "availabilityVerbatim": "call back Thursday",
      "capturedAt": "2026-09-01T18:44:02Z",
      "expiresAt": "2026-09-02T18:44:02Z"
    },
    {
      "bidId": "bid_03",
      "disposition": "no_answer"
    }
  ],
  "receipt": {
    "jws": "eyJhbGciOiJFUzI1NiIs"
  }
}
```

In that example three pros were called: one quoted, one was interested without quoting, one
never answered. A disposition that is not a win is reported as itself — never a fake success,
never an invented figure. Bid pricing is the pro's own words. Each bid carries `expiresAt`;
past it, re-quoting is a new paid round.

Complete disposition taxonomy — never invent one outside it:
`quoted`, `interested_no_quote`, `declined`, `no_answer`, `machine`, `failed`

Accepting a bid is a plain book request carrying `acceptedBidId`, so a round that converts is
never dearer than booking cold.

## Discovery — LIVE

- `/llms.txt` — LIVE — the agent-readable index
- `/ai-info.md` — LIVE — official briefing for assistants (HTML twin: `/ai-info`)
- `/{handle}/agent.json` — LIVE — per-pro agent card: priced services, MCP server, web-chat endpoint
- Per-pro MCP server — LIVE — Streamable HTTP, JSON-RPC; address in the agent card under `interface.mcp`
- JSON-LD on public pro pages — LIVE — real published prices, never a fabricated rating
- One OpenAPI document covering both contracts — SPECCED

## Settlement and trust

- **Completion-gated refunds** — SPECCED — fees are captured at purchase but earned only when the job completes, in the same transaction that marks it complete. No-show, cancellation, or a lapsed hold auto-refunds to the instrument that paid.
- **Signed receipts** — SPECCED — a compact JWS over the receipt claims, verifiable offline against a published key set. Completion or refund mints a fresh receipt; the history is append-only.
- **The 402 payment envelope** — SPECCED — the first lane is a prepaid balance or invoice reference, no crypto dependency. Native x402 settlement is designed and gated behind a founder decision. It is NOT live.
- **What we verify** — LIVE — key possession, possession of the principal's phone at booking time, and a paid deposit. We cannot verify that your principal consented, that they are human, or the scope of your brief; those fail closed. An attestation is recorded as evidence of what was claimed, never as proof it was true.
- **The consumer is never a side effect** — LIVE — before verification the only message we send a supplied number is the transactional confirmation for the booking just made. STOP outranks everything. An agent request is consent for the transaction and nothing else.

## Request early access — LIVE

The contracts are preview, so access is granted by a human. Ask at
https://trycenter.com/developers#early-access or email hello@trycenter.com.

## Security

Report a vulnerability: https://trycenter.com/.well-known/security.txt
