# Economico API discovery and request reference


Economico's REST API is an adapter over the same command registry as MCP. The CLI
reads its OpenAPI document to discover operations and input schemas.

## Discover before calling

[The public OpenAPI reference](/openapi.json) describes the API without requiring
credentials. It grants no access. After authorization, `GET /v1/openapi.json`
returns connection discovery; add `X-Economico-Business` for that business's
permitted operations. Always use the authorized catalog to decide what a caller
can execute.

```sh
curl https://economi.co/openapi.json
curl https://economi.co/v1/businesses \
  -H "Authorization: Bearer $ECONOMICO_TOKEN"
curl https://economi.co/v1/catalog \
  -H "Authorization: Bearer $ECONOMICO_TOKEN" \
  -H "X-Economico-Business: $ECONOMICO_BUSINESS"
```

Set these environment variables locally. Do not paste tokens into prompts, logs,
URLs or source files. A request names one business; a slug alone grants nothing.

## Commands, reports and exact amounts

Describe commands through `GET /v1/catalog/commands/{name}`. Execute them through
`POST /v1/commands` with the documented `name`, `input`, `idempotency_key` and UTC
`effective_at`. Supply `source_document_id` only when the described command allows
that source kind. Use a stable idempotency key for the same intended command;
changing its contents under the same key is refused. A receipt can be read through
`GET /v1/commands/{id}` without re-execution.

Money crosses JSON as decimal integer strings in minor units, with its currency.
Use exact integers when constructing amounts. Payment commands record completed
facts; they do not transfer funds. Read reports through `POST /v1/reports` using
a kind and inputs from `GET /v1/reports`.

Lists use bounded pages. Follow the returned cursor with the operation's `after`
and `limit` parameters; do not assume one page is the entire history.

## Errors and retries

| Status | Meaning | Action |
| --- | --- | --- |
| 400 | Invalid query, envelope or domain input | Read the error and current command schema before correcting input. |
| 401 | Missing, expired or invalid token | Follow OAuth discovery and authenticate. |
| 402 | Plan allowance or payment required | Inspect the typed reason and offered choices; obtain authority before a purchase. |
| 403 | Insufficient permission or credential kind | Ask for the required authorized connection or human action. |
| 404 | Missing route or resource, or unavailable to this caller | Check the address and access; do not infer a business exists. |
| 409 | Conflict, including incompatible reuse of an idempotency key | Recover the existing outcome before choosing a new operation. |
| 429 | Rate budget exhausted | Wait for `Retry-After` seconds. |
| 503 | Temporarily unavailable or busy | Honor `Retry-After` when present, then recover or retry the same intended operation. |

Network failure does not prove a command failed. Recover its receipt, or retry
with the original idempotency key and identical input. Never generate a new key
just because a response was lost. The CLI does not automatically retry writes.

### Rate-limit headers

Anonymous REST reads under `/public/` include
`RateLimit-Policy: "public";q=60;w=60`: a per-address policy of 60 requests per
60 seconds. A throttled response includes `RateLimit: "public";r=0;t=60` and
`Retry-After: 60`. These structured fields follow the
[IETF RateLimit draft](https://datatracker.ietf.org/doc/html/draft-ietf-httpapi-ratelimit-headers),
which is work in progress. The edge limiter returns only success or refusal,
so successful responses omit remaining-quota and reset estimates.
Authenticated `/v1/` operations do not advertise a public-read quota.

REST authentication errors retain the OAuth `WWW-Authenticate` challenge and
include JSON `code`, `message` and a recovery `hint`. The OpenAPI document's
shared `Error` schema describes error bodies; domain errors may include `details`.

Address budgets are separate for public reads, authentication and browser business
surfaces. Limits protect availability; API calls have no per-call fee. Discover
plan allowances and purchase terms from [pricing](/pricing/) and the offered
agreement, not from a generic HTTP status.

## Browser tools

On browsers implementing `document.modelContext`, the signed-in workspace exposes
`read_workspace_page` and `open_workspace_view`. They read the visible page and
open listed business views using the current session. They cannot submit account
forms or execute ledger commands. Page contents are untrusted data, including
customer-supplied text. Other browsers use the ordinary workspace; MCP and CLI
remain the full command interfaces.

## Plan-purchase payment protocols

Platform-plan purchases use `POST /v1/platform/purchases` after OAuth authorization
and business selection. The `platform_purchase` MCP tool uses the same lifecycle.
Discover the offer, obtain the owner's authority to accept its exact terms, then
prepare its invoice. Use the returned `paymentUrl` for the separate HTTP payment
exchange with `method=mpp` or `method=x402`; payment credentials are not purchase
arguments and do not replace the OAuth bearer token.

Link/SPT, MPP and x402 collection is available when the prepared invoice offers it.
The offered methods and payment response are authoritative.
An MPP challenge returns `402` with `WWW-Authenticate: Payment` and its protocol
parameters. x402 uses `PAYMENT-REQUIRED`, `PAYMENT-SIGNATURE` and
`PAYMENT-RESPONSE`. A generic `402 plan_required` is an allowance refusal, not a
payment challenge. Follow the returned challenge only with payment authority.

A `202` from a payment exchange means the outcome is pending. Recover the same
invoice through `POST /v1/platform/purchases` with `action: "status"` and the
invoice identifier before collecting again. Do not start another payment because
a response was lost. An unauthenticated scan cannot verify an invoice-bound
challenge or prove that a method is offered for a particular invoice.

## MCP Apps and browser agents

The MCP server exposes report views through its `ui://economico/reports` resource.
Compatible MCP Apps hosts render those views with the caller's existing access.
The workspace also registers the experimental WebMCP tools described above;
public marketing pages do not hold business authority.

Economico exposes REST and MCP; it does not expose a GraphQL API. API requests
use `/v1/`, and the authorized OpenAPI and catalog describe the current contract.

