Skip to content

API

Create checks and read verdicts from your own system, and track keyword positions the same way. Same credits, same answers, same endpoints the app uses — there is no separate API to fall out of step.

Base URL https://api.indexaction.com/api/v1

Authentication

Create a key in your account under API, then send it as a bearer-style header. The key is shown once at creation — only a hash is stored, so it cannot be recovered afterwards. Rate limits apply per key, so one integration can never starve another.

Authorization: Api-Key ia_live_xxxxxxxxxxxxxxxx

Create a check

Duplicates and invalid lines are removed before anything is charged, and the response tells you what was dropped. Send an Idempotency-Key and a retried request resolves to the same check instead of charging twice.

curl https://api.indexaction.com/api/v1/checks/ \
  -H "Authorization: Api-Key YOUR_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "urls": [
      "https://example.com/page-1",
      "https://example.com/page-2"
    ],
    "name": "June batch"
  }'

Returns 201 with the check, initially queued:

{
  "id": "55c79216-28fd-4c54-b813-14bb210d6fae",
  "status": "queued",
  "total_count": 2,
  "processed_count": 0,
  "credits_used": "2.00",
  "input_report": { "submitted": 2, "accepted": 2, "duplicates": 0, "invalid": 0 },
  "results": []
}

Read the results

Poll until status is succeeded, failed or canceled. Partial results are available while it runs, so you can stream progress. A second or two between polls is plenty.

{
  "status": "succeeded",
  "total_count": 2,
  "indexed_count": 1,
  "not_indexed_count": 1,
  "error_count": 0,
  "indexed_pct": 50.0,
  "credits_used": "2.00",
  "credits_refunded": "0.00",
  "results": [
    { "url": "https://example.com/page-1", "status": "indexed",
      "note": "Found in Google",
      "matches": [{ "link": "https://example.com/page-1", "title": "Page 1" }] },
    { "url": "https://example.com/page-2", "status": "not_indexed",
      "note": "Google returned no result", "matches": [] }
  ]
}

Verdicts

Three values, and the third one matters. Most tools collapse a failed check into “not indexed”, which sends you chasing a problem that may not exist.

indexed

Google returned the page — at the exact URL, or the same page under its canonical URL.

not_indexed

Google returned no result in any query form we try. Established by an individual query, not inferred.

error

We could not determine it — a timeout or an upstream failure. Treat as unknown, never as missing. This credit is refunded.

indexed_pct excludes errors from its denominator: a run where half the checks failed should not report a halved index rate.

Rank tracking

A rank project is a domain, its keywords, and where to look: a market (gl country + hl language), a device, and a depth of 10, 30 or 100. One check scans every keyword on every device the project tracks.

Cost is one credit per results page, per keyword, per device: top 10 is 1 page, top 30 is 3, top 100 is 10. The full depth is charged when the check starts. A scan stops as soon as it has found your domain and every competitor, and the pages it did not need are refunded when it finishes — as are keywords whose lookup failed.

Create a project

curl https://api.indexaction.com/api/v1/rank/projects/ \
  -H "Authorization: Api-Key YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Example",
    "domain": "example.com",
    "keywords": ["bulk index checker", "check if url is indexed"],
    "gl": "us",
    "hl": "en",
    "devices": "desktop",
    "depth": 30,
    "competitors": ["rival.com"],
    "schedule_enabled": true,
    "schedule_hour": 7,
    "timezone_name": "UTC"
  }'

domain may be a URL; it is stored as the bare host, and subdomains count as the same site. devices is desktop, mobile or both. Nothing is charged until a check runs; the response says what one will cost:

{
  "id": "9f559ea8-2ad1-41f4-953f-0d3131b7d432",
  "domain": "example.com",
  "depth": 30,
  "keyword_count": 2,
  "cost_per_run": "6.00",
  "schedule_enabled": true,
  "next_run_at": "2026-09-18T07:00:00Z",
  "last_run": null,
  ...
}

Run a check, then read positions

curl -X POST https://api.indexaction.com/api/v1/rank/projects/PROJECT_ID/run/ \
  -H "Authorization: Api-Key YOUR_KEY" \
  -H "Idempotency-Key: $(uuidgen)"

# poll until status is succeeded, failed or canceled
curl https://api.indexaction.com/api/v1/rank/runs/RUN_ID/ -H "Authorization: Api-Key YOUR_KEY"

# then read each keyword's latest position per device
curl https://api.indexaction.com/api/v1/rank/projects/PROJECT_ID/keywords/ -H "Authorization: Api-Key YOUR_KEY"
[
  {
    "id": "10a5e2cf-15ce-4caa-a79b-be8ed4874043",
    "keyword": "bulk index checker",
    "latest": {
      "desktop": {
        "status": "ranked",
        "position": 12,
        "previous_position": 15,
        "has_previous": true,
        "best_position": 9,
        "url": "https://example.com/bulk-index-checker",
        "competitors": { "rival.com": 4 },
        "previous_competitors": { "rival.com": 6 },
        "checked_at": "2026-09-18T07:00:41+00:00"
      }
    }
  }
]

Plan limits

Accounts that have never bought credits can track one project of up to 10 keywords in the top 10, without competitors. Any credit pack lifts that. GET /rank/meta/ returns the limits that apply to the calling account, and a request over them is refused with a code saying which one — before anything is charged.

Endpoints

Index checks

Method Path Purpose
POST /checks/ Create a check. Up to 1,000 URLs.
GET /checks/{id}/ Status, counts, and per-URL verdicts.
GET /checks/ Paginated history. Filter by status, project, date.
POST /checks/{id}/cancel/ Stop a running check; unchecked URLs are refunded.
POST /checks/{id}/rerun/ Re-run the same URL list.
GET /checks/{id}/diff/ Newly indexed and dropped-out URLs vs the previous check.
GET /checks/{id}/export/ Download CSV or XLSX. ?format=csv|xlsx&verdict=…
DELETE /checks/{id}/ Remove a check from history. Credits are not affected.

Projects and schedules

Method Path Purpose
GET /projects/ Saved URL lists. Full CRUD at /projects/{id}/.
GET · PUT /projects/{id}/urls/ Read or replace a project's URL list.
POST /projects/{id}/check/ Check the project's saved list now.
GET /projects/{id}/runs/ The project's checks, newest first.
GET /projects/{id}/trend/ Index rate at each successful check.
GET /schedules/ Automatic re-checks. Full CRUD; one per project.
POST /schedules/{id}/run-now/ Run a schedule's check immediately.

Rank tracking

Method Path Purpose
GET /rank/projects/ Tracked domains with stats. Full CRUD at /rank/projects/{id}/.
GET · POST /rank/projects/{id}/keywords/ List keywords with their latest positions, or add more.
POST /rank/projects/{id}/keywords/remove/ Remove keywords and their history. Body: {"ids": [...]}
POST /rank/projects/{id}/run/ Check rankings now. Accepts Idempotency-Key.
GET /rank/projects/{id}/runs/ The project's rank checks, newest first.
GET /rank/projects/{id}/export/ Current positions as CSV, one row per keyword and device.
GET /rank/runs/{id}/ Status and counts of one rank check.
POST /rank/runs/{id}/cancel/ Stop a running rank check; unscanned pages are refunded.
GET /rank/keywords/{id}/history/ Every position recorded. ?days=30|90|365
GET /rank/meta/ This account's limits and price per page.

Account

Method Path Purpose
GET /dashboard/ Balance and aggregate totals.

Errors

Every error carries a stable machine-readable code, so you never have to match on human-readable text.

{ "code": "insufficient_credits",
  "detail": "You do not have enough credits for this check.",
  "required": "1000.00", "balance": "240.00", "shortfall": "760.00" }

An OpenAPI schema is served at https://api.indexaction.com/api/schema/, with a browsable reference at /api/docs/.

Get an API key
indexaction on Facebook Message indexaction on Telegram Email [email protected]