Scopes and rate limits
Scopes and rate limits
Section titled “Scopes and rate limits”Authenticating
Section titled “Authenticating”Three tiers, in precedence order on /mcp:
- API key —
Authorization: Bearer pm_<key>. Carries scopes + a per-key rate limit from the key record. - OAuth 2.1 token —
Authorization: Bearer pmt_<token>(see auth). Grantsread+underwrite. A successful OAuth token exchange also mints apm_API key (scopedread,underwrite), returned once in the token response asapi_key. - Anonymous — keyless beta, read-only, 30 calls/min/IP.
The private operator rail (/api/state, /api/deals, /api/run-listings, /api/keys) stays behind the shared write secret and is not issued externally.
Scopes
Section titled “Scopes”| Scope | Grants |
|---|---|
read |
All read tools + endpoints: search, tract reports, market pulse, comps, map-pins, viewport-context, property history. |
underwrite |
deep_underwrite_asset / underwrite, get_comps / comps (the compute-heavy tools). |
write-state |
The write tools — save_favorite_property, update_underwriting_preset, create_strategy_profile, add_note — and /api/me/* mutations. |
webhooks |
Register signed-webhook delivery targets on strategy profiles (see webhooks). |
A tool called without its scope returns forbidden_scope (HTTP 403 on REST, isError on MCP). UI-controller tools (update_map_filters, fly_to_location, highlight_properties) are available to any caller and append to the sync stream.
Rate limits
Section titled “Rate limits”| Principal | Limit | Mechanism |
|---|---|---|
| Anonymous | 30 requests/min/IP | Sliding per-minute window per IP. |
| API key | rpm_limit (default 60) |
Per-key token bucket (KV sliding window keyed by the key prefix). |
Exceeding a limit returns rate_limited (HTTP 429). Wait ~60s. Higher limits are a function of the key’s rpm_limit, not a different set of numbers.
Usage metering and cost
Section titled “Usage metering and cost”Every authenticated tool call is metered per key, per tool, per day, with cost weights that reflect the work each triggers (a comps call fans out to live county fetches):
| Tool | Cost units |
|---|---|
get_comps / comps |
5 |
deep_underwrite_asset / underwrite |
3 |
search_investment_inventory and all others |
1 |
Metering protects the compute; billing remains deferred behind an explicit product gate (the beta is free).
Issuing keys
Section titled “Issuing keys”Keys are issued by the operator today via POST /api/keys (write-secret gated). The plaintext pm_<key> is shown once — store it; only its SHA-256 hash is retained. Request body: { "scopes": "read,underwrite", "rpm_limit": 60, "email": "…" }. Self-serve issuance rides the existing OAuth consent flow (see above).
