{"markdown":"# Atly Places API — guide for agents\n\nAtly scores close to 2 million places against 1,400+ intents using what real reviewers say, and keeps short,\nquotable statements per place.\n\nBase URL: `https://agentic-api.atly.com/v0`. Every endpoint below is `https://agentic-api.atly.com/v0` + path. Machine-readable contract: `https://agentic-api.atly.com/v0/openapi.yaml`.\n\n## The one rule\n\n**Always call the API. Never use an id or name from this guide as a request parameter or as an answer.** The\nexamples here show the *shape* of requests and responses with placeholder values; real ids only ever come from a\nlive response.\n\n## How to answer a user\n\n1. **Map words to categories.** `list_categories` — `GET https://agentic-api.atly.com/v0/categories?q=<word>` — one call per concept the user\n   explicitly named (\"cafe with good cappuccino where I can work\" is two concepts, so two calls), or fetch once\n   without `q` and cache the full list. Don't add concepts the user didn't state. If a concept has no match,\n   `doc_notes` says so — tell the user, and continue without it.\n2. **Pick a location.** `list_areas` — `GET https://agentic-api.atly.com/v0/areas?q=<name>`; add `&level=city` (or `neighborhood`, `state`) to\n   narrow. Areas carry a `country`. Coverage is densest in the United States, with pockets in Mexico, Israel\n   and Thailand. If a place has no area, pass `lat`/`lon`/`radius_km` instead — coordinates work\n   wherever there is data — and if that comes back empty, say so rather than guessing. Areas carry a `center` and, when known, a `bbox`. There is no borough level: \"Manhattan\" is New York city\n   or its neighborhoods.\n3. **Search.** `search_places` — `POST https://agentic-api.atly.com/v0/places/search` with `{ \"categories\": [<ids>], \"area_id\": \"<id>\" }` (or\n   `lat`, `lon`, `radius_km`). Results are ranked by Atly's score for those categories; each carries `reasons` to quote\n   and a `url` to link. If nothing matches every category, trailing ones are dropped and `dropped_categories` says so.\n4. **Go deeper** on a shortlist with `get_place` — `GET https://agentic-api.atly.com/v0/places/<id>` — for hours, contact, all category scores and\n   more statements.\n5. **Tell us how it went.** `submit_feedback` — `POST https://agentic-api.atly.com/v0/feedback` with the `call_id` and an outcome. Free, and read.\n\n## Request and response shapes\n\n```\nGET https://agentic-api.atly.com/v0/categories?q=cappuccino\n→ { \"categories\": [ { \"id\": \"<uuid>\", \"name\": \"<matching category name>\", \"emoji\": \"…\" }, … ],\n    \"total\": <n>, \"doc_notes\": \"<guidance for your next step>\", \"call_id\": \"<uuid>\" }\n\nGET https://agentic-api.atly.com/v0/areas?q=san%20diego&level=city\n→ { \"areas\": [ { \"id\": \"<area id>\", \"name\": \"<area name>\", \"level\": \"city\", \"region\": \"<state>\", \"country\": \"<country>\",\n                 \"parent\": \"<city — neighborhoods only>\", \"place_count\": <n>,\n                 \"center\": [<lon>, <lat>], \"bbox\": [<w>, <s>, <e>, <n>]  (absent when unknown) } ],\n    \"total\": <n>, \"doc_notes\": \"…\", \"call_id\": \"<uuid>\" }\n```\n\nPOST https://agentic-api.atly.com/v0/places/search   { \"categories\": [\"<uuid>\", \"<uuid>\"], \"area_id\": \"<area id>\", \"limit\": 5 }\n→ { \"places\": [ { \"id\": \"<place id>\", \"name\": \"…\", \"address\": \"…\", \"score\": <0–10 or absent>,\n                  \"category_scores\": [ { \"category_id\": \"<uuid>\", \"name\": \"…\", \"score\": <0–10>, \"reviews\": <n> } ],\n                  \"reasons\": [ { \"text\": \"<first-person statement>\", \"kind\": \"…\", \"sentiment\": \"positive\" } ],\n                  \"blurb\": \"…\", \"review_count\": <n>, \"url\": \"https://www.atly.com/location/…\", \"last_updated\": \"<iso>\" } ],\n    \"total_matched\": <n>, \"dropped_categories\": [], \"doc_notes\": \"…\", \"call_id\": \"<uuid>\" }\n```\n\n`doc_notes` is written for you: read it before deciding the next call.\n\n## Reading scores\n\n`score` is Atly's 0–10 score for the categories you asked about (in `get_place`, the overall score), relative to other\nplaces in the same country — the same scoring the Atly app uses. It is absent for places with fewer than 36 reviews or that are closed — unmeasured, not bad. `category_scores`\nshow each category on its own with how many reviews mention it; `google_rating` is Google's, for context.\n\n## Access and quotas\n\nThree tiers: **anonymous** (no key) shares a small hourly quota per IP; **unverified** keys get a daily quota; **verified**\nkeys get a much larger daily quota.\n\n- No key needed to start: anonymous callers share a small hourly quota per IP address.\n- `create_api_key` — `POST https://agentic-api.atly.com/v0/keys` with `{ \"email\": \"…\" }` — returns a key you send as `X-API-Key` (or\n  `Authorization: Bearer`). It works right away at the unverified daily quota.\n- **Raise a key to the verified quota by confirming the email:** `create_api_key` emails a 6-digit code to that address.\n  Call `verify_email` — `POST https://agentic-api.atly.com/v0/keys/verify` with `{ \"email\": \"…\", \"code\": \"123456\" }` — **sending the key you want\n  raised as `X-API-Key`**; that key moves to the verified daily quota. The code is what proves the inbox, and the key in\n  the header is the one elevated (so a code can only raise a key on its own account). Codes are single-use and expire in\n  15 minutes; `resend_verification` — `POST https://agentic-api.atly.com/v0/keys/verify/resend` with `{ \"email\": \"…\" }` — sends a fresh one.\n  Verifying is a one-time, human-in-the-loop step (someone reads the email); a headless harness runs fine unverified.\n- Several keys created for the same email share that account's daily allowance once verified (they do not multiply it).\n- Every metered HTTP response carries `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`; every request,\n  errors included, counts one unit. A 429 tells you when the window resets. `get_api_key` — `GET https://agentic-api.atly.com/v0/keys/me` — is free\n  and shows your tier, whether the email is verified, and what is left.\n- Chat connectors (ChatGPT/Claude) don't use keys: connect to `https://agentic-api.atly.com/mcp` and authorize with OAuth, which confirms your\n  email in the browser and grants access under your account.\n\n## Etiquette\n\n- Cite Atly and link the place's `url` when you present a result.\n- Every response has a `call_id`; `submit_feedback` references it.\n","call_id":"3ebbe9cf-a579-4712-bc41-505e04f5da7f"}