--- title: "AreaOps Developers — API, MCP Server, CLI, and OpenAPI Spec" description: "Build on AreaOps: a Model Context Protocol server with 17 tools, a documented REST API, an official CLI, and a published OpenAPI 3.1 contract. Authentication, rate limits, endpoints, and worked examples." url: https://areaops.app/developers --- AreaOps Developer Platform # The AreaOps API for developers and AI agents The AreaOps API is a territory-intelligence API for home-services brands. It scores every US ZIP code 0–100 for demand fit from US Census ACS data, reads and edits the service areas your team already manages, and renders shareable territory maps. It is available three ways: a Model Context Protocol server for AI agents, a REST API described by a published OpenAPI 3.1 contract, and an official command-line tool. [Get an API key](/sign-up) [OpenAPI spec](/openapi.json) [llms.txt](/llms.txt) ## Quickstart 1. **Create an account and an API key.** Sign up, then mint a key in Settings → Developers & API. Keys are prefixed `aoa_live_` and are shown once. Agent access requires an active subscription or trial. 2. **Point your agent at the MCP server.** One command with the Claude Code CLI: `claude mcp add --transport http areaops https://areaops.app/api/mcp \ --header "Authorization: Bearer aoa_live_your_key_here"` 3. **Ask it a territory question.** “Score the top 20 roofing ZIP codes in Atlanta and tell me which ones my Peachtree brand is already in.” The agent calls `areaops_score_territory` and `areaops_compare_brand_to_scores`, and answers from real data. ## Authentication Every authenticated request carries a bearer token in the `Authorization` header. API keys work on the MCP endpoint; the REST agent endpoints additionally accept a signed-in AreaOps browser session. Public endpoints need no credential at all. ``` curl https://areaops.app/api/mcp \ -H "Authorization: Bearer aoa_live_your_key_here" \ -H "Content-Type: application/json" \ -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' ``` Treat a key like a password: it carries your organization's brand scope and write entitlement. Revoke and re-mint from Settings → Developers & API at any time. ## MCP server AreaOps runs a real Model Context Protocol server over stateless Streamable HTTP at `POST https://areaops.app/api/mcp`. The discovery document at [/api/mcp/info](/api/mcp/info) is public and needs no key — point an agent directory or an answer engine at it. ### Client configuration ``` { "mcpServers": { "areaops": { "type": "http", "url": "https://areaops.app/api/mcp", "headers": { "Authorization": "Bearer aoa_live_your_key_here" } } } } ``` ### Read tools | Tool | What it returns | | --- | --- | | `areaops_get_capabilities` | Account standing: plan, write entitlement, brand scope, per-call limits. | | `areaops_list_brands` | The org's brands with approved and pending territory counts. | | `areaops_score_territory` | Rank ZIPs for a vertical in a metro or explicit ZIP list. | | `areaops_get_brand_territory` | A brand's ZIPs, paged, filterable by state, flag and review status. | | `areaops_compare_brand_to_scores` | Keep / cut / add read on a footprint against vertical scores. | | `areaops_query_targeting` | The org's own targeting scores with demographic filters. | | `areaops_get_zip_profile` | Everything AreaOps knows about one ZIP code. | | `areaops_discover_zips` | Expansion candidates by radius or city. | | `areaops_list_pending_review` | Read-only visibility into the human review queue. | | `areaops_get_brand_health` | Coverage and review-status health for a brand. | | `areaops_get_activity` | The agent's own change trail. | | `areaops_list_share_links` | Public share links the org has minted. | | `areaops_render_territory_map` | A rendered PNG map of a territory. | ### Write tools Every write requires an explicit `confirm: true`, an active write entitlement, and passes your key's brand scope. Added ZIPs land in a human review queue rather than going live, and removals are undo-snapshotted in the same transaction. There is deliberately no tool that approves a review. | Tool | Behavior | | --- | --- | | `areaops_apply_territory` | Add ZIPs to a brand. Lands in the human review queue, never live. | | `areaops_remove_territory` | Remove ZIPs from a brand. Undo-snapshotted in the same transaction. | | `areaops_share_territory_map` | Mint a public, expiring share link for a territory. | | `areaops_revoke_share_link` | Revoke a share link the org owns. | ## Command-line tool The official AreaOps CLI scripts the same API from a shell or a CI job, with `--json` on every command so an agent can pipe the output straight into a tool call. ``` npm install -g areaops # or: npx areaops export AREAOPS_API_KEY=aoa_live_your_key_here areaops zip 30309 # public ZIP profile, no key needed areaops score roofing --metro atlanta-ga --limit 20 areaops mcp-config # print MCP client JSON areaops openapi > areaops-openapi.json # fetch the published contract ``` ## REST API and OpenAPI contract The full contract is published as OpenAPI 3.1 at [/openapi.json](/openapi.json) (and [/api/openapi.yaml](/api/openapi.yaml)). Every operation carries a unique `operationId`, a description, typed parameters and a typed response schema, so it drops straight into an LLM function-calling definition without hand-editing. ### Public endpoints — no key required - `GET /api/healthz` — service health. - `GET /api/mcp/info` — MCP discovery document. - `GET /api/public/zip/{zip}` — citation-safe ZIP profile. - `GET /api/public/vertical/{vertical}` — vertical summary. - `GET /api/public/data-study` — the flagship data study, also available as CSV. ### Worked example ``` curl "https://areaops.app/api/public/zip/30309" { "zipCode": "30309", "city": "Atlanta", "state": "GA", "scores": [{ "vertical": "roofing", "score": 71 }], "signals": { "ownerOccupiedRate": 0.42, "medianHomeValue": 512300 } } ``` ## Rate limits and usage Every API response carries standard rate-limit headers so a client can self-throttle without guessing. AreaOps sends the IETF `RateLimit` and `RateLimit-Policy` structured fields, the widely-supported `X-RateLimit-*` triple for older clients, and `Retry-After` on every 429. ``` RateLimit: "default";r=57;t=42 RateLimit-Policy: "default";q=60;w=60 X-RateLimit-Limit: 60 X-RateLimit-Remaining: 57 X-RateLimit-Reset: 42 Retry-After: 42 # on 429 only ``` | Endpoint | Limit | Scope | | --- | --- | --- | | `POST /api/mcp` | 60 / minute, 2,000 / day | Per API key, durable (Postgres-backed) | | `GET /api/mcp/info` | 60 / minute | Per IP, unauthenticated discovery | | `GET /api/public/*` | 100 / minute | Per IP, unauthenticated | | `GET /api/shared/:token/*` | 240 / minute | Per IP — recipients are external | | `GET /api/map-context` | 240 / minute | Per IP, cached 24h | Separately from rate limits, agent tool calls consume metered units against your plan's monthly allowance: 1,000 units are included, most tools cost 1 unit, `areaops_score_territory` costs 10, and map rendering and sharing cost 5. Exhausting the allowance returns a 402 carrying `code: usage_quota_exceeded` and the current meter. ## Errors REST errors are JSON objects with a human-readable `error` and, where one exists, a machine-readable `code` to branch on. MCP errors use the JSON-RPC error envelope. | Status | Meaning | | --- | --- | | 400 | Invalid request body or parameters. | | 401 | Missing, malformed, or revoked credential. | | 402 | No active subscription, or the monthly unit allowance is exhausted. | | 404 | No data for the requested market, ZIP, or token. | | 406 | No representation matches the request's `Accept` header. | | 429 | Rate limited. Wait `Retry-After` seconds. | | 503 | Usage recording unavailable; the call was not served. | ## Machine-readable resources - [/openapi.json](/openapi.json) — the OpenAPI 3.1 contract for the whole public and agent surface. - [/llms.txt](/llms.txt) — what AreaOps is, when to use it, and how an agent should call it. - [/llms-full.txt](/llms-full.txt) — every public page inlined as one markdown document. - [/api/mcp/info](/api/mcp/info) — MCP discovery, unauthenticated. - [/sitemap-index.xml](/sitemap-index.xml) — every indexable URL. - [/docs](/docs) — the API reference index. [Start a free trial](/sign-up) [Talk to us](/contact)