API Reference

The TopIndexer API

A small, honest REST API. Submit URLs, we trigger the crawl, and you read back the verified index status — the same engine the dashboard runs on. One Bearer key, three endpoints.

Base URL https://api.topindexer.com

Overview

Every endpoint lives under /api/v1 and returns JSON. Authentication is a single Bearer key — there are no separate OAuth scopes, no per-endpoint permissions. A key is bound to one team and acts on that team’s credit balance.

Method Endpoint Description
POST /api/v1/submit Submit up to 50 URLs for indexing.
GET /api/v1/submissions List your team's submissions.
GET /api/v1/me Your team + credit balance.

Specs & tools

Import the API anywhere — a Postman/Insomnia workspace, an SDK generator, or an AI agent. The OpenAPI spec is the universal one: drop the URL into a custom GPT action, an MCP/tool-use config, or any code generator.

Point an agent at the spec directly: https://topindexer.com/openapi.yaml · https://topindexer.com/llms.txt

Authentication

Create a key in the dashboard under Settings → API keys. Keys are shown once, look like ti_live_…, and don’t expire — but you can revoke them at any time. We only ever store a hash of the key, so a lost key can’t be recovered; create a new one.

Pass it as a Bearer token on every request:

Authorization: Bearer ti_live_a1b2c3…

A missing or malformed key returns 401 unauthorized.

POST /api/v1/submit

Submit between 1 and 50 URLs. We validate them, deduct one credit per accepted URL in a single atomic batch, and begin triggering the crawl immediately. Invalid (non-http(s)) URLs are silently dropped and reported in ignoredInvalid. Returns 202 Accepted.

Body

{
  "urls": ["https://example.com/page-a", "https://example.com/page-b"]
}

Request

curl -X POST https://api.topindexer.com/api/v1/submit \
  -H "Authorization: Bearer ti_live_a1b2c3…" \
  -H "Content-Type: application/json" \
  -d '{"urls":["https://example.com/page-a"]}'

Response · 202

{
  "submitted": 1,
  "ignoredInvalid": 0,
  "submissions": [
    { "id": "01J9…ULID", "url": "https://example.com/page-a", "status": "queued" }
  ]
}

Returns 402 insufficient_credits (with required and available fields) if your balance can’t cover the batch — nothing is charged.

GET /api/v1/submissions

List your team’s submissions, newest first.

Query parameters

Param Description
status Optional. Filter by one status (e.g. indexed).
limit Optional. Default 50, max 200.

Request

curl "https://api.topindexer.com/api/v1/submissions?status=indexed&limit=50" \
  -H "Authorization: Bearer ti_live_a1b2c3…"

Response · 200

{
  "submissions": [
    {
      "id": "01J9…ULID",
      "url": "https://example.com/page-a",
      "status": "indexed",
      "submittedAt": "2026-06-01T12:00:00.000Z"
    }
  ]
}
GET /api/v1/me

Return the authenticated team and its current credit balance — handy for a pre-flight check before a large batch.

Request

curl https://api.topindexer.com/api/v1/me \
  -H "Authorization: Bearer ti_live_a1b2c3…"

Response · 200

{
  "team": { "id": "team_…", "name": "Acme", "creditBalance": 480 },
  "keyId": "key_…"
}

Submission lifecycle

A submission moves through these states. We verify index status honestly — via a Google site: check, never Search Console — and auto-refund anything that isn’t indexed within the 7-day guarantee.

queued Accepted and credited. Waiting for a provider slot.
submitted Crawl request sent to the indexing provider.
crawled Googlebot has visited — not yet confirmed in the index.
indexed Verified live in Google’s index. The credit is spent.
not_indexed Not indexed within the 7-day guarantee. Auto-refunded.
failed The provider rejected the URL. No credit is charged.

Errors

Errors use standard HTTP status codes and a JSON body of the shape { "error": "…", "message": "…" }.

Status Error When
400 bad_request Missing/empty `urls`, or no valid http(s) URL.
400 too_many More than 50 URLs in one request.
401 unauthorized Missing, malformed, invalid, or revoked key.
402 insufficient_credits Balance can’t cover the batch.
404 not_found No route, or the team no longer exists.
500 internal Something failed on our side.

Ready to index?

Create a key in the dashboard and submit your first URL — it’s free. You only pay when a page is verified in the index.

Open the dashboard