{"components":{"schemas":{"Error":{"properties":{"code":{"description":"Stable machine code.","type":"string"},"detail":{"type":"string"},"error":{"description":"Human-readable message.","type":"string"},"hint":{"description":"What an agent should try next.","type":"string"}},"required":["error","code"],"type":"object"}},"securitySchemes":{"bearerAuth":{"bearerFormat":"rrk_ API key or rro_ OAuth access token","scheme":"bearer","type":"http"},"oauth2":{"description":"OAuth 2.0 authorization code + PKCE (S256); dynamic client registration at /oauth/register; discovery at /.well-known/oauth-authorization-server.","flows":{"authorizationCode":{"authorizationUrl":"https://app.rankright.dev/oauth/authorize","refreshUrl":"https://app.rankright.dev/oauth/token","scopes":{"jobs":"Run background jobs (audits, strategist, content, exports)","offline_access":"Stay connected (issue a refresh token so you are not asked again every hour)","read":"Read clients, keywords, rankings, action items, AI Visibility data and reports","write":"Change data: add clients and questions, update items, enrol AI Visibility, register webhooks"},"tokenUrl":"https://app.rankright.dev/oauth/token"}},"type":"oauth2"}}},"externalDocs":{"description":"Full API and agent guide (markdown); orientation at /llms.txt.","url":"https://app.rankright.dev/developers.md"},"info":{"description":"SEO tracking + AI Visibility (AEO) API, designed for AI agents. Bearer auth with rrk_ keys; structured error envelopes with machine codes and hints; Idempotency-Key supported on all POSTs; per-key rate limits surfaced via X-RateLimit-* headers. Operations are tagged by domain (ai-visibility, clients, search-console, ...); multi-call sequences are under x-workflows. Start at GET /api/v1/capabilities or read https://app.rankright.dev/developers.md.","title":"RankRight API","version":"1.0"},"openapi":"3.1.0","paths":{"/.well-known/oauth-authorization-server":{"get":{"operationId":"oauth_metadata","responses":{"200":{"description":"Metadata document."}},"security":[],"summary":"OAuth 2.0 authorization-server metadata (RFC 8414, public).","tags":["org-admin"]}},"/.well-known/oauth-protected-resource/api/v1/mcp":{"get":{"operationId":"oauth_protected_resource","responses":{"200":{"description":"Metadata document."}},"security":[],"summary":"Protected-resource metadata for the MCP server (RFC 9728, public).","tags":["org-admin"]}},"/api/v1/capabilities":{"get":{"operationId":"capabilities","responses":{"200":{"description":"Capabilities doc."}},"security":[{"bearerAuth":[]}],"summary":"Machine-readable API inventory."}},"/api/v1/health":{"get":{"operationId":"health","responses":{"200":{"description":"ok"}},"security":[],"summary":"Liveness check."}},"/api/v1/jobs":{"post":{"operationId":"create_job","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"},"group_id":{"description":"bulk_strategist only","type":"integer"},"kind":{"enum":["strategist","bulk_strategist","execute_tier_a","keyword_generation","blog_pipeline","fulfill_selected","autopilot","content_edit","ad_copy","prompted_edit"],"type":"string"},"meter":{"type":"boolean"},"payload":{"description":"Kind-specific. prompted_edit: {instruction (required, plain English), pages?: [wp_post_id|slug|url], dry_run?: bool, refresh?: auto|force|skip}. content_edit: {mode, pages?, instructions?, spec?}. ad_copy: {services?, areas?, \u2026}.","type":"object"}},"required":["kind"],"type":"object"}}}},"responses":{"202":{"description":"Job accepted; body has job id."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]}],"summary":"Queue a background job."}},"/api/v1/jobs/{job_id}":{"get":{"operationId":"get_job","parameters":[{"in":"path","name":"job_id","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Job record."}},"security":[{"bearerAuth":[]}],"summary":"Job status/result."}},"/api/v1/jobs/{job_id}/cancel":{"post":{"operationId":"cancel_job","parameters":[{"in":"path","name":"job_id","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Cancelled (or already terminal)."}},"security":[{"bearerAuth":[]}],"summary":"Cancel a queued/running job."}},"/api/v1/mcp":{"post":{"description":"Model Context Protocol over JSON-RPC 2.0: initialize, tools/list, tools/call, resources/*, prompts/*. Tools are the org-scoped RPCs plus list_rpcs / describe_rpc / call_rpc; same key, scope and limits as the REST API.","operationId":"mcp","requestBody":{"content":{"application/json":{"schema":{"properties":{"id":{},"jsonrpc":{"const":"2.0","type":"string"},"method":{"type":"string"},"params":{"type":"object"}},"required":["jsonrpc","method"],"type":"object"}}}},"responses":{"200":{"description":"JSON-RPC response."},"202":{"description":"Notification accepted (no body)."}},"security":[{"bearerAuth":[]}],"summary":"MCP server endpoint (Streamable HTTP, stateless).","tags":["jobs"]}},"/api/v1/rpc/add_aeo_query":{"post":{"operationId":"rpc_add_aeo_query","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"},"engine":{"default":"chatgpt","type":"string"},"org_id":{"type":"integer"},"prompt":{"type":"string"}},"required":["org_id","client_id","prompt"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"integer"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Get-or-create the recurring query row for (client, prompt). Dedup is case/punctuation-insensitive so a re-typed question maps to the same series. The question set is engine-neutral (one row per question, asked on several engines), so a row for the same prompt under any engine is reused before a new one is created \u2014 otherwise every API-engine capture would spawn a service-less duplicate.","tags":["rpc-write","ai-visibility"]}},"/api/v1/rpc/add_batch_request":{"post":{"operationId":"rpc_add_batch_request","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"batch_job_id":{"type":"integer"},"client_id":{"default":null,"type":"integer"},"context_json":{"default":"{}","type":"string"},"custom_id":{"type":"string"},"max_tokens":{"default":4096,"type":"integer"},"model":{"type":"string"},"operation":{"type":"string"},"org_id":{"default":null},"prompt_type":{"default":"text","type":"string"},"system_prompt":{"type":"string"},"user_prompt":{"type":"string"}},"required":["batch_job_id","custom_id","operation","model","system_prompt","user_prompt"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"integer"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Add a request to a batch job. `org_id` is stored so the batch result handler (running async, after current_caller is gone) can debit the right org's credits. Returns request ID.","tags":["rpc-write","billing"]}},"/api/v1/rpc/add_client":{"post":{"operationId":"rpc_add_client","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client":{}},"required":["client"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"integer"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Add a new client and return its ID. org_id comes from the Client dataclass \u2014 the web RPC layer stamps the caller's org onto it before this runs; the local CLI leaves it at the default (1 = Innersite).","tags":["rpc-write","clients"]}},"/api/v1/rpc/add_client_image":{"post":{"operationId":"rpc_add_client_image","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"image":{}},"required":["image"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"integer"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Insert a discovered image. Uses INSERT OR IGNORE for idempotency.","tags":["rpc-write","images"]}},"/api/v1/rpc/add_keyword":{"post":{"operationId":"rpc_add_keyword","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"keyword":{}},"required":["keyword"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"integer"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Add a new keyword to track","tags":["rpc-write","search-console"]}},"/api/v1/rpc/add_location":{"post":{"operationId":"rpc_add_location","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"location":{}},"required":["location"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"integer"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"add_location","tags":["rpc-write","clients"]}},"/api/v1/rpc/add_org_credits":{"post":{"operationId":"rpc_add_org_credits","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"credits":{"type":"integer"},"granted_by_user_id":{"default":null},"note":{"default":null},"org_id":{"type":"integer"},"source":{"type":"string"},"stripe_payment_id":{"default":null}},"required":["org_id","credits","source"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"integer"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Add credits to an org. Logs the grant to credit_grants for the audit trail. Returns the new balance.","tags":["rpc-write","billing"]}},"/api/v1/rpc/add_org_saml_provider":{"post":{"operationId":"rpc_add_org_saml_provider","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"allow_unsolicited":{"default":false,"type":"boolean"},"allowed_domains":{"default":null,"type":"array"},"certificate":{"default":"","type":"string"},"default_role":{"default":"viewer","type":"string"},"email_attribute":{"default":"","type":"string"},"idp_entity_id":{"default":"","type":"string"},"label":{"type":"string"},"metadata_xml":{"default":"","type":"string"},"org_id":{"type":"integer"},"sso_url":{"default":"","type":"string"}},"required":["org_id","label"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Self-serve SAML: register the organization's SAML 2.0 IdP from its metadata XML (entityID, SSO URL and signing certificate are read from it) or from those three values. Returns the provider with the SP metadata URL / ACS URL to register at the IdP; staff sign in at /login/sso.","tags":["rpc-write","org-admin"]}},"/api/v1/rpc/add_org_sso_provider":{"post":{"operationId":"rpc_add_org_sso_provider","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"allowed_domains":{"default":null,"type":"array"},"client_id":{"type":"string"},"client_secret":{"default":"","type":"string"},"default_role":{"default":"viewer","type":"string"},"hosted_domain":{"default":"","type":"string"},"issuer":{"type":"string"},"label":{"type":"string"},"org_id":{"type":"integer"}},"required":["org_id","label","issuer","client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Self-serve SSO: register the organization's OIDC identity provider (issuer URL, client id/secret from the IdP, the email domains whose staff may sign in / be provisioned into this org, and the role new staff get). The issuer's discovery document is fetched to validate it. Register https://<host>/auth/oidc/<provider_key>/callback with the IdP.","tags":["rpc-write","org-admin"]}},"/api/v1/rpc/add_page":{"post":{"operationId":"rpc_add_page","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"page":{}},"required":["page"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"integer"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Add a new page and return its ID","tags":["rpc-write","clients"]}},"/api/v1/rpc/add_service":{"post":{"operationId":"rpc_add_service","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"service":{}},"required":["service"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"integer"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"add_service","tags":["rpc-write","clients"]}},"/api/v1/rpc/add_snapshot":{"post":{"operationId":"rpc_add_snapshot","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"snapshot":{}},"required":["snapshot"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"integer"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Add a new page snapshot","tags":["rpc-write","monitoring"]}},"/api/v1/rpc/add_website_project":{"post":{"operationId":"rpc_add_website_project","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"project":{}},"required":["project"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"integer"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"add_website_project","tags":["rpc-write","clients"]}},"/api/v1/rpc/aeo_report_html":{"post":{"operationId":"rpc_aeo_report_html","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"},"month":{"default":"","type":"string"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"White-label AI Visibility report for a month as HTML: {ok, html, month, trend_ready, months}; {ok: False, error} when the month has no captures. PDF comes from the web route /clients/<id>/non-seo/report.pdf.","tags":["rpc-read","ai-visibility"]}},"/api/v1/rpc/apply_site_edit":{"post":{"operationId":"rpc_apply_site_edit","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"approved_by":{"default":"","type":"string"},"edit_id":{"type":"integer"}},"required":["edit_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"RPC entry: OM applies an approved proposal to the live site.","tags":["rpc-write","site-edits"]}},"/api/v1/rpc/approve_ad_copy_set":{"post":{"operationId":"rpc_approve_ad_copy_set","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"approved_by":{"default":"","type":"string"},"client_id":{"type":"integer"},"set_id":{"type":"integer"}},"required":["set_id","client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"RPC entry (WRITE_RPCS): OM approves a proposed, owned set for export. approved_by is REQUIRED non-empty (review M3): approval is an accountable human action, and the stamp is what the export audit trail hangs off. Only a 'proposed' set may be approved.","tags":["rpc-write","content"]}},"/api/v1/rpc/auto_resolve_push_failures":{"post":{"operationId":"rpc_auto_resolve_push_failures","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"},"note":{"default":"auto: next attempt succeeded","type":"string"},"operation":{"type":"string"}},"required":["client_id","operation"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"integer"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Mark all unresolved failures for (client, operation) as resolved. Called when a retry succeeds. Returns number of rows resolved.","tags":["rpc-write","site-edits"]}},"/api/v1/rpc/bulk_update_image_types":{"post":{"operationId":"rpc_bulk_update_image_types","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"updates":{"type":"array"}},"required":["updates"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"description":"Method-specific result."}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Bulk update image types from WordPress data. updates: list of {'filename': str, 'client_id': int, 'image_type': str, 'wp_attachment_id': int}","tags":["rpc-write","images"]}},"/api/v1/rpc/cancel_aeo_runs":{"post":{"operationId":"rpc_cancel_aeo_runs","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"},"month":{"default":null,"type":"string"},"query_id":{"default":null,"type":"integer"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"integer"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Drop queued runs (a question was deactivated/deleted, or a client left).","tags":["rpc-write","ai-visibility"]}},"/api/v1/rpc/claim_aeo_runs":{"post":{"operationId":"rpc_claim_aeo_runs","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"agent_id":{"type":"string"},"capabilities_json":{"type":"string"},"limit":{"default":1,"type":"integer"}},"required":["agent_id","capabilities_json"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Atomically claim up to `limit` queued runs this agent can serve: engine in its list, and geo_state matching its state (or agent geo 'any', or the run has no geo). Returns rows joined with the prompt and client name. Disjoint across agents (UPDATE ... WHERE status='queued').","tags":["rpc-write","ai-visibility"]}},"/api/v1/rpc/complete_aeo_run":{"post":{"operationId":"rpc_complete_aeo_run","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"agent_id":{"type":"string"},"capture_id":{"type":"integer"},"run_id":{"type":"integer"}},"required":["run_id","agent_id","capture_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"null"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Capture-agent protocol: the run produced capture_id (from ingest_aeo_capture); marks it done.","tags":["rpc-write","ai-visibility"]}},"/api/v1/rpc/complete_scan_session":{"post":{"operationId":"rpc_complete_scan_session","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"keywords_checked":{"default":0,"type":"integer"},"pages_scanned":{"default":0,"type":"integer"},"session_id":{"type":"integer"},"status":{"default":"completed","type":"string"}},"required":["session_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"description":"Method-specific result."}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Complete a scan session","tags":["rpc-write","monitoring"]}},"/api/v1/rpc/count_active_clients":{"post":{"operationId":"rpc_count_active_clients","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"org_id":{"type":"integer"}},"required":["org_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"integer"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Billable-seat count = the Stripe subscription quantity (status='active' only). Paused is DELIBERATELY excluded here: a paused client is non-renewing, so it must drop out of the NEXT renewal's quantity. It is still \"billed this cycle\" because the current cycle's invoice was already issued while it was active and pausing carries proration_behavior='none' (no refund) \u2014 so reducing the quantity the mo","tags":["rpc-read","clients"]}},"/api/v1/rpc/count_aeo_runs_done_today":{"post":{"operationId":"rpc_count_aeo_runs_done_today","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"agent_id":{"type":"string"}},"required":["agent_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"integer"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Runs this agent completed in the last 24h (server truth, so a restarted agent doesn't forget its daily cap).","tags":["rpc-read","ai-visibility"]}},"/api/v1/rpc/count_batch_requests":{"post":{"operationId":"rpc_count_batch_requests","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"batch_job_id":{"type":"integer"}},"required":["batch_job_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Count requests by status for a batch job.","tags":["rpc-read","billing"]}},"/api/v1/rpc/count_images_out_of_sync":{"post":{"operationId":"rpc_count_images_out_of_sync","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{},"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"integer"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Rows where our featured_image_url differs from the last confirmed WP-side URL. Only counts rows where we HAVE an image locally.","tags":["rpc-read","images"]}},"/api/v1/rpc/count_pending_site_edits":{"post":{"operationId":"rpc_count_pending_site_edits","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"integer"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"count_pending_site_edits","tags":["rpc-read","site-edits"]}},"/api/v1/rpc/count_recent_meta_optimizations":{"post":{"operationId":"rpc_count_recent_meta_optimizations","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"},"days":{"default":7,"type":"integer"},"page_id":{"type":"integer"}},"required":["client_id","page_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"integer"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"How many applied meta_optimizations for (client, page) in the last `days` days. Used by the operator UI to flag whether a meta change is already in flight before pushing another.","tags":["rpc-read","action-items"]}},"/api/v1/rpc/count_recent_published_blogs":{"post":{"operationId":"rpc_count_recent_published_blogs","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"},"days":{"default":7,"type":"integer"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"integer"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"How many blog topics for this client were published in the last `days` days. Used by the operator UI for activity awareness.","tags":["rpc-read","content"]}},"/api/v1/rpc/count_scheduled_blog_topics_by_client":{"post":{"operationId":"rpc_count_scheduled_blog_topics_by_client","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"month":{"type":"string"},"org_id":{"type":"integer"}},"required":["org_id","month"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"{client_id: count} of blog topics scheduled to publish in `month` (YYYY-MM), per client in the org. Powers the /clients list 'Blogs' column (scheduled / monthly target). One GROUP BY, not per-client.","tags":["rpc-read","content"]}},"/api/v1/rpc/count_site_changes_by_month":{"post":{"operationId":"rpc_count_site_changes_by_month","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"},"months":{"default":12,"type":"integer"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Per-month rollup of logged site changes for a client, newest month first: [{'month': 'YYYY-MM', 'changes': rows, 'pages': distinct pages}]. detected_at is the DB's CURRENT_TIMESTAMP (UTC). Drives the Competitor Monitor updates-per-month line charts.","tags":["rpc-read","clients"]}},"/api/v1/rpc/count_site_edit_attempts_last_hour":{"post":{"operationId":"rpc_count_site_edit_attempts_last_hour","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{},"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"integer"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Apply attempts across ALL clients in the trailing hour \u2014 the denominator for the executor's blast-radius cap.","tags":["rpc-read","site-edits"]}},"/api/v1/rpc/count_unpushed_articles":{"post":{"operationId":"rpc_count_unpushed_articles","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{},"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"integer"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Written blog articles that haven't been exported to WP yet.","tags":["rpc-read","site-edits"]}},"/api/v1/rpc/count_unpushed_content_for_client":{"post":{"operationId":"rpc_count_unpushed_content_for_client","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"integer"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Written blog articles not yet exported for a specific client.","tags":["rpc-read","site-edits"]}},"/api/v1/rpc/count_unresolved_app_errors":{"post":{"operationId":"rpc_count_unresolved_app_errors","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{},"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"integer"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"count_unresolved_app_errors","tags":["rpc-read","monitoring"]}},"/api/v1/rpc/count_unresolved_push_failures":{"post":{"operationId":"rpc_count_unresolved_push_failures","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"categories":{"default":null,"type":"array"},"client_id":{"default":null,"type":"integer"}},"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"integer"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Count push_failures with resolved_at IS NULL. Optionally filter by client_id and/or a set of category labels (e.g. ['captcha','network', 'timeout']). Both filters are AND'd.","tags":["rpc-read","site-edits"]}},"/api/v1/rpc/count_unresolved_push_failures_for_org":{"post":{"operationId":"rpc_count_unresolved_push_failures_for_org","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"org_id":{"type":"integer"}},"required":["org_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"integer"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Org-scoped unresolved count \u2014 powers the nav badge.","tags":["rpc-read","site-edits"]}},"/api/v1/rpc/count_unscheduled_articles":{"post":{"operationId":"rpc_count_unscheduled_articles","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{},"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"integer"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Written blog articles that don't have a scheduled_publish_date.","tags":["rpc-read","content"]}},"/api/v1/rpc/create_api_key":{"post":{"operationId":"rpc_create_api_key","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"created_by_user_id":{"default":null,"type":"integer"},"name":{"type":"string"},"notes":{"default":"","type":"string"},"org_id":{"default":null,"type":"integer"},"scopes":{"default":"read,write,jobs","type":"string"}},"required":["name"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Mint a new API key. org_id=None => partner/platform key (cross-org service-account semantics); org_id set => org-scoped agent key confined + metered to that org (enforced in web.py \u2014 ORG_SCOPED_RPCS injects the caller's org so owners can only mint for their own org).","tags":["rpc-write","org-admin"]}},"/api/v1/rpc/create_content_page":{"post":{"operationId":"rpc_create_content_page","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"},"job_id":{"default":null,"type":"integer"},"slug":{"default":"","type":"string"},"status":{"default":"draft","type":"string"},"title":{"default":"","type":"string"},"verify_json":{"default":"","type":"string"},"wp_post_id":{"type":"integer"}},"required":["client_id","wp_post_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"integer"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Insert one draft row (called by content_edit_pipeline.run_assemble right after verify_draft). Returns the new row id.","tags":["rpc-write","site-edits"]}},"/api/v1/rpc/create_site_edit":{"post":{"operationId":"rpc_create_site_edit","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"},"operation":{"type":"string"},"page_url":{"default":"","type":"string"},"payload":{"type":"string"}},"required":["client_id","operation","payload"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"integer"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"create_site_edit","tags":["rpc-write","site-edits"]}},"/api/v1/rpc/deactivate_pages_not_in_list":{"post":{"operationId":"rpc_deactivate_pages_not_in_list","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"active_urls":{"type":"array"},"client_id":{"type":"integer"}},"required":["client_id","active_urls"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"description":"Method-specific result."}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Mark pages as inactive if they're not in the current sitemap","tags":["rpc-write","clients"]}},"/api/v1/rpc/dedupe_aeo_queries":{"post":{"operationId":"rpc_dedupe_aeo_queries","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Merge duplicate question rows (same prompt_key, different engine \u2014 the shape API-engine captures used to create) into the canonical row (the one with a service, else the oldest): captures, runs and item query links are re-pointed, then the duplicates are deleted.","tags":["rpc-write","ai-visibility"]}},"/api/v1/rpc/delete_action_items_for_month":{"post":{"operationId":"rpc_delete_action_items_for_month","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"},"month":{"type":"string"},"preserve_statuses":{"default":null}},"required":["client_id","month"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"description":"Method-specific result."}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Delete action items for a specific month (before regenerating).","tags":["rpc-write","action-items"]}},"/api/v1/rpc/delete_aeo_items_for_client":{"post":{"operationId":"rpc_delete_aeo_items_for_client","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"integer"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Wipe every tracker item for a client. reanalyze_aeo_client rebuilds them from the captures and keeps statuses; calling this alone loses them.","tags":["rpc-write","ai-visibility"]}},"/api/v1/rpc/delete_aeo_queries_for_client":{"post":{"operationId":"rpc_delete_aeo_queries_for_client","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"},"uncaptured_only":{"default":true,"type":"boolean"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"integer"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Bulk reset of a client's question set. Default removes only rows that never produced a capture (a bad generate, an over-broad location list); rows with history are kept (deactivate those individually). Returns rows deleted.","tags":["rpc-write","ai-visibility"]}},"/api/v1/rpc/delete_aeo_query":{"post":{"operationId":"rpc_delete_aeo_query","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"query_id":{"type":"integer"}},"required":["query_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"boolean"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Remove a question that has never been captured; one with history is deactivated instead (its captures and item links stay). Returns True when the row was actually deleted.","tags":["rpc-write","ai-visibility"]}},"/api/v1/rpc/delete_keyword":{"post":{"operationId":"rpc_delete_keyword","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"keyword_id":{"type":"integer"}},"required":["keyword_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"description":"Method-specific result."}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Soft delete a keyword","tags":["rpc-write","search-console"]}},"/api/v1/rpc/delete_locations_for_client":{"post":{"operationId":"rpc_delete_locations_for_client","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"description":"Method-specific result."}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"delete_locations_for_client","tags":["rpc-write","clients"]}},"/api/v1/rpc/delete_org_saml_provider":{"post":{"operationId":"rpc_delete_org_saml_provider","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"org_id":{"type":"integer"},"provider_id":{"type":"integer"}},"required":["org_id","provider_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"boolean"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"delete_org_saml_provider","tags":["rpc-write","org-admin"]}},"/api/v1/rpc/delete_org_sso_provider":{"post":{"operationId":"rpc_delete_org_sso_provider","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"org_id":{"type":"integer"},"provider_id":{"type":"integer"}},"required":["org_id","provider_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"boolean"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"delete_org_sso_provider","tags":["rpc-write","org-admin"]}},"/api/v1/rpc/delete_section_template":{"post":{"operationId":"rpc_delete_section_template","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"template_id":{"type":"integer"}},"required":["template_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"description":"Method-specific result."}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Delete a section template.","tags":["rpc-write","site-edits"]}},"/api/v1/rpc/delete_services_for_client":{"post":{"operationId":"rpc_delete_services_for_client","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"description":"Method-specific result."}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"delete_services_for_client","tags":["rpc-write","clients"]}},"/api/v1/rpc/delete_webhook":{"post":{"operationId":"rpc_delete_webhook","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"org_id":{"type":"integer"},"webhook_id":{"type":"integer"}},"required":["org_id","webhook_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"boolean"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Delete a webhook and its delivery history. False when not the org's.","tags":["rpc-write","general"]}},"/api/v1/rpc/detect_replaced_images":{"post":{"operationId":"rpc_detect_replaced_images","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"},"current_urls":{"type":"array"},"page_id":{"type":"integer"}},"required":["client_id","page_id","current_urls"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"description":"Method-specific result."}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Mark template images that are no longer on the page as replaced.","tags":["rpc-write","images"]}},"/api/v1/rpc/emit_event":{"post":{"operationId":"rpc_emit_event","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"default":null,"type":"integer"},"data":{"default":null,"type":"object"},"event":{"type":"string"},"org_id":{"type":"integer"}},"required":["org_id","event"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"integer"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Queue `event` for every active webhook of the org subscribed to it. Returns the number of deliveries queued. Never raises \u2014 a webhook problem must not fail the operation that produced the event.","tags":["rpc-write","general"]}},"/api/v1/rpc/enqueue_aeo_runs":{"post":{"operationId":"rpc_enqueue_aeo_runs","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"},"org_id":{"type":"integer"},"rows":{"type":"array"}},"required":["org_id","client_id","rows"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Batch enqueue; rows = [{query_id, engine, month, sample_no, geo_state, priority}]. The UNIQUE key makes re-enqueuing a no-op.","tags":["rpc-write","ai-visibility"]}},"/api/v1/rpc/enqueue_cron_trigger":{"post":{"operationId":"rpc_enqueue_cron_trigger","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"},"url":{"type":"string"}},"required":["client_id","url"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"description":"Method-specific result."}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Queue a cron-trigger / render request for the laptop agent. Returns the trigger id. Deduped per (client, url): if a pending trigger for this client+url already exists, that row's id is returned and no new row is added. Per-url (not per-client) dedup so a targeted page render (content_extractor.fetch_via_laptop) coexists with the homepage cron fire \u2014 same homepage url still collapses duplicate fire","tags":["rpc-write","jobs"]}},"/api/v1/rpc/enqueue_due_aeo_runs":{"post":{"operationId":"rpc_enqueue_due_aeo_runs","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"default":null,"type":"integer"},"month":{"default":null,"type":"string"}},"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Daily-sweep entry point (idempotent): for every active client with an active question set, make sure this month's runs exist per the client's cadence (`client_settings.aeo_cadence`: {samples_per_month, engines, geo_state}; default 1 sample, chatgpt-web, geo from the HQ state).","tags":["rpc-write","ai-visibility"]}},"/api/v1/rpc/fail_aeo_run":{"post":{"operationId":"rpc_fail_aeo_run","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"agent_id":{"type":"string"},"error":{"type":"string"},"requeue":{"default":true,"type":"boolean"},"run_id":{"type":"integer"}},"required":["run_id","agent_id","error"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"string"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Requeue (until AEO_RUN_MAX_ATTEMPTS) or mark failed. Returns new status.","tags":["rpc-write","ai-visibility"]}},"/api/v1/rpc/find_action_item_id":{"post":{"operationId":"rpc_find_action_item_id","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"action_type":{"type":"string"},"client_id":{"type":"integer"},"description_contains":{"default":null,"type":"string"},"month":{"type":"string"},"page_url":{"default":null,"type":"string"}},"required":["client_id","month","action_type"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"integer"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Look up a single action_item id by (client_id, action_type) with optional month + page_url + description-substring filters. Returns the first matching id or None. Used by schema_emitter to detect whether a schema_add / schema_data_backfill / seo_plugin_upgrade item already exists before creating a new one.","tags":["rpc-read","action-items"]}},"/api/v1/rpc/generate_aeo_questions":{"post":{"operationId":"rpc_generate_aeo_questions","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"},"use_ai":{"default":false,"type":"boolean"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Build (or refresh) the client's AI-engine question set from its services and locations: buyer-style questions per core service, stored as aeo_queries (review with get_aeo_queries, toggle with update_aeo_query). use_ai=True lets Claude propose extra referral categories, added inactive for review. Returns the generation summary.","tags":["rpc-write","ai-visibility"]}},"/api/v1/rpc/get_action_item":{"post":{"operationId":"rpc_get_action_item","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"item_id":{"type":"integer"}},"required":["item_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"properties":{"action_type":{"type":"string"},"automation_tier":{"type":"string"},"client_id":{"type":"integer"},"completed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"estimated_hours":{"type":"number"},"human_steps":{"type":"string"},"id":{"type":"integer"},"instruction":{"type":"string"},"manual_note":{"type":"string"},"month":{"type":"string"},"operator_note":{"type":"string"},"page_url":{"type":"string"},"priority":{"type":"integer"},"status":{"type":"string"}},"title":"SEOActionItem","type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Get a single action item by ID.","tags":["rpc-read","action-items"]}},"/api/v1/rpc/get_action_items":{"post":{"operationId":"rpc_get_action_items","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"action_type":{"default":null},"client_id":{"type":"integer"},"completed_between":{"default":null},"include_null_month":{"default":false,"type":"boolean"},"month":{"default":null,"type":"string"},"status":{"default":null}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"properties":{"action_type":{"type":"string"},"automation_tier":{"type":"string"},"client_id":{"type":"integer"},"completed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"estimated_hours":{"type":"number"},"human_steps":{"type":"string"},"id":{"type":"integer"},"instruction":{"type":"string"},"manual_note":{"type":"string"},"month":{"type":"string"},"operator_note":{"type":"string"},"page_url":{"type":"string"},"priority":{"type":"integer"},"status":{"type":"string"}},"title":"SEOActionItem","type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Get action items, optionally filtered by month / status / action_type.","tags":["rpc-read","action-items"]}},"/api/v1/rpc/get_active_cooldowns":{"post":{"operationId":"rpc_get_active_cooldowns","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{},"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"get_active_cooldowns","tags":["rpc-read","monitoring"]}},"/api/v1/rpc/get_active_pages_with_intent":{"post":{"operationId":"rpc_get_active_pages_with_intent","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Active pages for a client with their cached intent classification. Returns id, url, intent, intent_confidence per row. Used by schema_emitter to decide which schemas to generate per page.","tags":["rpc-read","clients"]}},"/api/v1/rpc/get_ad_copy_set":{"post":{"operationId":"rpc_get_ad_copy_set","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"},"set_id":{"type":"integer"}},"required":["set_id","client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Wire contract v1 read: ONE shaped set dict, or None when the set does not exist OR is not owned by client_id (same answer either way \u2014 never confirm another client's set exists).","tags":["rpc-read","content"]}},"/api/v1/rpc/get_aeo_agents":{"post":{"operationId":"rpc_get_aeo_agents","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{},"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Registered capture agents (operator devices + the server-API agent) with online flag, capabilities {engines, geo, max_per_day}, current run and run counts.","tags":["rpc-read","ai-visibility"]}},"/api/v1/rpc/get_aeo_cadence":{"post":{"operationId":"rpc_get_aeo_cadence","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"The client's capture cadence {enabled, samples_per_month, engines, geo_state}; {} when never enrolled.","tags":["rpc-read","ai-visibility"]}},"/api/v1/rpc/get_aeo_capture":{"post":{"operationId":"rpc_get_aeo_capture","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"capture_id":{"type":"integer"}},"required":["capture_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"One capture in full: the raw engine record (record_json, '' once pruned) and its analysis (report_json: scorecard, source_table, claim_map, entity_table, findings).","tags":["rpc-read","ai-visibility"]}},"/api/v1/rpc/get_aeo_capture_records":{"post":{"operationId":"rpc_get_aeo_capture_records","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Every capture of a client WITH its raw record, oldest first \u2014 the feed for `aeo_tracker.reanalyze_client`.","tags":["rpc-read","ai-visibility"]}},"/api/v1/rpc/get_aeo_captures":{"post":{"operationId":"rpc_get_aeo_captures","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"},"limit":{"default":200,"type":"integer"},"month":{"default":null,"type":"string"},"query_id":{"default":null,"type":"integer"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Captures for a client, newest first. Includes report_json (the monthly report reads scorecards out of it); record_json is omitted.","tags":["rpc-read","ai-visibility"]}},"/api/v1/rpc/get_aeo_item":{"post":{"operationId":"rpc_get_aeo_item","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"item_id":{"type":"integer"}},"required":["item_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"One tracker item by id (evidence, query_ids and per-month hits decoded).","tags":["rpc-read","ai-visibility"]}},"/api/v1/rpc/get_aeo_item_by_key":{"post":{"operationId":"rpc_get_aeo_item_by_key","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"},"item_key":{"type":"string"}},"required":["client_id","item_key"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"One tracker item by its stable item_key \u2014 the finding id, e.g. 'G3-RETRIEVED- DIRECTORY::clutch.co'.","tags":["rpc-read","ai-visibility"]}},"/api/v1/rpc/get_aeo_items":{"post":{"operationId":"rpc_get_aeo_items","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"},"status":{"default":null,"type":"string"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"All tracked items for a client (or one status), tier A\u2192X then title.","tags":["rpc-read","ai-visibility"]}},"/api/v1/rpc/get_aeo_months":{"post":{"operationId":"rpc_get_aeo_months","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"type":"string"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Distinct capture months for a client, ascending.","tags":["rpc-read","ai-visibility"]}},"/api/v1/rpc/get_aeo_queries":{"post":{"operationId":"rpc_get_aeo_queries","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Recurring queries for a client with capture_count + last_month, ordered for a run: active first, then priority, then age.","tags":["rpc-read","ai-visibility"]}},"/api/v1/rpc/get_aeo_query":{"post":{"operationId":"rpc_get_aeo_query","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"query_id":{"type":"integer"}},"required":["query_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"One recurring question row (prompt, engine, service, kind, priority, active).","tags":["rpc-read","ai-visibility"]}},"/api/v1/rpc/get_aeo_queue_overview":{"post":{"operationId":"rpc_get_aeo_queue_overview","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"org_id":{"default":null,"type":"integer"}},"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Everything the queue monitor needs in one call: status counts, per-client backlog with oldest-queued age, queued runs per market state, throughput (done last 24h / 7d, per agent), recent failures, and the agent registry.","tags":["rpc-read","ai-visibility"]}},"/api/v1/rpc/get_aeo_run_stats":{"post":{"operationId":"rpc_get_aeo_run_stats","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"default":null,"type":"integer"},"month":{"default":null,"type":"string"}},"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Queue counts for a client (or all clients) and month: queued / claimed / running / done / failed / cancelled / total.","tags":["rpc-read","ai-visibility"]}},"/api/v1/rpc/get_aeo_runs":{"post":{"operationId":"rpc_get_aeo_runs","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"},"limit":{"default":200,"type":"integer"},"month":{"default":null,"type":"string"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Queue rows for a client, newest first: engine, status, agent_id, attempts, error, capture_id.","tags":["rpc-read","ai-visibility"]}},"/api/v1/rpc/get_aeo_summary":{"post":{"operationId":"rpc_get_aeo_summary","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"},"month":{"default":"","type":"string"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"One-call status card for a client: active question count, captures this month, per- service presence / named-first rates, open task count, queue counts and cadence. Start here before drilling into get_aeo_items / get_aeo_captures.","tags":["rpc-read","ai-visibility"]}},"/api/v1/rpc/get_agency_name_for_client":{"post":{"operationId":"rpc_get_agency_name_for_client","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"string"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"White-label 'Generated by \u2026' name for a client's deliverables.","tags":["rpc-read","clients"]}},"/api/v1/rpc/get_agent_status":{"post":{"operationId":"rpc_get_agent_status","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"within_seconds":{"default":90,"type":"integer"}},"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Laptop cron-agent liveness. `online` is True if any agent has pinged within `within_seconds`. Returns the freshest age + the list of recently-active agents (supports a 'string of laptops').","tags":["rpc-read","jobs"]}},"/api/v1/rpc/get_all_associations_for_client":{"post":{"operationId":"rpc_get_all_associations_for_client","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Get all keyword-page associations for a client","tags":["rpc-read","clients"]}},"/api/v1/rpc/get_all_client_groups":{"post":{"operationId":"rpc_get_all_client_groups","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"active_only":{"default":true,"type":"boolean"},"org_id":{"default":null,"type":"integer"}},"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"properties":{"active":{"type":"boolean"},"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"integer"},"name":{"type":"string"},"org_id":{"type":"integer"}},"title":"ClientGroup","type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Get all client groups. org_id, when given, restricts to that organization \u2014 the web layer always passes the caller's org_id.","tags":["rpc-read","clients"]}},"/api/v1/rpc/get_all_client_settings":{"post":{"operationId":"rpc_get_all_client_settings","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Get all settings for a client as a dict.","tags":["rpc-read","clients"]}},"/api/v1/rpc/get_all_client_slugs":{"post":{"operationId":"rpc_get_all_client_slugs","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{},"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"type":"array"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"All (id, slug) pairs with a non-empty slug \u2014 feeds the routing cache.","tags":["rpc-read","clients"]}},"/api/v1/rpc/get_all_clients":{"post":{"operationId":"rpc_get_all_clients","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"active_only":{"default":true,"type":"boolean"},"include_deleted":{"default":false,"type":"boolean"},"include_paused":{"default":true,"type":"boolean"},"include_staging":{"default":false,"type":"boolean"},"org_id":{"default":null,"type":"integer"}},"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"properties":{"active":{"type":"boolean"},"blogs_per_month":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"ftp_host":{"type":"string"},"ftp_password":{"type":"string"},"ftp_port":{"type":"integer"},"ftp_root":{"type":"string"},"ftp_use_tls":{"type":"boolean"},"ftp_username":{"type":"string"},"gsc_property":{"type":"string"},"id":{"type":"integer"},"industry":{"type":"string"},"monthly_seo_hours":{"type":"number"},"name":{"type":"string"},"org_id":{"type":"integer"},"parent_client_id":{"type":"integer"},"sitemap_url":{"type":"string"},"staging":{"type":"boolean"},"status":{"type":"string"},"webhook_secret":{"type":"string"},"webhook_url":{"type":"string"},"website_url":{"type":"string"}},"title":"Client","type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Get all clients. Deleted clients are excluded unless include_deleted=True.","tags":["rpc-read","clients"]}},"/api/v1/rpc/get_all_content_for_client":{"post":{"operationId":"rpc_get_all_content_for_client","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"properties":{"categories":{"items":{"type":"string"},"type":"array"},"content_html":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"excerpt":{"type":"string"},"exported":{"type":"boolean"},"exported_at":{"type":"string"},"featured_image_alt":{"type":"string"},"featured_image_url":{"type":"string"},"id":{"type":"integer"},"internal_links":{"items":{"type":"object"},"type":"array"},"quality_notes":{"type":"string"},"quality_score":{"type":"number"},"scheduled_publish_date":{"type":"string"},"schema_markup":{"type":"string"},"seo_description":{"type":"string"},"seo_title":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"topic_id":{"type":"integer"},"updated_at":{"format":"date-time","type":"string"},"word_count":{"type":"integer"}},"title":"BlogContent","type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Get all written content for a client (exported and unexported).","tags":["rpc-read","content"]}},"/api/v1/rpc/get_all_costs_summary":{"post":{"operationId":"rpc_get_all_costs_summary","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"days":{"default":null,"type":"integer"}},"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Get cost summary grouped by client across all operations.","tags":["rpc-read","billing"]}},"/api/v1/rpc/get_app_errors":{"post":{"operationId":"rpc_get_app_errors","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"limit":{"default":100,"type":"integer"},"unresolved_only":{"default":true,"type":"boolean"}},"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"get_app_errors","tags":["rpc-read","monitoring"]}},"/api/v1/rpc/get_associations_for_keyword":{"post":{"operationId":"rpc_get_associations_for_keyword","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"keyword_id":{"type":"integer"}},"required":["keyword_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Get all page associations for a keyword","tags":["rpc-read","search-console"]}},"/api/v1/rpc/get_associations_for_page":{"post":{"operationId":"rpc_get_associations_for_page","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"page_id":{"type":"integer"}},"required":["page_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Get all keyword associations for a page","tags":["rpc-read","clients"]}},"/api/v1/rpc/get_attention_flags_for_org":{"post":{"operationId":"rpc_get_attention_flags_for_org","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"org_id":{"type":"integer"}},"required":["org_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"{client_id: flag_text} for clients in the org with a non-empty `attention_flag` setting. Powers the \u2691 shown next to client names for clients that need special handling (non-WP / proprietary CMS, etc.). One query so list views don't round-trip per client.","tags":["rpc-read","org-admin"]}},"/api/v1/rpc/get_available_rank_dates":{"post":{"operationId":"rpc_get_available_rank_dates","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"type":"string"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Get list of distinct dates when rank checks were done for a client","tags":["rpc-read","search-console"]}},"/api/v1/rpc/get_available_snapshot_dates":{"post":{"operationId":"rpc_get_available_snapshot_dates","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"type":"string"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Get list of distinct dates when snapshots were taken for a client","tags":["rpc-read","monitoring"]}},"/api/v1/rpc/get_batch_job":{"post":{"operationId":"rpc_get_batch_job","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"job_id":{"type":"integer"}},"required":["job_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Get a batch job by ID.","tags":["rpc-read","jobs"]}},"/api/v1/rpc/get_batch_jobs":{"post":{"operationId":"rpc_get_batch_jobs","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"default":null,"type":"integer"},"limit":{"default":20,"type":"integer"},"status":{"default":null,"type":"string"}},"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Get batch jobs, optionally filtered by status and/or client.","tags":["rpc-read","jobs"]}},"/api/v1/rpc/get_batch_request_by_custom_id":{"post":{"operationId":"rpc_get_batch_request_by_custom_id","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"custom_id":{"type":"string"}},"required":["custom_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Get a batch request by its custom_id.","tags":["rpc-read","billing"]}},"/api/v1/rpc/get_batch_requests":{"post":{"operationId":"rpc_get_batch_requests","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"batch_job_id":{"type":"integer"},"status":{"default":null,"type":"string"}},"required":["batch_job_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Get all requests for a batch job.","tags":["rpc-read","billing"]}},"/api/v1/rpc/get_blog_calendar_month":{"post":{"operationId":"rpc_get_blog_calendar_month","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"month":{"type":"string"},"org_id":{"type":"integer"}},"required":["org_id","month"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"All blog posts scheduled in `month` (YYYY-MM) across the org \u2014 date, client, title, delivery state. Powers the /blog-calendar grid.","tags":["rpc-read","content"]}},"/api/v1/rpc/get_blog_content":{"post":{"operationId":"rpc_get_blog_content","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"content_id":{"type":"integer"}},"required":["content_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"properties":{"categories":{"items":{"type":"string"},"type":"array"},"content_html":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"excerpt":{"type":"string"},"exported":{"type":"boolean"},"exported_at":{"type":"string"},"featured_image_alt":{"type":"string"},"featured_image_url":{"type":"string"},"id":{"type":"integer"},"internal_links":{"items":{"type":"object"},"type":"array"},"quality_notes":{"type":"string"},"quality_score":{"type":"number"},"scheduled_publish_date":{"type":"string"},"schema_markup":{"type":"string"},"seo_description":{"type":"string"},"seo_title":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"topic_id":{"type":"integer"},"updated_at":{"format":"date-time","type":"string"},"word_count":{"type":"integer"}},"title":"BlogContent","type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Fetch a blog_content row by its primary key id.","tags":["rpc-read","content"]}},"/api/v1/rpc/get_blog_content_for_topic":{"post":{"operationId":"rpc_get_blog_content_for_topic","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"topic_id":{"type":"integer"}},"required":["topic_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"properties":{"categories":{"items":{"type":"string"},"type":"array"},"content_html":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"excerpt":{"type":"string"},"exported":{"type":"boolean"},"exported_at":{"type":"string"},"featured_image_alt":{"type":"string"},"featured_image_url":{"type":"string"},"id":{"type":"integer"},"internal_links":{"items":{"type":"object"},"type":"array"},"quality_notes":{"type":"string"},"quality_score":{"type":"number"},"scheduled_publish_date":{"type":"string"},"schema_markup":{"type":"string"},"seo_description":{"type":"string"},"seo_title":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"topic_id":{"type":"integer"},"updated_at":{"format":"date-time","type":"string"},"word_count":{"type":"integer"}},"title":"BlogContent","type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"get_blog_content_for_topic","tags":["rpc-read","content"]}},"/api/v1/rpc/get_blog_content_summary_for_client":{"post":{"operationId":"rpc_get_blog_content_summary_for_client","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Lightweight title + scheduled_publish_date rollup of all blog content for a client. Used for: - title-based slug matching when deciding if a page is a blog post (seo_strategist.is_blog_post_url) - title \u2192 date mapping for Article schema's datePublished (schema_emitter) Joins blog_topics so the client_id filter works (blog_content carries topic_id, not client_id directly).","tags":["rpc-read","content"]}},"/api/v1/rpc/get_blog_filter_options_for_org":{"post":{"operationId":"rpc_get_blog_filter_options_for_org","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"org_id":{"type":"integer"}},"required":["org_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Distinct schedule months + clients that have blog content \u2014 the /blogs filter dropdowns.","tags":["rpc-read","content"]}},"/api/v1/rpc/get_blog_images_for_org":{"post":{"operationId":"rpc_get_blog_images_for_org","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"default":0,"type":"integer"},"client_status":{"default":"","type":"string"},"limit":{"default":60,"type":"integer"},"month":{"default":"","type":"string"},"offset":{"default":0,"type":"integer"},"org_id":{"type":"integer"}},"required":["org_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Org-wide generated-image gallery: blog posts that HAVE a featured image, newest-first (by created_at), paginated. Returns (rows, total). Filters: month (by scheduled date), client, client_status ('active' / 'inactive' / '' = all). Powers /blogs/images.","tags":["rpc-read","images"]}},"/api/v1/rpc/get_blog_posts_for_client":{"post":{"operationId":"rpc_get_blog_posts_for_client","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"properties":{"active":{"type":"boolean"},"client_id":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"integer"},"keywords_targeted":{"items":{"type":"string"},"type":"array"},"meta_description":{"type":"string"},"page_id":{"type":"integer"},"primary_topic":{"type":"string"},"published_date":{"type":"string"},"title":{"type":"string"},"url":{"type":"string"},"word_count":{"type":"integer"}},"title":"BlogPost","type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"get_blog_posts_for_client","tags":["rpc-read","content"]}},"/api/v1/rpc/get_blog_posts_for_org":{"post":{"operationId":"rpc_get_blog_posts_for_org","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"default":0,"type":"integer"},"client_status":{"default":"","type":"string"},"limit":{"default":300,"type":"integer"},"month":{"default":"","type":"string"},"org_id":{"type":"integer"},"q":{"default":"","type":"string"},"status":{"default":"","type":"string"}},"required":["org_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Org-wide blog browser: every generated article with its schedule + delivery state, newest first (unscheduled drafts at the end). Filters: month (YYYY-MM), client, status ('published' / 'scheduled' / 'unscheduled'), title substring, client_status ('active' = active clients only / 'inactive' = paused+inactive / '' or 'all' = no client-status filter). Powers /blogs.","tags":["rpc-read","content"]}},"/api/v1/rpc/get_blog_schedule":{"post":{"operationId":"rpc_get_blog_schedule","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"properties":{"active":{"type":"boolean"},"client_id":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"integer"},"next_publish_date":{"type":"string"},"posts_per_week":{"type":"integer"},"preferred_days":{"items":{"type":"string"},"type":"array"}},"title":"BlogSchedule","type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"get_blog_schedule","tags":["rpc-read","content"]}},"/api/v1/rpc/get_blog_topic":{"post":{"operationId":"rpc_get_blog_topic","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"topic_id":{"type":"integer"}},"required":["topic_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"properties":{"active":{"type":"boolean"},"categories":{"items":{"type":"string"},"type":"array"},"client_id":{"type":"integer"},"competitor_gap":{"type":"boolean"},"created_at":{"format":"date-time","type":"string"},"featured_image_prompt":{"type":"string"},"id":{"type":"integer"},"priority":{"type":"integer"},"published_at":{"format":"date-time","type":"string"},"scheduled_publish_date":{"type":"string"},"search_volume":{"type":"integer"},"seo_description":{"type":"string"},"seo_title":{"type":"string"},"status":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"target_keywords":{"items":{"type":"string"},"type":"array"},"target_location":{"type":"string"},"target_service":{"type":"string"},"topic_description":{"type":"string"},"topic_title":{"type":"string"},"value_score":{"type":"number"},"written_at":{"format":"date-time","type":"string"}},"title":"BlogTopic","type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"get_blog_topic","tags":["rpc-read","content"]}},"/api/v1/rpc/get_blog_topics_for_client":{"post":{"operationId":"rpc_get_blog_topics_for_client","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"},"status":{"default":null,"type":"string"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"properties":{"active":{"type":"boolean"},"categories":{"items":{"type":"string"},"type":"array"},"client_id":{"type":"integer"},"competitor_gap":{"type":"boolean"},"created_at":{"format":"date-time","type":"string"},"featured_image_prompt":{"type":"string"},"id":{"type":"integer"},"priority":{"type":"integer"},"published_at":{"format":"date-time","type":"string"},"scheduled_publish_date":{"type":"string"},"search_volume":{"type":"integer"},"seo_description":{"type":"string"},"seo_title":{"type":"string"},"status":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"target_keywords":{"items":{"type":"string"},"type":"array"},"target_location":{"type":"string"},"target_service":{"type":"string"},"topic_description":{"type":"string"},"topic_title":{"type":"string"},"value_score":{"type":"number"},"written_at":{"format":"date-time","type":"string"}},"title":"BlogTopic","type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"get_blog_topics_for_client","tags":["rpc-read","content"]}},"/api/v1/rpc/get_cached_description":{"post":{"operationId":"rpc_get_cached_description","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"image_url":{"type":"string"}},"required":["image_url"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"string"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Look up a cached image description by URL. Returns None on miss.","tags":["rpc-read","content"]}},"/api/v1/rpc/get_client":{"post":{"operationId":"rpc_get_client","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"properties":{"active":{"type":"boolean"},"blogs_per_month":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"ftp_host":{"type":"string"},"ftp_password":{"type":"string"},"ftp_port":{"type":"integer"},"ftp_root":{"type":"string"},"ftp_use_tls":{"type":"boolean"},"ftp_username":{"type":"string"},"gsc_property":{"type":"string"},"id":{"type":"integer"},"industry":{"type":"string"},"monthly_seo_hours":{"type":"number"},"name":{"type":"string"},"org_id":{"type":"integer"},"parent_client_id":{"type":"integer"},"sitemap_url":{"type":"string"},"staging":{"type":"boolean"},"status":{"type":"string"},"webhook_secret":{"type":"string"},"webhook_url":{"type":"string"},"website_url":{"type":"string"}},"title":"Client","type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Get a client by ID","tags":["rpc-read","clients"]}},"/api/v1/rpc/get_client_activity":{"post":{"operationId":"rpc_get_client_activity","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"},"limit":{"default":150,"type":"integer"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Chronological feed of everything the system did to/for a client: entity changes (pushes, meta/image/date mutations), background jobs, and push failures \u2014 merged, newest first. Powers /clients/<id>/activity.","tags":["rpc-read","clients"]}},"/api/v1/rpc/get_client_change_history":{"post":{"operationId":"rpc_get_client_change_history","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"},"entity_type":{"default":null,"type":"string"},"limit":{"default":200,"type":"integer"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"get_client_change_history","tags":["rpc-read","clients"]}},"/api/v1/rpc/get_client_cooldown":{"post":{"operationId":"rpc_get_client_cooldown","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"},"reason":{"default":null,"type":"string"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Return the soonest-expiring active cooldown for this client, or None.","tags":["rpc-read","monitoring"]}},"/api/v1/rpc/get_client_costs":{"post":{"operationId":"rpc_get_client_costs","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"},"days":{"default":null,"type":"integer"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Get cost summary grouped by operation for a client.","tags":["rpc-read","billing"]}},"/api/v1/rpc/get_client_deactivated_at":{"post":{"operationId":"rpc_get_client_deactivated_at","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"string"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"get_client_deactivated_at","tags":["rpc-read","clients"]}},"/api/v1/rpc/get_client_ftp":{"post":{"operationId":"rpc_get_client_ftp","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Get FTP credentials \u2014 reads from client_settings first, falls back to clients columns.","tags":["rpc-read","clients"]}},"/api/v1/rpc/get_client_group":{"post":{"operationId":"rpc_get_client_group","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"group_id":{"type":"integer"}},"required":["group_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"properties":{"active":{"type":"boolean"},"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"integer"},"name":{"type":"string"},"org_id":{"type":"integer"}},"title":"ClientGroup","type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Get a single client group by ID","tags":["rpc-read","clients"]}},"/api/v1/rpc/get_client_id_by_slug":{"post":{"operationId":"rpc_get_client_id_by_slug","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"slug":{"type":"string"}},"required":["slug"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"integer"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Resolve a URL slug to a client id (global lookup; ownership is enforced downstream by _load_owned_client). None if unknown.","tags":["rpc-read","clients"]}},"/api/v1/rpc/get_client_org_id":{"post":{"operationId":"rpc_get_client_org_id","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"integer"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Return the org_id that owns a client, or None if the client does not exist. Used by the RPC layer to validate that an org-scoped caller is only touching clients in their own org.","tags":["rpc-read","org-admin"]}},"/api/v1/rpc/get_client_setting":{"post":{"operationId":"rpc_get_client_setting","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"},"key":{"type":"string"}},"required":["client_id","key"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"string"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Get a per-client setting value.","tags":["rpc-read","clients"]}},"/api/v1/rpc/get_client_slug":{"post":{"operationId":"rpc_get_client_slug","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"string"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"The client's URL slug, or '' if not set.","tags":["rpc-read","clients"]}},"/api/v1/rpc/get_client_ssh_pubkey":{"post":{"operationId":"rpc_get_client_ssh_pubkey","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"string"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"The per-client SSH public key a self-hosted client should authorize (generates the keypair on first request). Exposed as a read RPC so Operations Manager can embed the right key in that client's connect kit \u2014 one key per client, so a leak opens one site, not all of them.","tags":["rpc-read","clients"]}},"/api/v1/rpc/get_client_webhook":{"post":{"operationId":"rpc_get_client_webhook","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Get webhook credentials \u2014 reads from client_settings first, falls back to clients columns.","tags":["rpc-read","clients"]}},"/api/v1/rpc/get_client_wp_post_ids":{"post":{"operationId":"rpc_get_client_wp_post_ids","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"{slug: wp_post_id} for a client \u2014 captured from plugin push responses (and /export backfill). Powers exact wp-admin edit deep-links.","tags":["rpc-read","site-edits"]}},"/api/v1/rpc/get_clients_in_group":{"post":{"operationId":"rpc_get_clients_in_group","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"group_id":{"type":"integer"}},"required":["group_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"properties":{"active":{"type":"boolean"},"blogs_per_month":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"ftp_host":{"type":"string"},"ftp_password":{"type":"string"},"ftp_port":{"type":"integer"},"ftp_root":{"type":"string"},"ftp_use_tls":{"type":"boolean"},"ftp_username":{"type":"string"},"gsc_property":{"type":"string"},"id":{"type":"integer"},"industry":{"type":"string"},"monthly_seo_hours":{"type":"number"},"name":{"type":"string"},"org_id":{"type":"integer"},"parent_client_id":{"type":"integer"},"sitemap_url":{"type":"string"},"staging":{"type":"boolean"},"status":{"type":"string"},"webhook_secret":{"type":"string"},"webhook_url":{"type":"string"},"website_url":{"type":"string"}},"title":"Client","type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Get all clients belonging to a group","tags":["rpc-read","clients"]}},"/api/v1/rpc/get_compare_report":{"post":{"operationId":"rpc_get_compare_report","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"report_id":{"type":"integer"}},"required":["report_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Full comparison report (incl. HTML + org_id for the ownership check).","tags":["rpc-read","reports"]}},"/api/v1/rpc/get_compare_reports_for_org":{"post":{"operationId":"rpc_get_compare_reports_for_org","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"limit":{"default":50,"type":"integer"},"org_id":{"type":"integer"}},"required":["org_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Recent A/B comparison reports for the org (no HTML \u2014 list view). Joins client names for display.","tags":["rpc-read","reports"]}},"/api/v1/rpc/get_consecutive_rollover_months":{"post":{"operationId":"rpc_get_consecutive_rollover_months","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"integer"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Count how many consecutive *past* months had unused hours rolling over. Skips the current month (which may be in progress). Used to detect on-page SEO exhaustion signal.","tags":["rpc-read","billing"]}},"/api/v1/rpc/get_content_page":{"post":{"operationId":"rpc_get_content_page","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"page_id":{"type":"integer"}},"required":["page_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"get_content_page","tags":["rpc-read","site-edits"]}},"/api/v1/rpc/get_cost_detail":{"post":{"operationId":"rpc_get_cost_detail","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"default":null,"type":"integer"},"days":{"default":null,"type":"integer"},"limit":{"default":100,"type":"integer"},"operation":{"default":null,"type":"string"}},"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Get individual API call records with optional filters.","tags":["rpc-read","billing"]}},"/api/v1/rpc/get_cron_trigger_result":{"post":{"operationId":"rpc_get_cron_trigger_result","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"trigger_id":{"type":"integer"}},"required":["trigger_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Return {status, rendered_at, html, meta} for a trigger, or None. Pollers (content_extractor.fetch_via_laptop) wait until rendered_at is set, then read the relayed real-browser HTML.","tags":["rpc-read","jobs"]}},"/api/v1/rpc/get_deleted_clients":{"post":{"operationId":"rpc_get_deleted_clients","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{},"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"properties":{"active":{"type":"boolean"},"blogs_per_month":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"ftp_host":{"type":"string"},"ftp_password":{"type":"string"},"ftp_port":{"type":"integer"},"ftp_root":{"type":"string"},"ftp_use_tls":{"type":"boolean"},"ftp_username":{"type":"string"},"gsc_property":{"type":"string"},"id":{"type":"integer"},"industry":{"type":"string"},"monthly_seo_hours":{"type":"number"},"name":{"type":"string"},"org_id":{"type":"integer"},"parent_client_id":{"type":"integer"},"sitemap_url":{"type":"string"},"staging":{"type":"boolean"},"status":{"type":"string"},"webhook_secret":{"type":"string"},"webhook_url":{"type":"string"},"website_url":{"type":"string"}},"title":"Client","type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Get all deleted clients.","tags":["rpc-read","clients"]}},"/api/v1/rpc/get_elementor_page":{"post":{"operationId":"rpc_get_elementor_page","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"project_id":{"type":"integer"},"wp_post_id":{"type":"integer"}},"required":["project_id","wp_post_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Get a single exported Elementor page.","tags":["rpc-read","site-edits"]}},"/api/v1/rpc/get_elementor_page_stamps":{"post":{"operationId":"rpc_get_elementor_page_stamps","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"project_id":{"type":"integer"}},"required":["project_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Lightweight listing for the freshness check + UI page pickers: [{wp_post_id, title, slug, url, post_type, modified_gmt, updated_at}] \u2014 no elementor_data blob, so it stays cheap on sites with hundreds of pages.","tags":["rpc-read","site-edits"]}},"/api/v1/rpc/get_elementor_pages":{"post":{"operationId":"rpc_get_elementor_pages","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"project_id":{"type":"integer"}},"required":["project_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Get all exported Elementor pages for a project.","tags":["rpc-read","site-edits"]}},"/api/v1/rpc/get_entity_changes":{"post":{"operationId":"rpc_get_entity_changes","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"actions":{"default":null,"type":"array"},"client_id":{"type":"integer"},"month":{"type":"string"}},"required":["client_id","month"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"entity_change_log rows for a client + month-string, optionally filtered to a set of action labels (e.g. ['set', 'pushed']). `month` matches against strftime('%Y-%m', created_at).","tags":["rpc-read","monitoring"]}},"/api/v1/rpc/get_entity_changes_between":{"post":{"operationId":"rpc_get_entity_changes_between","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"actions":{"default":null,"type":"array"},"client_id":{"type":"integer"},"end":{"type":"string"},"start":{"type":"string"}},"required":["client_id","start","end"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"entity_change_log rows for a client whose `created_at` day falls in the inclusive [start, end] window ('YYYY-MM-DD' dates), optionally filtered to a set of action labels. The date-range analogue of `get_entity_changes`, used by the arbitrary-period client report.","tags":["rpc-read","monitoring"]}},"/api/v1/rpc/get_entity_history":{"post":{"operationId":"rpc_get_entity_history","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"entity_id":{"type":"integer"},"entity_type":{"type":"string"},"limit":{"default":100,"type":"integer"}},"required":["entity_type","entity_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"get_entity_history","tags":["rpc-read","monitoring"]}},"/api/v1/rpc/get_first_snapshot_dates":{"post":{"operationId":"rpc_get_first_snapshot_dates","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"{page_id: 'YYYY-MM-DD HH:MM:SS'} of each page's EARLIEST snapshot \u2014 i.e. when we first saw the page. Snapshots are append-only, so this is how 'new page since <date>' is answered (pages has no created_at).","tags":["rpc-read","monitoring"]}},"/api/v1/rpc/get_ftp_capable_client_ids":{"post":{"operationId":"rpc_get_ftp_capable_client_ids","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"org_id":{"type":"integer"}},"required":["org_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"type":"integer"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Client ids with FTP-inbox delivery configured (client_settings.ftp_credentials \u2014 mirrors InboxPusher.is_configured). Used with webhook_url to decide whether the browser can auto-deliver blogs for a client (PushRouter handles either transport).","tags":["rpc-read","clients"]}},"/api/v1/rpc/get_generated_content_for_page":{"post":{"operationId":"rpc_get_generated_content_for_page","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"sitemap_page_id":{"type":"integer"}},"required":["sitemap_page_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"properties":{"content_html":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"integer"},"meta_description":{"type":"string"},"meta_title":{"type":"string"},"og_description":{"type":"string"},"og_image_prompt":{"type":"string"},"og_title":{"type":"string"},"project_id":{"type":"integer"},"schema_markup":{"type":"string"},"sitemap_page_id":{"type":"integer"},"target_keywords":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"updated_at":{"format":"date-time","type":"string"},"word_count":{"type":"integer"}},"title":"GeneratedPageContent","type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"get_generated_content_for_page","tags":["rpc-read","content"]}},"/api/v1/rpc/get_generated_content_for_project":{"post":{"operationId":"rpc_get_generated_content_for_project","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"project_id":{"type":"integer"}},"required":["project_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"properties":{"content_html":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"integer"},"meta_description":{"type":"string"},"meta_title":{"type":"string"},"og_description":{"type":"string"},"og_image_prompt":{"type":"string"},"og_title":{"type":"string"},"project_id":{"type":"integer"},"schema_markup":{"type":"string"},"sitemap_page_id":{"type":"integer"},"target_keywords":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"updated_at":{"format":"date-time","type":"string"},"word_count":{"type":"integer"}},"title":"GeneratedPageContent","type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"get_generated_content_for_project","tags":["rpc-read","content"]}},"/api/v1/rpc/get_groups_for_client":{"post":{"operationId":"rpc_get_groups_for_client","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"properties":{"active":{"type":"boolean"},"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"integer"},"name":{"type":"string"},"org_id":{"type":"integer"}},"title":"ClientGroup","type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Get all groups a client belongs to","tags":["rpc-read","clients"]}},"/api/v1/rpc/get_gsc_capture_keywords":{"post":{"operationId":"rpc_get_gsc_capture_keywords","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"capture_id":{"type":"integer"}},"required":["capture_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Return {keyword: {position, impressions, clicks, ctr}} for a capture.","tags":["rpc-read","search-console"]}},"/api/v1/rpc/get_gsc_snapshot":{"post":{"operationId":"rpc_get_gsc_snapshot","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"},"level":{"type":"string"},"period_end":{"type":"string"},"period_start":{"type":"string"}},"required":["client_id","period_start","period_end","level"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Retrieve GSC snapshot rows for a given period/level.","tags":["rpc-read","search-console"]}},"/api/v1/rpc/get_hour_budgets":{"post":{"operationId":"rpc_get_hour_budgets","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"},"limit":{"default":6,"type":"integer"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Get recent monthly budgets, ordered by month descending.","tags":["rpc-read","billing"]}},"/api/v1/rpc/get_image_catalog":{"post":{"operationId":"rpc_get_image_catalog","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"project_id":{"type":"integer"},"status":{"default":null,"type":"string"}},"required":["project_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Get all image catalog entries for a project, optionally filtered by status.","tags":["rpc-read","images"]}},"/api/v1/rpc/get_image_catalog_for_page":{"post":{"operationId":"rpc_get_image_catalog_for_page","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"project_id":{"type":"integer"},"wp_post_id":{"type":"integer"}},"required":["project_id","wp_post_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Get image catalog entries for a specific page.","tags":["rpc-read","images"]}},"/api/v1/rpc/get_image_catalog_stats":{"post":{"operationId":"rpc_get_image_catalog_stats","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"project_id":{"type":"integer"}},"required":["project_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Get counts of images by replacement status.","tags":["rpc-read","images"]}},"/api/v1/rpc/get_image_history":{"post":{"operationId":"rpc_get_image_history","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"content_id":{"type":"integer"}},"required":["content_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Full change log for one blog content row.","tags":["rpc-read","images"]}},"/api/v1/rpc/get_image_stats":{"post":{"operationId":"rpc_get_image_stats","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Return image counts by status for a client.","tags":["rpc-read","images"]}},"/api/v1/rpc/get_image_sync_states_for_client":{"post":{"operationId":"rpc_get_image_sync_states_for_client","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Aggregate counts of blog_content image-sync states for a client. Returns {no_image, synced, never_pushed, stale}. Mirrors the inline SQL formerly in main.py:321 (client image stats panel).","tags":["rpc-read","images"]}},"/api/v1/rpc/get_image_type_stats":{"post":{"operationId":"rpc_get_image_type_stats","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Return image counts by type for a client.","tags":["rpc-read","images"]}},"/api/v1/rpc/get_images_for_client":{"post":{"operationId":"rpc_get_images_for_client","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"},"image_type":{"default":null},"status":{"default":null,"type":"string"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"properties":{"alt_text":{"type":"string"},"analyzed_at":{"type":"string"},"applied_at":{"type":"string"},"client_id":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"file_size":{"type":"integer"},"filename":{"type":"string"},"id":{"type":"integer"},"image_type":{"type":"string"},"remote_path":{"type":"string"},"status":{"type":"string"},"wp_attachment_id":{"type":"integer"}},"title":"ClientImage","type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Get images for a client, optionally filtered by status and/or image_type. image_type can be a single string or a list of strings for multi-type filtering.","tags":["rpc-read","images"]}},"/api/v1/rpc/get_images_out_of_sync":{"post":{"operationId":"rpc_get_images_out_of_sync","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{},"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"List of out-of-sync rows with client name for the review screen.","tags":["rpc-read","images"]}},"/api/v1/rpc/get_jobs_progress_for_org":{"post":{"operationId":"rpc_get_jobs_progress_for_org","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"org_id":{"type":"integer"},"recent_minutes":{"default":30,"type":"integer"}},"required":["org_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Active (queued/running) jobs + those that FINISHED in the last `recent_minutes`, with live progress + client name. Powers the real-time fleet-progress panel on the dashboard / clients list \u2014 the recently-finished rows let the panel show 'X done of N' as a batch drains, since finished jobs otherwise vanish from the active set. Running first, then queued, then finished (newest).","tags":["rpc-read","reports"]}},"/api/v1/rpc/get_keyword":{"post":{"operationId":"rpc_get_keyword","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"keyword_id":{"type":"integer"}},"required":["keyword_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"properties":{"active":{"type":"boolean"},"client_id":{"type":"integer"},"competition":{"type":"number"},"cpc":{"type":"number"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"integer"},"keyword":{"type":"string"},"metrics_updated_at":{"format":"date-time","type":"string"},"search_volume":{"type":"integer"}},"title":"Keyword","type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Fetch one keyword by id, or None. Caller is responsible for verifying the keyword's client_id matches the caller's org scope.","tags":["rpc-read","search-console"]}},"/api/v1/rpc/get_keyword_ids_by_text":{"post":{"operationId":"rpc_get_keyword_ids_by_text","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"keyword_text":{"type":"string"}},"required":["keyword_text"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"type":"integer"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Get all keyword IDs that have the same keyword text (case-insensitive)","tags":["rpc-read","search-console"]}},"/api/v1/rpc/get_keywords_for_client":{"post":{"operationId":"rpc_get_keywords_for_client","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"active_only":{"default":true,"type":"boolean"},"client_id":{"type":"integer"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"properties":{"active":{"type":"boolean"},"client_id":{"type":"integer"},"competition":{"type":"number"},"cpc":{"type":"number"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"integer"},"keyword":{"type":"string"},"metrics_updated_at":{"format":"date-time","type":"string"},"search_volume":{"type":"integer"}},"title":"Keyword","type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Get all keywords for a client","tags":["rpc-read","search-console"]}},"/api/v1/rpc/get_keywords_without_pages":{"post":{"operationId":"rpc_get_keywords_without_pages","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"properties":{"active":{"type":"boolean"},"client_id":{"type":"integer"},"competition":{"type":"number"},"cpc":{"type":"number"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"integer"},"keyword":{"type":"string"},"metrics_updated_at":{"format":"date-time","type":"string"},"search_volume":{"type":"integer"}},"title":"Keyword","type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Get keywords that don't appear prominently on any page","tags":["rpc-read","search-console"]}},"/api/v1/rpc/get_last_audit_at":{"post":{"operationId":"rpc_get_last_audit_at","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"string"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Timestamp of this client's most recent audit run (newest audit_onboard job; falls back to the client row's created_at, since the original audit is what created the row). Powers the \"last audited\" column on the Audits list.","tags":["rpc-read","reports"]}},"/api/v1/rpc/get_last_gsc_keyword_capture":{"post":{"operationId":"rpc_get_last_gsc_keyword_capture","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"before_id":{"default":null,"type":"integer"},"client_id":{"type":"integer"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Return the most recent capture for a client, or None.","tags":["rpc-read","search-console"]}},"/api/v1/rpc/get_last_image_push_timestamp_for_client":{"post":{"operationId":"rpc_get_last_image_push_timestamp_for_client","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"string"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Latest wp_image_pushed_at across all blog content for a client. Returns None if no image has ever been pushed.","tags":["rpc-read","site-edits"]}},"/api/v1/rpc/get_last_n_ranks_for_keyword":{"post":{"operationId":"rpc_get_last_n_ranks_for_keyword","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"keyword_id":{"type":"integer"},"n":{"default":2,"type":"integer"}},"required":["keyword_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Last N rank_results rows for a keyword, newest first. Used to compute rank movement (e.g. n=2 \u2192 current vs previous).","tags":["rpc-read","search-console"]}},"/api/v1/rpc/get_last_scan_session":{"post":{"operationId":"rpc_get_last_scan_session","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"},"scan_type":{"default":null,"type":"string"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"properties":{"client_id":{"type":"integer"},"completed_at":{"format":"date-time","type":"string"},"id":{"type":"integer"},"keywords_checked":{"type":"integer"},"pages_scanned":{"type":"integer"},"scan_type":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"}},"title":"ScanSession","type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Get the last scan session for a client","tags":["rpc-read","monitoring"]}},"/api/v1/rpc/get_latest_meta_for_page_url":{"post":{"operationId":"rpc_get_latest_meta_for_page_url","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"},"page_url":{"type":"string"}},"required":["client_id","page_url"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Most-recent page_snapshots.meta_{title,description} for a page identified by (client_id, page_url). Returns None if no snapshot exists for that URL.","tags":["rpc-read","clients"]}},"/api/v1/rpc/get_latest_page_summaries":{"post":{"operationId":"rpc_get_latest_page_summaries","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"One row per page for a client, joined with its most recent snapshot. Returns url + meta_title + meta_description + h1_tags + word_count. Used by the progress-report summary section.","tags":["rpc-read","clients"]}},"/api/v1/rpc/get_latest_rank":{"post":{"operationId":"rpc_get_latest_rank","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"keyword_id":{"type":"integer"}},"required":["keyword_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"properties":{"id":{"type":"integer"},"keyword_id":{"type":"integer"},"location":{"type":"string"},"position":{"type":"integer"},"scan_date":{"format":"date-time","type":"string"},"search_engine":{"type":"string"},"url":{"type":"string"}},"title":"RankResult","type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Get the most recent rank for a keyword","tags":["rpc-read","search-console"]}},"/api/v1/rpc/get_latest_rank_for_keyword":{"post":{"operationId":"rpc_get_latest_rank_for_keyword","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"keyword_id":{"type":"integer"}},"required":["keyword_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Most-recent rank_results row for a keyword. Returns dict with position (and any other columns); None if no rank has been recorded yet.","tags":["rpc-read","search-console"]}},"/api/v1/rpc/get_latest_render":{"post":{"operationId":"rpc_get_latest_render","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"},"url":{"type":"string"}},"required":["client_id","url"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Most recent relayed render for (client, url): {html, meta, rendered_at}, or None. Lets callers reuse a fresh render instead of queueing another laptop round-trip.","tags":["rpc-read","monitoring"]}},"/api/v1/rpc/get_latest_snapshot":{"post":{"operationId":"rpc_get_latest_snapshot","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"page_id":{"type":"integer"}},"required":["page_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"properties":{"canonical_url":{"type":"string"},"content_hash":{"type":"string"},"h1_tags":{"items":{"type":"string"},"type":"array"},"h2_tags":{"items":{"type":"string"},"type":"array"},"h3_tags":{"items":{"type":"string"},"type":"array"},"h4_tags":{"items":{"type":"string"},"type":"array"},"h5_tags":{"items":{"type":"string"},"type":"array"},"h6_tags":{"items":{"type":"string"},"type":"array"},"id":{"type":"integer"},"meta_description":{"type":"string"},"meta_title":{"type":"string"},"og_description":{"type":"string"},"og_image":{"type":"string"},"og_title":{"type":"string"},"page_id":{"type":"integer"},"paragraph_text":{"type":"string"},"robots_meta":{"type":"string"},"scan_date":{"format":"date-time","type":"string"},"schema_markup":{"type":"string"},"word_count":{"type":"integer"}},"title":"PageSnapshot","type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Get the most recent snapshot for a page","tags":["rpc-read","monitoring"]}},"/api/v1/rpc/get_locations_for_client":{"post":{"operationId":"rpc_get_locations_for_client","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"properties":{"active":{"type":"boolean"},"client_id":{"type":"integer"},"confidence_score":{"type":"number"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"integer"},"location_name":{"type":"string"},"location_type":{"type":"string"},"source":{"type":"string"}},"title":"ClientLocation","type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"get_locations_for_client","tags":["rpc-read","clients"]}},"/api/v1/rpc/get_meta_optimization_stats":{"post":{"operationId":"rpc_get_meta_optimization_stats","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Return meta optimization counts by status.","tags":["rpc-read","action-items"]}},"/api/v1/rpc/get_meta_optimizations":{"post":{"operationId":"rpc_get_meta_optimizations","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"},"status":{"default":null,"type":"string"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"properties":{"applied_at":{"type":"string"},"client_id":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"current_description":{"type":"string"},"current_title":{"type":"string"},"detection_reason_desc":{"type":"string"},"detection_reason_title":{"type":"string"},"id":{"type":"integer"},"page_id":{"type":"integer"},"page_type":{"type":"string"},"status":{"type":"string"},"suggested_description":{"type":"string"},"suggested_title":{"type":"string"},"url":{"type":"string"}},"title":"MetaOptimization","type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Get meta optimizations for a client, optionally filtered by status.","tags":["rpc-read","action-items"]}},"/api/v1/rpc/get_month_topup_paid_cents":{"post":{"operationId":"rpc_get_month_topup_paid_cents","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"month":{"default":null,"type":"string"},"org_id":{"type":"integer"}},"required":["org_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"integer"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Sum of the actual dollars PAID for top-ups in `month` (default current), in cents \u2014 for the /billing 'this period' breakdown.","tags":["rpc-read","billing"]}},"/api/v1/rpc/get_month_topup_tokens":{"post":{"operationId":"rpc_get_month_topup_tokens","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"month":{"default":null,"type":"string"},"org_id":{"type":"integer"}},"required":["org_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"number"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Sum of token-USD bought as top-ups for `month` (default current).","tags":["rpc-read","billing"]}},"/api/v1/rpc/get_or_create_hour_budget":{"post":{"operationId":"rpc_get_or_create_hour_budget","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"allocated_hours":{"default":0,"type":"number"},"client_id":{"type":"integer"},"month":{"type":"string"}},"required":["client_id","month"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"properties":{"allocated_hours":{"type":"number"},"client_id":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"integer"},"month":{"type":"string"},"rollover_from_previous":{"type":"number"},"used_hours":{"type":"number"}},"title":"SEOHourBudget","type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Get existing budget for month, or create with allocation + rollover from previous.","tags":["rpc-write","billing"]}},"/api/v1/rpc/get_org_activity":{"post":{"operationId":"rpc_get_org_activity","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"default":null,"type":"integer"},"days":{"default":30,"type":"integer"},"limit":{"default":500,"type":"integer"},"org_id":{"type":"integer"},"user_id":{"default":null,"type":"integer"}},"required":["org_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Org activity rows (newest first) joined with the actor's email and the target client's name.","tags":["rpc-read","org-admin"]}},"/api/v1/rpc/get_org_billing_user_id":{"post":{"operationId":"rpc_get_org_billing_user_id","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"org_id":{"type":"integer"}},"required":["org_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"integer"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"The user whose id stamps metered jobs for this org \u2014 its 'owner' member, else the earliest member. A job stamped with this user runs through the worker as a real (non-service) caller, so api_client.call_or_queue meters it against the org's credit balance. Returns None if the org has no members.","tags":["rpc-read","billing"]}},"/api/v1/rpc/get_org_credit_status":{"post":{"operationId":"rpc_get_org_credit_status","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"org_id":{"type":"integer"}},"required":["org_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Credit balance + gate state for an org, for the Operations Manager billing panel. balance is whole credits (1 credit = $0.01).","tags":["rpc-read","billing"]}},"/api/v1/rpc/get_org_cycle_overview":{"post":{"operationId":"rpc_get_org_cycle_overview","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"current_month":{"type":"string"},"month":{"type":"string"},"org_id":{"type":"integer"}},"required":["org_id","month","current_month"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Per-client monthly delivery-cycle rollup for the dashboard.","tags":["rpc-read","org-admin"]}},"/api/v1/rpc/get_org_id_by_stripe_customer":{"post":{"operationId":"rpc_get_org_id_by_stripe_customer","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"customer_id":{"type":"string"}},"required":["customer_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"integer"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Reverse-lookup an org from its Stripe customer id \u2014 used by the webhook to attribute subscription/invoice events that don't carry an org_id in metadata.","tags":["rpc-read","billing"]}},"/api/v1/rpc/get_org_invoices":{"post":{"operationId":"rpc_get_org_invoices","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"limit":{"default":24,"type":"integer"},"org_id":{"type":"integer"}},"required":["org_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Recent captured Stripe invoices for an org, newest first \u2014 powers the /billing invoice-history panel.","tags":["rpc-read","org-admin"]}},"/api/v1/rpc/get_org_month_ai_spend_usd":{"post":{"operationId":"rpc_get_org_month_ai_spend_usd","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"month":{"default":null,"type":"string"},"org_id":{"type":"integer"}},"required":["org_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"number"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Total AI spend (all services: anthropic + anthropic_batch + fal) for an org in `month` (YYYY-MM, default current). Resets naturally each calendar month \u2014 there's no carryover, it's just a per-month SUM.","tags":["rpc-read","org-admin"]}},"/api/v1/rpc/get_org_reference_doc":{"post":{"operationId":"rpc_get_org_reference_doc","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"doc_id":{"type":"integer"}},"required":["doc_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"One reference doc by id (incl. org_id + deleted for caller scoping).","tags":["rpc-read","org-admin"]}},"/api/v1/rpc/get_org_reference_docs":{"post":{"operationId":"rpc_get_org_reference_docs","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"org_id":{"type":"integer"}},"required":["org_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Active reference docs for an org, newest first, with uploader email.","tags":["rpc-read","org-admin"]}},"/api/v1/rpc/get_org_revenue_series":{"post":{"operationId":"rpc_get_org_revenue_series","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"months":{"default":12,"type":"integer"},"org_id":{"type":"integer"}},"required":["org_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Per-month revenue + profit for one org (newest-last), for the platform revenue graph. revenue = paid Stripe invoices (by invoiced_at) + allowance top-ups (by month); cost = AI spend (api_costs); profit = revenue \u2212 cost. All amounts in dollars.","tags":["rpc-read","org-admin"]}},"/api/v1/rpc/get_org_token_allowance_status":{"post":{"operationId":"rpc_get_org_token_allowance_status","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"month":{"default":null,"type":"string"},"org_id":{"type":"integer"}},"required":["org_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Monthly token-allowance status for an org's shared pool.","tags":["rpc-read","billing"]}},"/api/v1/rpc/get_outstanding_summary":{"post":{"operationId":"rpc_get_outstanding_summary","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"org_id":{"type":"integer"}},"required":["org_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"One-call 'do I still have work?' rollup for the whole org. Powers the nav badge (every page), the action-items banner, AND the per-client blog 'to publish' counts + the standalone 'Blogs to publish' push targets \u2014 so all four reconcile to the same numbers. Counts: tasks = committed-but-unfinished action items (pending / in_progress) blogs = scheduled-but-unpublished articles that are DUE (this mon","tags":["rpc-read","billing"]}},"/api/v1/rpc/get_page_images":{"post":{"operationId":"rpc_get_page_images","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"page_id":{"type":"integer"}},"required":["page_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Get all images for a page.","tags":["rpc-read","images"]}},"/api/v1/rpc/get_page_intent_cache":{"post":{"operationId":"rpc_get_page_intent_cache","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"page_id":{"type":"integer"}},"required":["page_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Cached intent classification for a page. Returns dict with intent, intent_confidence, intent_reasoning, intent_classified_at, last_scanned \u2014 or None if the page row doesn't exist. Used by page_intent_classifier.classify_page for its cache hit check.","tags":["rpc-read","clients"]}},"/api/v1/rpc/get_pages_for_client":{"post":{"operationId":"rpc_get_pages_for_client","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"active_only":{"default":true,"type":"boolean"},"client_id":{"type":"integer"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"properties":{"active":{"type":"boolean"},"client_id":{"type":"integer"},"id":{"type":"integer"},"last_modified":{"type":"string"},"last_scanned":{"format":"date-time","type":"string"},"url":{"type":"string"}},"title":"Page","type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Get all pages for a client","tags":["rpc-read","clients"]}},"/api/v1/rpc/get_pages_without_keywords":{"post":{"operationId":"rpc_get_pages_without_keywords","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"properties":{"active":{"type":"boolean"},"client_id":{"type":"integer"},"id":{"type":"integer"},"last_modified":{"type":"string"},"last_scanned":{"format":"date-time","type":"string"},"url":{"type":"string"}},"title":"Page","type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Get pages that don't have any prominent keyword targeting","tags":["rpc-read","search-console"]}},"/api/v1/rpc/get_pending_batch_jobs":{"post":{"operationId":"rpc_get_pending_batch_jobs","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{},"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Get all submitted/in_progress batch jobs.","tags":["rpc-read","jobs"]}},"/api/v1/rpc/get_plugin_states":{"post":{"operationId":"rpc_get_plugin_states","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{},"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Return per-client plugin_state caches as parsed dicts.","tags":["rpc-read","site-edits"]}},"/api/v1/rpc/get_posts_needing_date_fix":{"post":{"operationId":"rpc_get_posts_needing_date_fix","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"},"only_past":{"default":false,"type":"boolean"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Exported blog posts with a scheduled_publish_date. When only_past=True, restrict to dates before today. Returns dicts with id, title, scheduled_publish_date, topic_id, ordered by scheduled_publish_date ascending. Replaces the identical raw-SQL method that used to live in blog_pusher.py.","tags":["rpc-read","content"]}},"/api/v1/rpc/get_previous_rank":{"post":{"operationId":"rpc_get_previous_rank","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"keyword_id":{"type":"integer"}},"required":["keyword_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"properties":{"id":{"type":"integer"},"keyword_id":{"type":"integer"},"location":{"type":"string"},"position":{"type":"integer"},"scan_date":{"format":"date-time","type":"string"},"search_engine":{"type":"string"},"url":{"type":"string"}},"title":"RankResult","type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Get the previous rank for a keyword (for comparison)","tags":["rpc-read","search-console"]}},"/api/v1/rpc/get_previous_snapshot":{"post":{"operationId":"rpc_get_previous_snapshot","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"page_id":{"type":"integer"}},"required":["page_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"properties":{"canonical_url":{"type":"string"},"content_hash":{"type":"string"},"h1_tags":{"items":{"type":"string"},"type":"array"},"h2_tags":{"items":{"type":"string"},"type":"array"},"h3_tags":{"items":{"type":"string"},"type":"array"},"h4_tags":{"items":{"type":"string"},"type":"array"},"h5_tags":{"items":{"type":"string"},"type":"array"},"h6_tags":{"items":{"type":"string"},"type":"array"},"id":{"type":"integer"},"meta_description":{"type":"string"},"meta_title":{"type":"string"},"og_description":{"type":"string"},"og_image":{"type":"string"},"og_title":{"type":"string"},"page_id":{"type":"integer"},"paragraph_text":{"type":"string"},"robots_meta":{"type":"string"},"scan_date":{"format":"date-time","type":"string"},"schema_markup":{"type":"string"},"word_count":{"type":"integer"}},"title":"PageSnapshot","type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Get the second most recent snapshot for a page (for comparison)","tags":["rpc-read","monitoring"]}},"/api/v1/rpc/get_projects_for_client":{"post":{"operationId":"rpc_get_projects_for_client","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"properties":{"client_id":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"integer"},"project_name":{"type":"string"},"status":{"type":"string"},"survey_id":{"type":"integer"},"template_url":{"type":"string"},"updated_at":{"format":"date-time","type":"string"}},"title":"WebsiteProject","type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"get_projects_for_client","tags":["rpc-read","clients"]}},"/api/v1/rpc/get_published_blog_content_between":{"post":{"operationId":"rpc_get_published_blog_content_between","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"},"end":{"type":"string"},"start":{"type":"string"}},"required":["client_id","start","end"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Exported blog articles whose `scheduled_publish_date` day falls in the inclusive [start, end] window ('YYYY-MM-DD' dates). The date-range analogue of `get_published_blog_content_for_month`, used by the arbitrary-period client report. `target_keywords` left as JSON string.","tags":["rpc-read","content"]}},"/api/v1/rpc/get_published_blog_content_for_month":{"post":{"operationId":"rpc_get_published_blog_content_for_month","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"},"month":{"type":"string"}},"required":["client_id","month"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Exported blog articles whose scheduled_publish_date falls in the given YYYY-MM. Joins blog_topics to surface target keywords / service / location. `target_keywords` is left as a JSON string (the report renderer is responsible for parsing it).","tags":["rpc-read","content"]}},"/api/v1/rpc/get_rank_for_date":{"post":{"operationId":"rpc_get_rank_for_date","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"keyword_id":{"type":"integer"},"target_date":{"type":"string"}},"required":["keyword_id","target_date"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"properties":{"id":{"type":"integer"},"keyword_id":{"type":"integer"},"location":{"type":"string"},"position":{"type":"integer"},"scan_date":{"format":"date-time","type":"string"},"search_engine":{"type":"string"},"url":{"type":"string"}},"title":"RankResult","type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Get rank result for a keyword closest to (but not after) the target date","tags":["rpc-read","search-console"]}},"/api/v1/rpc/get_rank_history":{"post":{"operationId":"rpc_get_rank_history","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"keyword_id":{"type":"integer"},"limit":{"default":12,"type":"integer"}},"required":["keyword_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"properties":{"id":{"type":"integer"},"keyword_id":{"type":"integer"},"location":{"type":"string"},"position":{"type":"integer"},"scan_date":{"format":"date-time","type":"string"},"search_engine":{"type":"string"},"url":{"type":"string"}},"title":"RankResult","type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Get rank history for a keyword","tags":["rpc-read","search-console"]}},"/api/v1/rpc/get_recent_topic_profile":{"post":{"operationId":"rpc_get_recent_topic_profile","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"},"days":{"default":60,"type":"integer"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Build a profile of recently covered topics for diversity scoring.","tags":["rpc-read","content"]}},"/api/v1/rpc/get_resolved_cycle_pairs":{"post":{"operationId":"rpc_get_resolved_cycle_pairs","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"org_id":{"type":"integer"}},"required":["org_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Set of (client_id, month) that are RESOLVED (final_done=1) for the org \u2014 every closed cycle, across all months. Used to decide which report-generated cycles still need a Resolve (independent of whichever month the action-items view happens to be focused on).","tags":["rpc-read","general"]}},"/api/v1/rpc/get_scheduled_blogs_in_date_range":{"post":{"operationId":"rpc_get_scheduled_blogs_in_date_range","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"},"end_iso":{"type":"string"},"start_iso":{"type":"string"}},"required":["client_id","start_iso","end_iso"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Blog content scheduled (any export state) within a date range. Returns id + scheduled_publish_date per row, ordered ascending. Used by main.py:_reschedule_plan to project existing slots.","tags":["rpc-read","content"]}},"/api/v1/rpc/get_seat_charges_for_month":{"post":{"operationId":"rpc_get_seat_charges_for_month","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"month":{"default":null,"type":"string"},"org_id":{"type":"integer"}},"required":["org_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"This month's seat-charge summary for the billing page: {count, total_cents, rows:[{client_id, client_name, amount_cents, created_at}]}.","tags":["rpc-read","billing"]}},"/api/v1/rpc/get_seat_credit":{"post":{"operationId":"rpc_get_seat_credit","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"},"month":{"type":"string"}},"required":["client_id","month"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"get_seat_credit","tags":["rpc-read","billing"]}},"/api/v1/rpc/get_seat_credits_for_org":{"post":{"operationId":"rpc_get_seat_credits_for_org","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"month":{"default":null,"type":"string"},"org_id":{"type":"integer"}},"required":["org_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Granted seat credits for an org (default: current month) \u2014 for the /billing 'credits applied next renewal' display.","tags":["rpc-read","billing"]}},"/api/v1/rpc/get_section_template":{"post":{"operationId":"rpc_get_section_template","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"template_id":{"type":"integer"}},"required":["template_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Get a single section template by ID.","tags":["rpc-read","site-edits"]}},"/api/v1/rpc/get_section_templates":{"post":{"operationId":"rpc_get_section_templates","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"category":{"default":null,"type":"string"}},"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Get all section templates, optionally filtered by category.","tags":["rpc-read","site-edits"]}},"/api/v1/rpc/get_seo_insights":{"post":{"operationId":"rpc_get_seo_insights","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"applied":{"default":null,"type":"boolean"},"client_id":{"type":"integer"},"insight_type":{"default":null,"type":"string"},"limit":{"default":50,"type":"integer"},"source":{"default":null,"type":"string"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Get SEO insights for a client.","tags":["rpc-read","action-items"]}},"/api/v1/rpc/get_services_for_client":{"post":{"operationId":"rpc_get_services_for_client","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"properties":{"active":{"type":"boolean"},"client_id":{"type":"integer"},"confidence_score":{"type":"number"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"integer"},"service_description":{"type":"string"},"service_name":{"type":"string"},"source":{"type":"string"}},"title":"ClientService","type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"get_services_for_client","tags":["rpc-read","clients"]}},"/api/v1/rpc/get_site_architecture":{"post":{"operationId":"rpc_get_site_architecture","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"The site structure this business SHOULD have, and what's missing.","tags":["rpc-read","clients"]}},"/api/v1/rpc/get_site_changes":{"post":{"operationId":"rpc_get_site_changes","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"attribution":{"default":null,"type":"string"},"client_id":{"type":"integer"},"limit":{"default":50,"type":"integer"},"since":{"default":null,"type":"string"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Get recent site changes for a client.","tags":["rpc-read","clients"]}},"/api/v1/rpc/get_site_changes_for_page":{"post":{"operationId":"rpc_get_site_changes_for_page","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"limit":{"default":20,"type":"integer"},"page_id":{"type":"integer"}},"required":["page_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Get recent changes for a specific page.","tags":["rpc-read","clients"]}},"/api/v1/rpc/get_site_edit":{"post":{"operationId":"rpc_get_site_edit","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"edit_id":{"type":"integer"}},"required":["edit_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"get_site_edit","tags":["rpc-read","site-edits"]}},"/api/v1/rpc/get_site_edits":{"post":{"operationId":"rpc_get_site_edits","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"},"status":{"default":"","type":"string"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"get_site_edits","tags":["rpc-read","site-edits"]}},"/api/v1/rpc/get_sitemap_page":{"post":{"operationId":"rpc_get_sitemap_page","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"page_id":{"type":"integer"}},"required":["page_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"integer"},"mapped_location":{"type":"string"},"mapped_service":{"type":"string"},"page_type":{"type":"string"},"parent_page_id":{"type":"integer"},"project_id":{"type":"integer"},"slug":{"type":"string"},"sort_order":{"type":"integer"},"status":{"type":"string"},"target_keyword":{"type":"string"},"template_page_id":{"type":"integer"},"title":{"type":"string"}},"title":"SiteMapPage","type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"get_sitemap_page","tags":["rpc-read","clients"]}},"/api/v1/rpc/get_sitemap_pages_for_project":{"post":{"operationId":"rpc_get_sitemap_pages_for_project","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"project_id":{"type":"integer"},"status":{"default":null,"type":"string"}},"required":["project_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"integer"},"mapped_location":{"type":"string"},"mapped_service":{"type":"string"},"page_type":{"type":"string"},"parent_page_id":{"type":"integer"},"project_id":{"type":"integer"},"slug":{"type":"string"},"sort_order":{"type":"integer"},"status":{"type":"string"},"target_keyword":{"type":"string"},"template_page_id":{"type":"integer"},"title":{"type":"string"}},"title":"SiteMapPage","type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"get_sitemap_pages_for_project","tags":["rpc-read","clients"]}},"/api/v1/rpc/get_snapshot_for_date":{"post":{"operationId":"rpc_get_snapshot_for_date","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"page_id":{"type":"integer"},"target_date":{"type":"string"}},"required":["page_id","target_date"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"properties":{"canonical_url":{"type":"string"},"content_hash":{"type":"string"},"h1_tags":{"items":{"type":"string"},"type":"array"},"h2_tags":{"items":{"type":"string"},"type":"array"},"h3_tags":{"items":{"type":"string"},"type":"array"},"h4_tags":{"items":{"type":"string"},"type":"array"},"h5_tags":{"items":{"type":"string"},"type":"array"},"h6_tags":{"items":{"type":"string"},"type":"array"},"id":{"type":"integer"},"meta_description":{"type":"string"},"meta_title":{"type":"string"},"og_description":{"type":"string"},"og_image":{"type":"string"},"og_title":{"type":"string"},"page_id":{"type":"integer"},"paragraph_text":{"type":"string"},"robots_meta":{"type":"string"},"scan_date":{"format":"date-time","type":"string"},"schema_markup":{"type":"string"},"word_count":{"type":"integer"}},"title":"PageSnapshot","type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Get snapshot for a page closest to (but not after) the target date","tags":["rpc-read","monitoring"]}},"/api/v1/rpc/get_snapshots_for_page":{"post":{"operationId":"rpc_get_snapshots_for_page","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"limit":{"default":10,"type":"integer"},"page_id":{"type":"integer"}},"required":["page_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"properties":{"canonical_url":{"type":"string"},"content_hash":{"type":"string"},"h1_tags":{"items":{"type":"string"},"type":"array"},"h2_tags":{"items":{"type":"string"},"type":"array"},"h3_tags":{"items":{"type":"string"},"type":"array"},"h4_tags":{"items":{"type":"string"},"type":"array"},"h5_tags":{"items":{"type":"string"},"type":"array"},"h6_tags":{"items":{"type":"string"},"type":"array"},"id":{"type":"integer"},"meta_description":{"type":"string"},"meta_title":{"type":"string"},"og_description":{"type":"string"},"og_image":{"type":"string"},"og_title":{"type":"string"},"page_id":{"type":"integer"},"paragraph_text":{"type":"string"},"robots_meta":{"type":"string"},"scan_date":{"format":"date-time","type":"string"},"schema_markup":{"type":"string"},"word_count":{"type":"integer"}},"title":"PageSnapshot","type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Get recent snapshots for a page","tags":["rpc-read","monitoring"]}},"/api/v1/rpc/get_survey":{"post":{"operationId":"rpc_get_survey","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"survey_id":{"type":"integer"}},"required":["survey_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"properties":{"address":{"type":"string"},"brand_colors":{"type":"string"},"brand_vibe":{"type":"string"},"brand_voice":{"type":"string"},"business_hours":{"type":"string"},"client_id":{"type":"integer"},"company_name":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"credentials":{"type":"string"},"cta_preference":{"type":"string"},"desired_features":{"type":"string"},"email":{"type":"string"},"existing_domain":{"type":"string"},"existing_website":{"type":"string"},"facebook_url":{"type":"string"},"faqs_raw":{"type":"string"},"founded_year":{"type":"string"},"general_notes":{"type":"string"},"google_business_url":{"type":"string"},"has_logo":{"type":"string"},"has_photos":{"type":"string"},"id":{"type":"integer"},"inspiration_sites":{"type":"string"},"instagram_url":{"type":"string"},"languages":{"type":"string"},"locations_raw":{"type":"string"},"other_social":{"type":"string"},"payment_methods":{"type":"string"},"phone":{"type":"string"},"preferred_contact":{"type":"string"},"pricing_notes":{"type":"string"},"services_raw":{"type":"string"},"tagline":{"type":"string"},"target_audience":{"type":"string"},"team_raw":{"type":"string"},"testimonials_raw":{"type":"string"},"usp":{"type":"string"}},"title":"ClientSurvey","type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"get_survey","tags":["rpc-read","clients"]}},"/api/v1/rpc/get_surveys_for_client":{"post":{"operationId":"rpc_get_surveys_for_client","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"properties":{"address":{"type":"string"},"brand_colors":{"type":"string"},"brand_vibe":{"type":"string"},"brand_voice":{"type":"string"},"business_hours":{"type":"string"},"client_id":{"type":"integer"},"company_name":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"credentials":{"type":"string"},"cta_preference":{"type":"string"},"desired_features":{"type":"string"},"email":{"type":"string"},"existing_domain":{"type":"string"},"existing_website":{"type":"string"},"facebook_url":{"type":"string"},"faqs_raw":{"type":"string"},"founded_year":{"type":"string"},"general_notes":{"type":"string"},"google_business_url":{"type":"string"},"has_logo":{"type":"string"},"has_photos":{"type":"string"},"id":{"type":"integer"},"inspiration_sites":{"type":"string"},"instagram_url":{"type":"string"},"languages":{"type":"string"},"locations_raw":{"type":"string"},"other_social":{"type":"string"},"payment_methods":{"type":"string"},"phone":{"type":"string"},"preferred_contact":{"type":"string"},"pricing_notes":{"type":"string"},"services_raw":{"type":"string"},"tagline":{"type":"string"},"target_audience":{"type":"string"},"team_raw":{"type":"string"},"testimonials_raw":{"type":"string"},"usp":{"type":"string"}},"title":"ClientSurvey","type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"get_surveys_for_client","tags":["rpc-read","clients"]}},"/api/v1/rpc/get_template_catalog_entry":{"post":{"operationId":"rpc_get_template_catalog_entry","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"library_client_id":{"type":"integer"},"template_id":{"type":"integer"}},"required":["library_client_id","template_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"get_template_catalog_entry","tags":["rpc-read","site-edits"]}},"/api/v1/rpc/get_template_images_report":{"post":{"operationId":"rpc_get_template_images_report","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Get a summary of template image status for a client.","tags":["rpc-read","site-edits"]}},"/api/v1/rpc/get_template_page":{"post":{"operationId":"rpc_get_template_page","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"page_id":{"type":"integer"}},"required":["page_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"properties":{"content_blocks":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"css_classes":{"type":"string"},"h1_tags":{"items":{"type":"string"},"type":"array"},"h2_tags":{"items":{"type":"string"},"type":"array"},"h3_tags":{"items":{"type":"string"},"type":"array"},"html_structure":{"type":"string"},"id":{"type":"integer"},"image_placeholders":{"type":"string"},"meta_description":{"type":"string"},"meta_title":{"type":"string"},"page_type":{"type":"string"},"project_id":{"type":"integer"},"url":{"type":"string"}},"title":"TemplatePage","type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"get_template_page","tags":["rpc-read","site-edits"]}},"/api/v1/rpc/get_template_pages_for_project":{"post":{"operationId":"rpc_get_template_pages_for_project","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"project_id":{"type":"integer"}},"required":["project_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"properties":{"content_blocks":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"css_classes":{"type":"string"},"h1_tags":{"items":{"type":"string"},"type":"array"},"h2_tags":{"items":{"type":"string"},"type":"array"},"h3_tags":{"items":{"type":"string"},"type":"array"},"html_structure":{"type":"string"},"id":{"type":"integer"},"image_placeholders":{"type":"string"},"meta_description":{"type":"string"},"meta_title":{"type":"string"},"page_type":{"type":"string"},"project_id":{"type":"integer"},"url":{"type":"string"}},"title":"TemplatePage","type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"get_template_pages_for_project","tags":["rpc-read","site-edits"]}},"/api/v1/rpc/get_total_cost":{"post":{"operationId":"rpc_get_total_cost","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"default":null,"type":"integer"},"days":{"default":null,"type":"integer"}},"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"number"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Get the total USD cost, optionally filtered by client and time range.","tags":["rpc-read","billing"]}},"/api/v1/rpc/get_unapplied_insights":{"post":{"operationId":"rpc_get_unapplied_insights","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"},"limit":{"default":10,"type":"integer"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Get unapplied SEO insights for a client, ordered by recency.","tags":["rpc-read","action-items"]}},"/api/v1/rpc/get_unapplied_seat_credits":{"post":{"operationId":"rpc_get_unapplied_seat_credits","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"org_id":{"type":"integer"}},"required":["org_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Seat credits not yet pushed to Stripe (any month) \u2014 the /billing reconcile applies these to the customer balance.","tags":["rpc-read","billing"]}},"/api/v1/rpc/get_unexported_content":{"post":{"operationId":"rpc_get_unexported_content","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"properties":{"categories":{"items":{"type":"string"},"type":"array"},"content_html":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"excerpt":{"type":"string"},"exported":{"type":"boolean"},"exported_at":{"type":"string"},"featured_image_alt":{"type":"string"},"featured_image_url":{"type":"string"},"id":{"type":"integer"},"internal_links":{"items":{"type":"object"},"type":"array"},"quality_notes":{"type":"string"},"quality_score":{"type":"number"},"scheduled_publish_date":{"type":"string"},"schema_markup":{"type":"string"},"seo_description":{"type":"string"},"seo_title":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"topic_id":{"type":"integer"},"updated_at":{"format":"date-time","type":"string"},"word_count":{"type":"integer"}},"title":"BlogContent","type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"get_unexported_content","tags":["rpc-read","content"]}},"/api/v1/rpc/get_unique_keywords_needing_metrics":{"post":{"operationId":"rpc_get_unique_keywords_needing_metrics","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"exclude_keywords":{"default":null,"type":"array"},"limit":{"default":1000,"type":"integer"}},"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Get unique keyword texts that need metrics updates, ordered by staleness. Returns list of dicts with 'keyword' and list of 'keyword_ids' sharing that text.","tags":["rpc-read","search-console"]}},"/api/v1/rpc/get_unresolved_push_failures":{"post":{"operationId":"rpc_get_unresolved_push_failures","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{},"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Return all unresolved failure rows (joined with client name).","tags":["rpc-read","site-edits"]}},"/api/v1/rpc/get_unresolved_push_failures_for_org":{"post":{"operationId":"rpc_get_unresolved_push_failures_for_org","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"limit":{"default":500,"type":"integer"},"org_id":{"type":"integer"}},"required":["org_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Org-scoped unresolved push failures for the /push-failures review page (joined with client name; newest first).","tags":["rpc-read","site-edits"]}},"/api/v1/rpc/get_unscheduled_blog_content_ids":{"post":{"operationId":"rpc_get_unscheduled_blog_content_ids","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"type":"integer"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"IDs of blog_content rows for a client that have no scheduled publish date. Returned in creation order. Used by both the interactive reschedule flow and the group-pipeline scheduler.","tags":["rpc-read","content"]}},"/api/v1/rpc/get_valid_password_reset":{"post":{"operationId":"rpc_get_valid_password_reset","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"token_hash":{"type":"string"}},"required":["token_hash"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Unused, unexpired reset row for this token hash, or None.","tags":["rpc-read","org-admin"]}},"/api/v1/rpc/get_website_project":{"post":{"operationId":"rpc_get_website_project","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"project_id":{"type":"integer"}},"required":["project_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"properties":{"client_id":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"integer"},"project_name":{"type":"string"},"status":{"type":"string"},"survey_id":{"type":"integer"},"template_url":{"type":"string"},"updated_at":{"format":"date-time","type":"string"}},"title":"WebsiteProject","type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"get_website_project","tags":["rpc-read","clients"]}},"/api/v1/rpc/has_recent_password_reset":{"post":{"operationId":"rpc_has_recent_password_reset","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"minutes":{"default":2,"type":"integer"},"user_id":{"type":"integer"}},"required":["user_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"boolean"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"True if a reset token was created for this user in the last `minutes` \u2014 the forgot-password rate limit (anti-mailbomb).","tags":["rpc-read","org-admin"]}},"/api/v1/rpc/heartbeat_aeo_agent":{"post":{"operationId":"rpc_heartbeat_aeo_agent","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"agent_id":{"type":"string"},"run_id":{"default":null,"type":"integer"}},"required":["agent_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"null"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Capture-agent protocol: mark the agent alive (and which run it is on) \u2014 a run whose agent stops heartbeating is requeued by the maintenance sweep.","tags":["rpc-write","ai-visibility"]}},"/api/v1/rpc/ingest_aeo_capture":{"post":{"operationId":"rpc_ingest_aeo_capture","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"},"convo_json":{"type":"string"},"month":{"default":"","type":"string"},"query_id":{"default":null,"type":"integer"}},"required":["client_id","convo_json"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Server-side ingest for agents: ONE RPC carrying the raw conversation. Runs aeo_tracker.ingest_capture against the local DB (the per-finding upserts stay in-process instead of ~40 remote calls per capture).","tags":["rpc-write","ai-visibility"]}},"/api/v1/rpc/is_client_in_cooldown":{"post":{"operationId":"rpc_is_client_in_cooldown","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"},"reason":{"default":null,"type":"string"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"boolean"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"is_client_in_cooldown","tags":["rpc-read","monitoring"]}},"/api/v1/rpc/is_job_cancel_requested":{"post":{"operationId":"rpc_is_job_cancel_requested","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"job_id":{"type":"integer"}},"required":["job_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"boolean"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Worker-side check \u2014 fast, single-row read.","tags":["rpc-read","jobs"]}},"/api/v1/rpc/is_runaffiliate_org":{"post":{"operationId":"rpc_is_runaffiliate_org","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"org_id":{"type":"integer"}},"required":["org_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"boolean"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"True only for orgs provisioned for the RunAffiliate / Operations Manager scope. The jobs endpoint uses this to refuse any metered (OM-triggered) run whose target is NOT in that scope \u2014 so a bug or a mistyped id can never reach the real agency clients again.","tags":["rpc-read","org-admin"]}},"/api/v1/rpc/link_survey_to_project":{"post":{"operationId":"rpc_link_survey_to_project","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"project_id":{"type":"integer"},"survey_id":{"type":"integer"}},"required":["survey_id","project_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"null"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Attach a client_surveys row to a website_projects row. Identical UPDATE used in three places in main.py \u2014 consolidating keeps the SQL in one place and gets all three callers on the RPC-safe path automatically.","tags":["rpc-write","clients"]}},"/api/v1/rpc/list_action_item_months_for_client":{"post":{"operationId":"rpc_list_action_item_months_for_client","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"type":"string"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Per-client version of list_action_item_months_for_org. Used by the per-client Delivered-window month picker so each client's dropdown only offers months that actually have data.","tags":["rpc-read","action-items"]}},"/api/v1/rpc/list_action_item_months_for_org":{"post":{"operationId":"rpc_list_action_item_months_for_org","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"org_id":{"type":"integer"}},"required":["org_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"type":"string"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Distinct YYYY-MM values present in the org's action_items.month column, newest first. Powers the fulfillment-month picker on /action-items, /jobs, and the per-client Delivered window. Excludes empty strings + NULL.","tags":["rpc-read","action-items"]}},"/api/v1/rpc/list_action_items_for_org_filtered":{"post":{"operationId":"rpc_list_action_items_for_org_filtered","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"completed_at_present":{"default":false,"type":"boolean"},"completed_since":{"default":null,"type":"string"},"month":{"default":null,"type":"string"},"org_id":{"type":"integer"},"status":{"default":null,"type":"string"}},"required":["org_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Cross-client action items in the org with optional filters.","tags":["rpc-read","action-items"]}},"/api/v1/rpc/list_ad_copy_ad_groups":{"post":{"operationId":"rpc_list_ad_copy_ad_groups","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"},"set_id":{"type":"integer"}},"required":["set_id","client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"description":"Method-specific result."}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Wire contract v1 read: shaped ad-group dicts for one OWNED set. Ownership failure returns the standard {'ok': False, 'reason'} envelope with the same wording as a missing set \u2014 no existence leak.","tags":["rpc-read","content"]}},"/api/v1/rpc/list_ad_copy_sets_for_client":{"post":{"operationId":"rpc_list_ad_copy_sets_for_client","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"},"status":{"default":"","type":"string"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Wire contract v1 read: shaped set dicts for one client, newest first (list_-prefixed: readable via the RPC prefix rule). `status` optionally filters to one lifecycle state.","tags":["rpc-read","content"]}},"/api/v1/rpc/list_all_site_edits":{"post":{"operationId":"rpc_list_all_site_edits","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"limit":{"default":200,"type":"integer"},"status":{"default":"","type":"string"}},"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Every site edit across ALL clients (newest first) with the client name attached \u2014 the portfolio audit feed Operations Manager renders. Read-only; reachable as a read RPC by the list_ prefix (service account only \u2014 org users are deny-by-default on unregistered methods, which is correct for a cross-client view).","tags":["rpc-read","site-edits"]}},"/api/v1/rpc/list_api_keys":{"post":{"operationId":"rpc_list_api_keys","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"include_revoked":{"default":false,"type":"boolean"},"org_id":{"default":null,"type":"integer"}},"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"List API keys (hashes never leave this layer).","tags":["rpc-read","org-admin"]}},"/api/v1/rpc/list_content_pages":{"post":{"operationId":"rpc_list_content_pages","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"},"status":{"default":"","type":"string"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Drafts for one client, newest first (list_-prefixed: OM's service account reads this without RPC registration).","tags":["rpc-read","site-edits"]}},"/api/v1/rpc/list_cycle_tier_a_todo":{"post":{"operationId":"rpc_list_cycle_tier_a_todo","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"month":{"type":"string"},"org_id":{"type":"integer"}},"required":["org_id","month"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Tier-A items committed to `month` that are NOT done yet (status pending/in_progress) \u2014 the fulfillment to-do list. Powers the Fulfillment Review view. Joined with client name, ordered by client + priority.","tags":["rpc-read","billing"]}},"/api/v1/rpc/list_gsc_keyword_captures":{"post":{"operationId":"rpc_list_gsc_keyword_captures","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"},"limit":{"default":20,"type":"integer"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Return recent captures for a client, newest first.","tags":["rpc-read","search-console"]}},"/api/v1/rpc/list_job_months_for_org":{"post":{"operationId":"rpc_list_job_months_for_org","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"org_id":{"type":"integer"}},"required":["org_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"type":"string"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Distinct YYYY-MM values present in jobs.created_at for an org. Powers the /jobs month picker. Newest first.","tags":["rpc-read","jobs"]}},"/api/v1/rpc/list_org_exports":{"post":{"operationId":"rpc_list_org_exports","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"org_id":{"type":"integer"}},"required":["org_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Org data exports on disk (newest first): filename, size, created_at, expires_at, download_url. Produce one with POST /api/v1/jobs {\"kind\": \"export_org\"}; files are kept 7 days.","tags":["rpc-read","org-admin"]}},"/api/v1/rpc/list_org_saml_providers":{"post":{"operationId":"rpc_list_org_saml_providers","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"org_id":{"type":"integer"}},"required":["org_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"The organization's SAML identity providers: label, IdP entity id, SSO URL, allowed_domains, default_role, active, and the SP metadata / ACS / login URLs to give the IdP (certificate included \u2014 it is public).","tags":["rpc-read","org-admin"]}},"/api/v1/rpc/list_org_sso_providers":{"post":{"operationId":"rpc_list_org_sso_providers","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"org_id":{"type":"integer"}},"required":["org_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"The organization's own identity providers (never the client secret): label, issuer, allowed_domains, default_role, active, login_url.","tags":["rpc-read","org-admin"]}},"/api/v1/rpc/list_redirects":{"post":{"operationId":"rpc_list_redirects","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"applied_only":{"default":false,"type":"boolean"},"client_id":{"type":"integer"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"List redirects for a client. applied_only=True filters to those pushed live.","tags":["rpc-read","site-edits"]}},"/api/v1/rpc/list_seat_credit_eligible":{"post":{"operationId":"rpc_list_seat_credit_eligible","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"org_id":{"type":"integer"}},"required":["org_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Inactive clients in the org eligible for an unused-seat credit this month \u2014 for the /billing 'reclaim seat credit' section.","tags":["rpc-read","billing"]}},"/api/v1/rpc/list_template_catalog":{"post":{"operationId":"rpc_list_template_catalog","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"library_client_id":{"type":"integer"},"role":{"default":"","type":"string"}},"required":["library_client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"List catalog entries for a library, optionally filtered by role.","tags":["rpc-read","site-edits"]}},"/api/v1/rpc/list_webhook_deliveries":{"post":{"operationId":"rpc_list_webhook_deliveries","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"limit":{"default":50,"type":"integer"},"org_id":{"type":"integer"},"webhook_id":{"default":null,"type":"integer"}},"required":["org_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Recent deliveries for the org (newest first): event, status, attempts, last_status_code, last_error, timestamps.","tags":["rpc-read","general"]}},"/api/v1/rpc/list_webhooks":{"post":{"operationId":"rpc_list_webhooks","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"org_id":{"type":"integer"}},"required":["org_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"The org's webhooks (url, events, active, failure_count, last success / failure, secret hint) \u2014 never the secret itself.","tags":["rpc-read","general"]}},"/api/v1/rpc/log_anthropic_call":{"post":{"operationId":"rpc_log_anthropic_call","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"batch":{"default":false,"type":"boolean"},"cache_creation_tokens":{"default":0,"type":"integer"},"cache_read_tokens":{"default":0,"type":"integer"},"client_id":{"type":"integer"},"input_tokens":{"default":0,"type":"integer"},"model":{"type":"string"},"operation":{"type":"string"},"output_tokens":{"default":0,"type":"integer"}},"required":["client_id","operation","model"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"number"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Scalar-only equivalent of log_anthropic_response.","tags":["rpc-write","billing"]}},"/api/v1/rpc/log_anthropic_response":{"post":{"operationId":"rpc_log_anthropic_response","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"batch":{"default":false,"type":"boolean"},"client_id":{"type":"integer"},"model":{"type":"string"},"operation":{"type":"string"},"response":{}},"required":["client_id","operation","model","response"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"number"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Log cost from an Anthropic API response object. Returns the cost.","tags":["rpc-write","billing"]}},"/api/v1/rpc/log_api_cost":{"post":{"operationId":"rpc_log_api_cost","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"},"cost_usd":{"default":null,"type":"number"},"input_tokens":{"default":0,"type":"integer"},"metadata":{"default":"","type":"string"},"model":{"type":"string"},"operation":{"type":"string"},"output_tokens":{"default":0,"type":"integer"},"service":{"type":"string"}},"required":["client_id","service","operation","model"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"description":"Method-specific result."}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Log an API call with cost. Auto-calculates cost if not provided. Stamps org_id via _resolve_org_id so per-org cost rollups work, and key_id (m0019) from the ambient caller context so AI spend is attributable to the API key that caused it.","tags":["rpc-write","billing"]}},"/api/v1/rpc/log_entity_change":{"post":{"operationId":"rpc_log_entity_change","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"action":{"type":"string"},"client_id":{"default":null,"type":"integer"},"entity_id":{"type":"integer"},"entity_type":{"type":"string"},"field":{"type":"string"},"new_value":{"default":"","type":"string"},"note":{"default":"","type":"string"},"old_value":{"default":"","type":"string"},"source":{"default":"","type":"string"}},"required":["entity_type","entity_id","field","action"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"description":"Method-specific result."}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Append an audit row for any tracked entity change.","tags":["rpc-write","monitoring"]}},"/api/v1/rpc/log_image_change":{"post":{"operationId":"rpc_log_image_change","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"action":{"type":"string"},"content_id":{"type":"integer"},"image_url":{"type":"string"},"note":{"default":"","type":"string"},"prompt":{"default":"","type":"string"},"source":{"default":"","type":"string"}},"required":["content_id","image_url","action"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"description":"Method-specific result."}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Append an audit entry to image_change_log.","tags":["rpc-write","images"]}},"/api/v1/rpc/log_push_failure":{"post":{"operationId":"rpc_log_push_failure","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"category":{"default":null,"type":"string"},"client_id":{"type":"integer"},"context":{"default":null,"type":"object"},"message":{"type":"string"},"operation":{"type":"string"}},"required":["client_id","operation","message"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"description":"Method-specific result."}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Record a failed WP-side push (blog_push, plugin_update, date_sync, image_refresh, trust_ip, companion_keys). Categorizes automatically if category not given. Mirrors to entity_change_log so client-level change feeds include failures.","tags":["rpc-write","site-edits"]}},"/api/v1/rpc/log_site_change":{"post":{"operationId":"rpc_log_site_change","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"attribution":{"default":"unknown","type":"string"},"change_type":{"default":"modified","type":"string"},"client_id":{"type":"integer"},"field_changed":{"default":"","type":"string"},"linked_action_id":{"default":null,"type":"integer"},"linked_action_type":{"default":null,"type":"string"},"new_summary":{"default":"","type":"string"},"old_summary":{"default":"","type":"string"},"page_id":{"default":null,"type":"integer"},"scan_session_id":{"default":null,"type":"integer"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"description":"Method-specific result."}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Log a detected site change.","tags":["rpc-write","clients"]}},"/api/v1/rpc/mark_ad_copy_set_exported":{"post":{"operationId":"rpc_mark_ad_copy_set_exported","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"},"set_id":{"type":"integer"}},"required":["set_id","client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"RPC entry (WRITE_RPCS): OM records the manual CSV export of an approved, owned set. This is a bookkeeping stamp \u2014 the export itself is a Google Ads Editor CSV downloaded in OM; nothing touches any Ads API. Re-marking an already-exported set is idempotent (ok: true, original exported_at kept).","tags":["rpc-write","content"]}},"/api/v1/rpc/mark_compare_report_converted":{"post":{"operationId":"rpc_mark_compare_report_converted","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"count":{"type":"integer"},"report_id":{"type":"integer"}},"required":["report_id","count"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"null"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Stamp a comparison report as converted-to-tasks (idempotency guard for the convert-to-tasks feature, so a second click doesn't re-create).","tags":["rpc-write","reports"]}},"/api/v1/rpc/mark_cron_trigger_done":{"post":{"operationId":"rpc_mark_cron_trigger_done","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"trigger_id":{"type":"integer"}},"required":["trigger_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"null"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Mark a cron-trigger fired (best-effort \u2014 the agent calls this after attempting the page-load regardless of outcome).","tags":["rpc-write","jobs"]}},"/api/v1/rpc/mark_image_has_alt":{"post":{"operationId":"rpc_mark_image_has_alt","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"alt_text":{"type":"string"},"client_id":{"type":"integer"},"filename":{"type":"string"}},"required":["client_id","filename","alt_text"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"description":"Method-specific result."}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Mark an image as already having alt text in WordPress. Sets status to 'has_alt' so it's skipped during analysis.","tags":["rpc-write","images"]}},"/api/v1/rpc/mark_image_synced":{"post":{"operationId":"rpc_mark_image_synced","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"content_id":{"type":"integer"},"image_url":{"type":"string"}},"required":["content_id","image_url"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"description":"Method-specific result."}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Record that WP has confirmed this URL is attached to the post.","tags":["rpc-write","images"]}},"/api/v1/rpc/mark_images_applied":{"post":{"operationId":"rpc_mark_images_applied","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"},"filenames":{"type":"array"}},"required":["client_id","filenames"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"description":"Method-specific result."}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Bulk mark images as 'applied' after PHP updater runs.","tags":["rpc-write","images"]}},"/api/v1/rpc/oauth_list_grants":{"post":{"operationId":"rpc_oauth_list_grants","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"org_id":{"type":"integer"},"user_id":{"default":null,"type":"integer"}},"required":["org_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"items":{"type":"object"},"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Connected apps: one row per live grant (app, member, scopes, created, last used, refresh expiry). `user_id` limits to one member.","tags":["rpc-read","general"]}},"/api/v1/rpc/oauth_revoke_grant":{"post":{"operationId":"rpc_oauth_revoke_grant","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"grant_id":{"type":"string"},"org_id":{"type":"integer"},"user_id":{"default":null,"type":"integer"}},"required":["org_id","grant_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"boolean"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Revoke a connected app (all its tokens). Non-owners may only revoke their own.","tags":["rpc-write","general"]}},"/api/v1/rpc/org_within_token_allowance":{"post":{"operationId":"rpc_org_within_token_allowance","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"org_id":{"type":"integer"}},"required":["org_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"boolean"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"True when the org may still consume tokens/AI this month (under 99.9%, or billing-exempt).","tags":["rpc-read","billing"]}},"/api/v1/rpc/propose_site_edits":{"post":{"operationId":"rpc_propose_site_edits","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"RPC entry: autopilot/OM asks to propose file edits for a client.","tags":["rpc-write","site-edits"]}},"/api/v1/rpc/provision_client_billing":{"post":{"operationId":"rpc_provision_client_billing","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"billing_email":{"default":"","type":"string"},"client_id":{"type":"integer"},"org_name":{"type":"string"}},"required":["client_id","org_name"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Give a client its OWN metered organization, so its AI spend draws down a dedicated credit balance instead of the platform's exempt house org. Idempotent: if the client is already in a non-exempt org that has a billing user, returns it unchanged.","tags":["rpc-write","billing"]}},"/api/v1/rpc/provision_runaffiliate_client":{"post":{"operationId":"rpc_provision_runaffiliate_client","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"billing_email":{"default":"","type":"string"},"name":{"type":"string"},"website_url":{"type":"string"}},"required":["name","website_url"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Create a NEW RankRight client inside a NEW RunAffiliate-managed, non-exempt org with a no-BYOK billing user. This is the ONLY door Operations Manager has into RankRight: it always creates fresh, so OM can never attach to a pre-existing client or org \u2014 the real agency clients are structurally out of reach.","tags":["rpc-write","clients"]}},"/api/v1/rpc/prune_rpc_audit":{"post":{"operationId":"rpc_prune_rpc_audit","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"days_keep":{"default":90,"type":"integer"}},"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"integer"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Delete rpc_audit rows older than `days_keep` days. Returns the number of rows removed. Call periodically to keep the audit table bounded \u2014 no automatic retention by default.","tags":["rpc-write","reports"]}},"/api/v1/rpc/publish_page_draft":{"post":{"operationId":"rpc_publish_page_draft","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"approved_by":{"default":"","type":"string"},"page_id":{"type":"integer"}},"required":["page_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"RPC entry: OM publishes a verified content_edit draft \u2014 flip the WP post to 'publish' via the Site Manager plugin and stamp the row.","tags":["rpc-write","clients"]}},"/api/v1/rpc/reanalyze_aeo_client":{"post":{"operationId":"rpc_reanalyze_aeo_client","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Recompute every capture's findings and rebuild the tracker from them (after an analyzer change). Statuses/notes survive by item key.","tags":["rpc-write","ai-visibility"]}},"/api/v1/rpc/redeliver_webhook":{"post":{"operationId":"rpc_redeliver_webhook","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"delivery_id":{"type":"integer"},"org_id":{"type":"integer"}},"required":["org_id","delivery_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"boolean"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Re-queue a failed or delivered delivery (same payload, same id).","tags":["rpc-write","general"]}},"/api/v1/rpc/register_aeo_agent":{"post":{"operationId":"rpc_register_aeo_agent","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"agent_id":{"type":"string"},"capabilities_json":{"type":"string"},"host":{"type":"string"},"name":{"type":"string"},"version":{"default":"","type":"string"}},"required":["agent_id","name","host","capabilities_json"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"null"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Capture-agent protocol (devices + server): announce an agent and its capabilities JSON {engines, geo, max_per_day}; idempotent upsert by agent_id.","tags":["rpc-write","ai-visibility"]}},"/api/v1/rpc/register_webhook":{"post":{"operationId":"rpc_register_webhook","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"description":{"default":"","type":"string"},"events":{"default":null,"type":"array"},"org_id":{"type":"integer"},"url":{"type":"string"}},"required":["org_id","url"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Register an outbound webhook for the org: an https URL and the events it wants (names from the webhooks catalog, or '*' for all). Returns the hook with its signing `secret` \u2014 shown ONCE; later reads only carry a hint. Verify deliveries with the X-RankRight-Signature header (HMAC-SHA256 of '<timestamp>.<body>').","tags":["rpc-write","general"]}},"/api/v1/rpc/reject_ad_copy_set":{"post":{"operationId":"rpc_reject_ad_copy_set","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"},"reason":{"default":"","type":"string"},"rejected_by":{"default":"","type":"string"},"set_id":{"type":"integer"}},"required":["set_id","client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"RPC entry (WRITE_RPCS): OM rejects a proposed, owned set. `reason` is REQUIRED non-empty engine-side (review Low-1) \u2014 a reasonless rejection tells the next run nothing to improve. Only a 'proposed' set may be rejected.","tags":["rpc-write","content"]}},"/api/v1/rpc/reject_site_edit":{"post":{"operationId":"rpc_reject_site_edit","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"edit_id":{"type":"integer"}},"required":["edit_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"reject_site_edit","tags":["rpc-write","site-edits"]}},"/api/v1/rpc/requeue_failed_aeo_runs":{"post":{"operationId":"rpc_requeue_failed_aeo_runs","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"default":null,"type":"integer"},"org_id":{"default":null,"type":"integer"}},"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"integer"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Operator retry: failed runs back to the queue with a fresh attempt budget.","tags":["rpc-write","ai-visibility"]}},"/api/v1/rpc/requeue_stale_aeo_runs":{"post":{"operationId":"rpc_requeue_stale_aeo_runs","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"lease_minutes":{"default":null,"type":"integer"}},"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"integer"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Daily-sweep / safety net: runs claimed or running whose heartbeat is older than the lease go back to the queue (or fail after max attempts).","tags":["rpc-write","ai-visibility"]}},"/api/v1/rpc/resolve_all_push_failures":{"post":{"operationId":"rpc_resolve_all_push_failures","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"note":{"default":"manual clear-all","type":"string"}},"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"integer"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Mark every unresolved failure resolved.","tags":["rpc-write","site-edits"]}},"/api/v1/rpc/resolve_push_failure":{"post":{"operationId":"rpc_resolve_push_failure","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"failure_id":{"type":"integer"},"note":{"default":"manual","type":"string"}},"required":["failure_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"boolean"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Mark one failure row resolved.","tags":["rpc-write","site-edits"]}},"/api/v1/rpc/revoke_api_key":{"post":{"operationId":"rpc_revoke_api_key","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"key_id":{"type":"integer"},"org_id":{"default":null,"type":"integer"}},"required":["key_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"boolean"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Revoke a key (idempotent). org_id=None => operator: any key. org_id set (injected for org callers) => only that org's keys \u2014 an owner can't revoke partner keys or another org's keys. Returns True if a live key was revoked this call.","tags":["rpc-write","org-admin"]}},"/api/v1/rpc/revoke_client_access":{"post":{"operationId":"rpc_revoke_client_access","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"RPC entry: offboarding \u2014 give back the access a client granted us.","tags":["rpc-write","clients"]}},"/api/v1/rpc/rollback_site_edit":{"post":{"operationId":"rpc_rollback_site_edit","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"actor":{"default":"","type":"string"},"edit_id":{"type":"integer"}},"required":["edit_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"RPC entry: OM reverts an applied change \u2014 restore the backup over the live file and confirm byte-for-byte. 'elementor_rewrite' rows carry their pre-image in the payload instead of a file backup, so they revert by pushing the recorded before-settings back.","tags":["rpc-write","site-edits"]}},"/api/v1/rpc/rotate_webhook_secret":{"post":{"operationId":"rpc_rotate_webhook_secret","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"org_id":{"type":"integer"},"webhook_id":{"type":"integer"}},"required":["org_id","webhook_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Issue a new signing secret (returned once); the old one stops validating immediately.","tags":["rpc-write","general"]}},"/api/v1/rpc/save_action_item":{"post":{"operationId":"rpc_save_action_item","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"item":{}},"required":["item"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"integer"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Insert or update an SEO action item. Returns its ID.","tags":["rpc-write","action-items"]}},"/api/v1/rpc/save_aeo_capture":{"post":{"operationId":"rpc_save_aeo_capture","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"captured_at":{"default":null,"type":"string"},"client_id":{"type":"integer"},"engine":{"type":"string"},"month":{"type":"string"},"org_id":{"type":"integer"},"prompt":{"type":"string"},"query_id":{"type":"integer"},"record_json":{"default":"","type":"string"},"report_json":{"default":"","type":"string"}},"required":["org_id","client_id","query_id","month","engine","prompt"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"integer"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Low-level: store an already-analyzed capture row. Agents should call ingest_aeo_capture (raw conversation in, analysis + items out) instead.","tags":["rpc-write","ai-visibility"]}},"/api/v1/rpc/save_aeo_item":{"post":{"operationId":"rpc_save_aeo_item","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"item":{"type":"object"}},"required":["item"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"integer"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Insert (no `id`) or partial-update (with `id`) an aeo_items row. Only known columns are written; unknown keys are ignored.","tags":["rpc-write","ai-visibility"]}},"/api/v1/rpc/save_compare_report":{"post":{"operationId":"rpc_save_compare_report","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"},"competitor_id":{"type":"integer"},"focus":{"type":"string"},"html":{"type":"string"},"org_id":{"type":"integer"},"title":{"type":"string"}},"required":["org_id","client_id","competitor_id","focus","title","html"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"integer"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Store an A/B comparison report; returns its id.","tags":["rpc-write","reports"]}},"/api/v1/rpc/save_page_intent":{"post":{"operationId":"rpc_save_page_intent","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"confidence":{"type":"number"},"intent":{"type":"string"},"page_id":{"type":"integer"},"reasoning":{"default":"","type":"string"}},"required":["page_id","intent","confidence"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"null"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Persist intent classification result. Sets intent_classified_at = now(). Replaces the inline `_save` helper in page_intent_classifier that took a raw connection.","tags":["rpc-write","clients"]}},"/api/v1/rpc/save_section_template":{"post":{"operationId":"rpc_save_section_template","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"category":{"type":"string"},"description":{"type":"string"},"name":{"type":"string"},"preview_text":{"default":"","type":"string"},"slots_json":{"type":"string"},"source_client_id":{"default":null,"type":"integer"},"source_wp_post_id":{"default":null,"type":"integer"},"template_json":{"type":"string"}},"required":["name","category","description","template_json","slots_json"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"integer"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Save a section template and return its ID.","tags":["rpc-write","site-edits"]}},"/api/v1/rpc/set_ad_copy_ad_group_excluded":{"post":{"operationId":"rpc_set_ad_copy_ad_group_excluded","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"},"excluded":{"default":1,"type":"integer"},"group_id":{"type":"integer"}},"required":["group_id","client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"RPC entry (WRITE_RPCS): operator drops (or restores) one weak group while the owning set is still 'proposed'. An approved or exported set is a frozen artifact (review H4): what the operator approved is what gets exported, byte for byte \u2014 no post-approval edits through any path. Ownership chains group -> set -> client; a group under another client's set answers like a missing group.","tags":["rpc-write","content"]}},"/api/v1/rpc/set_aeo_cadence":{"post":{"operationId":"rpc_set_aeo_cadence","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"},"enabled":{"default":true,"type":"boolean"},"engines":{"default":null,"type":"array"},"geo_state":{"default":"","type":"string"},"samples_per_month":{"default":1,"type":"integer"}},"required":["client_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Enrol a client in monthly AI-engine capture. samples_per_month 1-10; engines any of 'chatgpt-web' (operator device fleet), 'claude', 'openai', 'gemini' (server-side official APIs); geo_state = two-letter US state a device must sit in ('' = any); enabled=False pauses the client and cancels its queued runs. Returns the stored cadence.","tags":["rpc-write","ai-visibility"]}},"/api/v1/rpc/set_client_setting":{"post":{"operationId":"rpc_set_client_setting","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"},"key":{"type":"string"},"value":{"type":"string"}},"required":["client_id","key","value"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"description":"Method-specific result."}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Set a per-client setting value.","tags":["rpc-write","clients"]}},"/api/v1/rpc/set_featured_image_prompt":{"post":{"operationId":"rpc_set_featured_image_prompt","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"prompt":{"type":"string"},"topic_id":{"type":"integer"}},"required":["topic_id","prompt"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"null"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Cache the Haiku-generated featured image prompt on a blog topic.","tags":["rpc-write","images"]}},"/api/v1/rpc/start_aeo_run":{"post":{"operationId":"rpc_start_aeo_run","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"agent_id":{"type":"string"},"run_id":{"type":"integer"}},"required":["run_id","agent_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"null"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Capture-agent protocol: a claimed run has started executing on this agent.","tags":["rpc-write","ai-visibility"]}},"/api/v1/rpc/start_scan_session":{"post":{"operationId":"rpc_start_scan_session","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"},"scan_type":{"type":"string"}},"required":["client_id","scan_type"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"integer"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Start a new scan session","tags":["rpc-write","monitoring"]}},"/api/v1/rpc/test_webhook":{"post":{"operationId":"rpc_test_webhook","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"org_id":{"type":"integer"},"webhook_id":{"type":"integer"}},"required":["org_id","webhook_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Queue a `ping` delivery to one webhook (the Test button).","tags":["rpc-write","general"]}},"/api/v1/rpc/update_action_item_status":{"post":{"operationId":"rpc_update_action_item_status","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"_caller_module":{"default":null,"type":"string"},"completed_at":{"default":null,"type":"string"},"item_id":{"type":"integer"},"manual_note":{"default":null,"type":"string"},"status":{"type":"string"}},"required":["item_id","status"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"description":"Method-specific result."}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Update an action item's status.","tags":["rpc-write","action-items"]}},"/api/v1/rpc/update_aeo_capture_report":{"post":{"operationId":"rpc_update_aeo_capture_report","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"capture_id":{"type":"integer"},"report_json":{"type":"string"}},"required":["capture_id","report_json"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"null"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Low-level: overwrite one capture's analysis JSON (used by reanalyze_aeo_client).","tags":["rpc-write","ai-visibility"]}},"/api/v1/rpc/update_aeo_item_status":{"post":{"operationId":"rpc_update_aeo_item_status","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"default":null,"type":"integer"},"item_id":{"type":"integer"},"note":{"default":"","type":"string"},"status":{"type":"string"}},"required":["item_id","status"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"null"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Set a tracker item's status: 'open' | 'in_progress' | 'done' | 'dismissed' ('resolved' is reserved for the auto-resolver). `note` is appended, dated, to the item's history rather than replacing it. `client_id` (required over the org-scoped RPC) pins the item to that client so a partner key can never touch another client's item.","tags":["rpc-write","ai-visibility"]}},"/api/v1/rpc/update_aeo_query":{"post":{"operationId":"rpc_update_aeo_query","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"active":{"default":null,"type":"boolean"},"priority":{"default":null,"type":"integer"},"prompt":{"default":null,"type":"string"},"query_id":{"type":"integer"},"service":{"default":null,"type":"string"}},"required":["query_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"null"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Operator edits to a question row (toggle / reprioritise / relabel).","tags":["rpc-write","ai-visibility"]}},"/api/v1/rpc/update_client":{"post":{"operationId":"rpc_update_client","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client":{}},"required":["client"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"description":"Method-specific result."}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Update a client \u2014 saves all editable fields","tags":["rpc-write","clients"]}},"/api/v1/rpc/update_content_schedule":{"post":{"operationId":"rpc_update_content_schedule","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"content_id":{"type":"integer"},"publish_date":{"type":"string"}},"required":["content_id","publish_date"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"description":"Method-specific result."}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"update_content_schedule","tags":["rpc-write","content"]}},"/api/v1/rpc/update_elementor_image_description":{"post":{"operationId":"rpc_update_elementor_image_description","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"description":{"type":"string"},"entry_id":{"type":"integer"}},"required":["entry_id","description"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"null"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Update the AI-edited content_description on a row in elementor_image_catalog. Called from the interactive elementor image regeneration menu.","tags":["rpc-write","site-edits"]}},"/api/v1/rpc/update_hour_budget_used":{"post":{"operationId":"rpc_update_hour_budget_used","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"action_type":{"default":null,"type":"string"},"client_id":{"type":"integer"},"hours_delta":{"type":"number"},"month":{"type":"string"}},"required":["client_id","month","hours_delta"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"description":"Method-specific result."}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Add hours_delta to used_hours for the given month. Blog topics are tracked separately from the on-page SEO budget and skipped here.","tags":["rpc-write","billing"]}},"/api/v1/rpc/update_image_alt_text":{"post":{"operationId":"rpc_update_image_alt_text","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"alt_text":{"type":"string"},"image_id":{"type":"integer"}},"required":["image_id","alt_text"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"description":"Method-specific result."}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Update just the alt_text field (for manual edits).","tags":["rpc-write","images"]}},"/api/v1/rpc/update_image_status":{"post":{"operationId":"rpc_update_image_status","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"alt_text":{"default":null,"type":"string"},"image_id":{"type":"integer"},"status":{"type":"string"}},"required":["image_id","status"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"description":"Method-specific result."}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Update image status and optionally set alt_text + timestamps.","tags":["rpc-write","images"]}},"/api/v1/rpc/update_image_type":{"post":{"operationId":"rpc_update_image_type","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"image_id":{"type":"integer"},"image_type":{"type":"string"},"wp_attachment_id":{"default":null,"type":"integer"}},"required":["image_id","image_type"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"description":"Method-specific result."}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Update the image type (product/page/other) and optionally WP attachment ID.","tags":["rpc-write","images"]}},"/api/v1/rpc/update_org_saml_provider":{"post":{"operationId":"rpc_update_org_saml_provider","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"active":{"default":null,"type":"boolean"},"allow_unsolicited":{"default":null,"type":"boolean"},"allowed_domains":{"default":null,"type":"array"},"certificate":{"default":null,"type":"string"},"default_role":{"default":null,"type":"string"},"label":{"default":null,"type":"string"},"org_id":{"type":"integer"},"provider_id":{"type":"integer"}},"required":["org_id","provider_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Enable/disable, change domains, default role, certificate (rotation), IdP-initiated flag or label.","tags":["rpc-write","org-admin"]}},"/api/v1/rpc/update_org_sso_provider":{"post":{"operationId":"rpc_update_org_sso_provider","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"active":{"default":null,"type":"boolean"},"allowed_domains":{"default":null,"type":"array"},"client_secret":{"default":null,"type":"string"},"default_role":{"default":null,"type":"string"},"label":{"default":null,"type":"string"},"org_id":{"type":"integer"},"provider_id":{"type":"integer"}},"required":["org_id","provider_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Enable/disable, change domains, default role, secret or label.","tags":["rpc-write","org-admin"]}},"/api/v1/rpc/update_organization_branding":{"post":{"operationId":"rpc_update_organization_branding","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"brand_accent":{"default":"","type":"string"},"brand_logo_url":{"default":"","type":"string"},"brand_name":{"default":"","type":"string"},"org_id":{"type":"integer"}},"required":["org_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"null"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"White-label: the name/logo/accent partners' clients see on reports.","tags":["rpc-write","ai-visibility"]}},"/api/v1/rpc/update_page_scanned":{"post":{"operationId":"rpc_update_page_scanned","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"last_modified":{"default":null,"type":"string"},"page_id":{"type":"integer"}},"required":["page_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"description":"Method-specific result."}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Update the last_scanned timestamp for a page, optionally storing last_modified.","tags":["rpc-write","clients"]}},"/api/v1/rpc/update_project_status":{"post":{"operationId":"rpc_update_project_status","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"project_id":{"type":"integer"},"status":{"type":"string"}},"required":["project_id","status"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"description":"Method-specific result."}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"update_project_status","tags":["rpc-write","clients"]}},"/api/v1/rpc/update_webhook":{"post":{"operationId":"rpc_update_webhook","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"active":{"default":null,"type":"boolean"},"description":{"default":null,"type":"string"},"events":{"default":null,"type":"array"},"org_id":{"type":"integer"},"url":{"default":null,"type":"string"},"webhook_id":{"type":"integer"}},"required":["org_id","webhook_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Change a webhook's url / events / active flag / description. Re-activating resets the consecutive failure counter.","tags":["rpc-write","general"]}},"/api/v1/rpc/upsert_aeo_queries":{"post":{"operationId":"rpc_upsert_aeo_queries","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"},"engine":{"type":"string"},"org_id":{"type":"integer"},"rows":{"type":"array"}},"required":["org_id","client_id","engine","rows"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"object"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Batch form of upsert_aeo_query for the generator - the whole question set in one call/one connection (the remote API rate-limits per request). Same rules per row. Returns {'created': n, 'updated': n}.","tags":["rpc-write","ai-visibility"]}},"/api/v1/rpc/upsert_aeo_query":{"post":{"operationId":"rpc_upsert_aeo_query","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"active":{"type":"boolean"},"client_id":{"type":"integer"},"engine":{"type":"string"},"kind":{"type":"string"},"org_id":{"type":"integer"},"priority":{"type":"integer"},"prompt":{"type":"string"},"service":{"type":"string"},"source":{"type":"string"}},"required":["org_id","client_id","prompt","engine","service","kind","priority","source","active"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"type":"array"}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Generator upsert. New prompt \u2192 row with these defaults. Existing prompt \u2192 fill in service/kind/source where the row only knew it from a capture, but NEVER touch `active` / `priority` (operator-owned once the row exists). Returns [id, created].","tags":["rpc-write","ai-visibility"]}},"/api/v1/rpc/upsert_elementor_page":{"post":{"operationId":"rpc_upsert_elementor_page","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"blocks_data":{"type":"string"},"builder":{"type":"string"},"content_hash":{"default":"","type":"string"},"elementor_data":{"type":"string"},"featured_image":{"type":"string"},"menu_order":{"type":"integer"},"modified_gmt":{"default":"","type":"string"},"parent_id":{"type":"integer"},"post_type":{"type":"string"},"project_id":{"type":"integer"},"seo_data":{"type":"string"},"slug":{"type":"string"},"template":{"type":"string"},"title":{"type":"string"},"url":{"type":"string"},"widget_summary":{"type":"string"},"wp_post_id":{"type":"integer"}},"required":["project_id","wp_post_id","title","slug","url","post_type","builder","template","parent_id","menu_order","seo_data","featured_image","elementor_data","widget_summary","blocks_data"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"description":"Method-specific result."}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Insert or update an exported Elementor page.","tags":["rpc-write","site-edits"]}},"/api/v1/rpc/upsert_keyword_page_association":{"post":{"operationId":"rpc_upsert_keyword_page_association","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"found_in_body":{"default":false,"type":"boolean"},"found_in_h1":{"default":false,"type":"boolean"},"found_in_h2":{"default":false,"type":"boolean"},"found_in_h3":{"default":false,"type":"boolean"},"found_in_meta_desc":{"default":false,"type":"boolean"},"found_in_title":{"default":false,"type":"boolean"},"keyword_id":{"type":"integer"},"occurrence_count":{"default":0,"type":"integer"},"page_id":{"type":"integer"},"prominence_score":{"default":0,"type":"number"}},"required":["keyword_id","page_id"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"description":"Method-specific result."}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Insert or update a keyword-page association","tags":["rpc-write","search-console"]}},"/api/v1/rpc/upsert_page_images":{"post":{"operationId":"rpc_upsert_page_images","parameters":[{"description":"Opaque key (max 200 chars) that makes this POST safely retryable: replays within 24h return the stored response with Idempotency-Replayed: true.","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"client_id":{"type":"integer"},"images":{"type":"array"},"is_first_scan":{"default":false,"type":"boolean"},"page_id":{"type":"integer"}},"required":["client_id","page_id","images"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"result":{"description":"Method-specific result."}},"required":["result"],"type":"object"}}},"description":"RPC result (shape is method-specific)."},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error envelope."}},"security":[{"bearerAuth":[]},{"oauth2":["read"]}],"summary":"Insert or update page images from a scan.","tags":["rpc-write","images"]}},"/oauth/authorize":{"get":{"operationId":"oauth_authorize","responses":{"302":{"description":"Redirect to redirect_uri with code or error."}},"security":[],"summary":"Consent page: response_type=code, client_id, redirect_uri, scope, state, code_challenge (S256), optional resource. Redirects back with code + state.","tags":["org-admin"]}},"/oauth/register":{"post":{"operationId":"oauth_register","requestBody":{"content":{"application/json":{"schema":{"properties":{"client_name":{"type":"string"},"redirect_uris":{"items":{"type":"string"},"type":"array"},"token_endpoint_auth_method":{"enum":["none","client_secret_basic","client_secret_post"],"type":"string"}},"required":["redirect_uris"],"type":"object"}}}},"responses":{"201":{"description":"client_id (+ client_secret for confidential clients)."}},"security":[],"summary":"Dynamic client registration (RFC 7591): public clients with https / loopback redirect URIs.","tags":["org-admin"]}},"/oauth/revoke":{"post":{"operationId":"oauth_revoke","responses":{"200":{"description":"Always 200."}},"security":[],"summary":"Revoke an access or refresh token (RFC 7009); revoking either kills the grant.","tags":["org-admin"]}},"/oauth/token":{"post":{"operationId":"oauth_token","requestBody":{"content":{"application/x-www-form-urlencoded":{"schema":{"properties":{"client_id":{"type":"string"},"client_secret":{"type":"string"},"code":{"type":"string"},"code_verifier":{"type":"string"},"grant_type":{"enum":["authorization_code","refresh_token"],"type":"string"},"redirect_uri":{"type":"string"},"refresh_token":{"type":"string"}},"required":["grant_type","client_id"],"type":"object"}}}},"responses":{"200":{"description":"access_token (rro_, 1 h), token_type, expires_in, scope, refresh_token?"},"400":{"description":"OAuth error object {error, error_description}."}},"security":[],"summary":"Token endpoint: grant_type=authorization_code (+ code_verifier) or refresh_token (rotating).","tags":["org-admin"]}}},"servers":[{"url":"https://app.rankright.dev"}],"tags":[{"description":"Read-only RPCs (any key scope).","name":"rpc-read"},{"description":"Mutating RPCs (need the write scope).","name":"rpc-write"},{"description":"AI Visibility (AEO): whether AI answer engines name and cite a client, the capture queue, the tracker, white-label reports.","name":"ai-visibility"},{"description":"Plain-English site edits, staged pages, templates and CMS pushes.","name":"site-edits"},{"description":"Image catalog, alt text and sync state.","name":"images"},{"description":"Blog / content pipeline and ad copy.","name":"content"},{"description":"Google Search Console data, rankings and keyword research.","name":"search-console"},{"description":"The prioritized per-page action list, insights and strategy runs.","name":"action-items"},{"description":"Site snapshots, change history, scans and operational errors.","name":"monitoring"},{"description":"Client reports and audits.","name":"reports"},{"description":"Competitor monitoring.","name":"competitors"},{"description":"Background jobs and worker agents.","name":"jobs"},{"description":"Billing, credits, AI-spend metering and batch requests.","name":"billing"},{"description":"Organizations, members, API keys and account security.","name":"org-admin"},{"description":"Client records, pages, locations, services and schema facts.","name":"clients"},{"description":"Everything not covered by a domain tag.","name":"general"}],"x-workflows":[{"name":"AI Visibility (AEO) for a client","steps":["add_client (or use an existing client_id) with website_url, services and locations filled in","generate_aeo_questions(client_id) \u2014 builds the buyer-style question set from the client's services/locations (get_aeo_queries to review; update_aeo_query to activate/deactivate)","set_aeo_cadence(client_id, samples_per_month=1, engines=['claude', 'chatgpt-web']) \u2014 enrols the client; the daily sweep queues runs, or call enqueue_due_aeo_runs(client_id=...) now","wait: server-API engines (claude/openai/gemini) answer within minutes; chatgpt-web runs when an operator device is online \u2014 get_aeo_run_stats(client_id) shows progress","get_aeo_summary(client_id) \u2014 presence / named-first per service, open tasks, queue, cadence","get_aeo_items(client_id, status=\"open\") \u2014 the action list: tier A/B = website work, C = Google Business / directory / review work, X = market-driven (tracked, not promised)","update_aeo_item_status(item_id, \"done\", client_id=...) as work completes","aeo_report_html(client_id, month) \u2014 white-label monthly report (update_organization_branding sets the name/logo/accent it carries)"],"summary":"Find out whether AI answer engines (ChatGPT, Claude, OpenAI, Gemini) name and cite a client for buyer questions, track what to fix, and report monthly. All calls are org-scoped by client_id."},{"name":"Export your organization","steps":["POST /api/v1/jobs {\"kind\": \"export_org\"} (owner key; a service account adds \"org_id\") \u2192 202 {job_id, status_url}","poll GET /api/v1/jobs/<id> until status is done \u2014 result.download_url and result.counts are there (or subscribe to the job.completed webhook)","GET /api/v1/exports/<org_id>/<filename> with the same key \u2192 the zip (kept 7 days; list_org_exports shows what exists)"],"summary":"Data portability in one call: every table the organization owns as JSON + CSV, plus filed report files, in a zip with a manifest (secrets excluded)."},{"name":"Plain-English site edit","steps":["POST /api/v1/jobs {\"kind\": \"prompted_edit\", \"client_id\": N, \"payload\": {\"instruction\": \"...\"}}","poll GET /api/v1/jobs/<id> until done; result.pages[].edit_id lists the staged edits","apply_site_edit(edit_id) to publish, rollback_site_edit(edit_id) to undo"],"summary":"Stage an edit to a client site from an instruction, then approve or undo it."}]}
