Optimize API endpoint
Start, poll, and retrieve durable asynchronous Rankability Optimize analyses with retry-safe usage accounting.
Use Optimize to score one existing public page against current search competitors for a target keyword. Agent API and MCP runs are asynchronous and durable: the start request returns an optimization_id immediately, and the result remains available through get and list operations.
This is separate from a persistent Copywriter existing-content project. Optimize saves the scoring run and its evidence, but it does not create or edit a Copywriter draft.
Scope and usage
Section titled “Scope and usage”The key needs optimize:run. Before starting work, read GET /api/agent/v1/usage and estimate optimize_page with GET /api/agent/v1/usage/estimate?operation=optimize_page.
POST https://app.rankability.com/api/agent/v1/optimizeA stable Idempotency-Key is required. Repeating the same logical request with the same key returns the same durable run and cannot create a second reservation or provider run.
Start a run
Section titled “Start a run”curl -X POST https://app.rankability.com/api/agent/v1/optimize \ -H "Authorization: Bearer rk_live_YOUR_KEY" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: optimize-example-seo-guide-v1" \ -d '{ "url": "https://example.com/seo-guide", "keyword": "seo guide", "language": "en-US", "client_id": "4746d28b-0a38-43f9-a1ca-5e8402ef73d4" }'| Field | Required | Behavior |
|---|---|---|
url |
Yes | Public HTTP or HTTPS page to score |
keyword |
Yes | Target query used for competitor research and scoring |
language |
No | Language code up to 10 characters; defaults to en-US |
client_id |
No | Organization-owned client used to attribute and filter run history |
Private IP ranges, localhost, link-local addresses, .local or .internal hosts, and cloud metadata targets are rejected before a reservation or job is created.
The accepted response is 202:
{ "optimization_id": "opt-0123456789abcdef", "status": "queued", "client_id": "4746d28b-0a38-43f9-a1ca-5e8402ef73d4", "url": "https://example.com/seo-guide", "keyword": "seo guide", "language": "en-US", "created_at": "2026-08-24T20:00:00.000Z", "started_at": null, "completed_at": null, "error": null}Poll and retrieve the result
Section titled “Poll and retrieve the result”Use the status view while work is queued or running:
GET /api/agent/v1/optimizations/:optimization_id?view=statusStatuses are queued, running, complete, or failed. After completion, request view=summary for the score, source word count, competitor count, duration, and billing finalization state. Use view=full only when the complete entity, category, scoring, and competitor evidence is needed.
GET /api/agent/v1/optimizations/:optimization_id?view=fullThe full response returns the saved upstream Optimize result under result. A successful result can include rankabilityScore, categoryScores, scoreDetails, entities, sourceWordCount, competitorCount, competitors, and duration.
Competitor pages that cannot be fetched are omitted. A smaller comparison set means less evidence; it does not mean Rankability verified every result page. Scores are dated observations because search results and page content change.
List past runs
Section titled “List past runs”GET /api/agent/v1/optimizations?client_id=:clientId&status=complete&limit=25&offset=0History is organization-scoped, newest first, and capped at 100 rows per page. Optional filters are client_id, status, keyword, and url. List results are summaries and do not repeat full result payloads.
Failure and retry behavior
Section titled “Failure and retry behavior”Failed provider work releases the run’s reservation. Successful work finalizes that same reservation once. If finalization needs reconciliation after a usable result exists, the artifact remains available with billing_status: reconciliation_pending; the system does not create an unrelated second debit.
Do not repeatedly poll the full view. Poll status with a bounded interval, then retrieve the full result once. A terminal failed run remains auditable; use a new idempotency key only when the user approves a genuinely new attempt.
| Status | Code or state | Action |
|---|---|---|
400 |
validation_error |
Correct invalid or unsafe input |
400 |
idempotency_key_required |
Supply one stable retry key |
401 |
unauthorized |
Replace or correct the key |
403 |
forbidden |
Grant optimize:run |
404 |
not_found |
Confirm the run belongs to the active organization |
429 |
usage_limit_reached or rate_limit_exceeded |
Wait until the returned recovery time |
| terminal | failed |
Read the saved error and start a separately approved retry with a new key |
See API usage, rate limits, and errors for the shared approval and usage contract.
