{"openapi":"3.1.0","info":{"title":"AI My Site public API","version":"1","description":"Key-based API for reading a customer's ranked action plan, marking items done, and verifying fixes on the live page. Auth: Authorization: Bearer ams_... (create keys under Settings — paid plans only). WORKFLOW FOR AGENTS: 1) call listDomains and use the returned domain id — never guess ids and never pass URLs; 2) getActionPlan and implement open items in rank order; 3) after deploying a fix, verifyItems to confirm it landed; 4) completeItem to close it. Errors 401/403 are permanent — do not retry them."},"servers":[{"url":"https://app.goaimysite.com"}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"API key in the Authorization header: 'Bearer ams_...'. Keys carry scopes (action_plan:read, items:write, verify:write) enforced per endpoint."}},"schemas":{"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Machine-stable error code: unauthenticated | insufficient_scope | tier_required | invalid_input | invalid_item_id | invalid_domain_id | domain_not_found | no_domains | item_not_found | rate_limited | internal_error."},"message":{"type":"string"},"details":{"type":"object","additionalProperties":true}}}}},"Domain":{"type":"object","properties":{"id":{"type":"string","description":"Stable namespaced domain id, e.g. 'dom_12'. Always pass this id — never a URL."},"url":{"type":"string"},"name":{"type":"string","description":"Bare hostname."},"platform":{"type":"string"},"is_verified":{"type":"boolean"},"last_analyzed_at":{"type":["string","null"],"format":"date-time"}}},"ActionItem":{"type":"object","properties":{"id":{"type":"string","description":"Stable namespaced item id: 'rec_123' or 'content_456'."},"source":{"type":"string","enum":["recommendation","content_recommendation"]},"type":{"type":"string"},"priority":{"type":"string","enum":["HIGH","MEDIUM","LOW"]},"impact":{"type":"string","enum":["critical","high","medium","low"]},"effort":{"type":"string","enum":["five-minutes","paste-ready","longer-job","developer"]},"effort_label":{"type":"string"},"band":{"type":"string","enum":["do-first","this-week","later"]},"rank":{"type":["integer","null"],"description":"1-based position in the ranked queue of open items; null when closed."},"status":{"type":"string","enum":["open","completed","dismissed"]},"title":{"type":"string"},"description":{"type":["string","null"]},"page_url":{"type":["string","null"]},"current_value":{"type":["string","null"],"description":"The flagged value found by the scan."},"recommended_value":{"type":["string","null"],"description":"Copy-ready value when available."},"target_keywords":{"type":["string","null"]},"acceptance_criteria":{"type":"string","description":"Machine-checkable statement of what \"done\" looks like for this item."},"completed_at":{"type":["string","null"],"format":"date-time"}}},"VerifyResult":{"type":"object","properties":{"item_id":{"type":"string"},"verdict":{"type":"string","enum":["changed","unchanged","not_checkable"],"description":"'changed' = the live page no longer matches the flagged value (fix appears live). 'unchanged' = still matches (not deployed / cached). 'not_checkable' = no on-page signal for this item type — verify via the next full scan."},"checked_field":{"type":["string","null"]},"observed_value":{"type":["string","null"]},"flagged_value":{"type":["string","null"]},"recommended_value":{"type":["string","null"]},"page":{"type":["object","null"],"additionalProperties":true},"note":{"type":"string"}}}}},"security":[{"bearerAuth":[]}],"paths":{"/api/v1/domains":{"get":{"operationId":"listDomains","summary":"List the domains this key can access","description":"THE ENTRY POINT — always call this first. Returns each domain's stable id ('dom_12'); pass that id to getActionPlan. Do not guess ids, do not parse URLs, do not pick 'the first one' without telling the user. Requires scope 'action_plan:read'.","responses":{"200":{"description":"The accessible domains, most recently analysed first.","content":{"application/json":{"schema":{"type":"object","properties":{"api_version":{"type":"string"},"domains":{"type":"array","items":{"$ref":"#/components/schemas/Domain"}},"hint":{"type":"string"}}}}}},"401":{"description":"Missing, malformed, unknown or revoked API key. Do not retry with the same key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Key lacks the required scope (code 'insufficient_scope') or the account has no paid plan (code 'tier_required'). Do not retry — surface the upgrade to the user.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded. Retry after the Retry-After header (seconds).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/action-plan":{"get":{"operationId":"getActionPlan","summary":"Get the ranked action plan for a domain","description":"The domain's single ranked queue of fix items (open items first, rank 1 = do this first), each with acceptance criteria. Query by domain_id from listDomains — URLs are never accepted. Omitting domain_id uses the most recently analysed domain. An unknown id returns 404 with available_domains so you can recover. Requires scope 'action_plan:read'.","parameters":[{"name":"domain_id","in":"query","required":false,"schema":{"type":"string"},"description":"Namespaced domain id from listDomains, e.g. 'dom_12'."}],"responses":{"200":{"description":"The ranked action plan.","content":{"application/json":{"schema":{"type":"object","properties":{"api_version":{"type":"string"},"domain":{"$ref":"#/components/schemas/Domain"},"summary":{"type":"object","properties":{"open":{"type":"integer"},"completed":{"type":"integer"},"dismissed":{"type":"integer"},"total":{"type":"integer"}}},"items":{"type":"array","items":{"$ref":"#/components/schemas/ActionItem"}},"hint":{"type":"string"}}}}}},"401":{"description":"Missing, malformed, unknown or revoked API key. Do not retry with the same key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Key lacks the required scope (code 'insufficient_scope') or the account has no paid plan (code 'tier_required'). Do not retry — surface the upgrade to the user.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Unknown domain id (code 'domain_not_found') or no domains on the account (code 'no_domains'). The details include available_domains — pick from it, do not retry blindly.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded. Retry after the Retry-After header (seconds).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/action-plan/items/{itemId}":{"get":{"operationId":"getActionItem","summary":"Get one action-plan item","description":"Full detail for a single item by its namespaced id ('rec_123' / 'content_456'). Requires scope 'action_plan:read'.","parameters":[{"name":"itemId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The item.","content":{"application/json":{"schema":{"type":"object","properties":{"api_version":{"type":"string"},"item":{"$ref":"#/components/schemas/ActionItem"}}}}}},"401":{"description":"Missing, malformed, unknown or revoked API key. Do not retry with the same key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Key lacks the required scope (code 'insufficient_scope') or the account has no paid plan (code 'tier_required'). Do not retry — surface the upgrade to the user.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such item on this account. Do not retry.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded. Retry after the Retry-After header (seconds).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/action-plan/items/{itemId}/complete":{"post":{"operationId":"completeItem","summary":"Mark an item done (or re-open it)","description":"Marks the item implemented — uses the same persistence as the in-app action plan, so the dashboard updates too. Call verifyItems first so you only close items whose fix is live. Requires scope 'items:write'.","parameters":[{"name":"itemId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"completed":{"type":"boolean","default":true,"description":"false re-opens the item."}}}}}},"responses":{"200":{"description":"The updated item.","content":{"application/json":{"schema":{"type":"object","properties":{"api_version":{"type":"string"},"item":{"$ref":"#/components/schemas/ActionItem"}}}}}},"401":{"description":"Missing, malformed, unknown or revoked API key. Do not retry with the same key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Key lacks the required scope (code 'insufficient_scope') or the account has no paid plan (code 'tier_required'). Do not retry — surface the upgrade to the user.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such item on this account. Do not retry.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded. Retry after the Retry-After header (seconds).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/verify":{"post":{"operationId":"verifyItems","summary":"Verify fixes against the live page","description":"Fetches the customer's live page(s) and reports, per item, whether the flagged value is still present. Fast and deterministic — NOT a re-scan (scores and AI visibility update on the next scheduled scan). Only the customer's own registered site is ever fetched. Requires scope 'verify:write'.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["item_ids"],"properties":{"item_ids":{"type":"array","items":{"type":"string"},"minItems":1,"maxItems":10,"description":"Namespaced item ids, e.g. ['rec_123']."}}}}}},"responses":{"200":{"description":"Per-item verdicts.","content":{"application/json":{"schema":{"type":"object","properties":{"api_version":{"type":"string"},"results":{"type":"array","items":{"$ref":"#/components/schemas/VerifyResult"}}}}}}},"400":{"description":"Invalid request body. Fix the request — do not retry as-is.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, malformed, unknown or revoked API key. Do not retry with the same key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Key lacks the required scope (code 'insufficient_scope') or the account has no paid plan (code 'tier_required'). Do not retry — surface the upgrade to the user.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded. Retry after the Retry-After header (seconds).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/openapi.json":{"get":{"operationId":"getOpenApiDocument","summary":"This document","security":[],"responses":{"200":{"description":"The OpenAPI description of this API."}}}}}}