API documentation
Two surfaces: a public one that needs no account, and an authenticated one for projects, automatic submission and delivery history.
The key check
Every submission endpoint fetches https://<host>/<key>.txt
and confirms it contains your key before sending anything. If it does not, the response is
422 with
submitted: false and nothing is sent.
This exists because Bing, Yandex and the global endpoint return 202
for any well-formed key and validate it later, discarding the submission silently if it fails. Pass
"skipVerification": true to bypass the check — useful
right after a deploy when a CDN has not yet served the new file.
Public endpoints
No authentication. Rate limited by IP: 20 requests per minute and 200 URLs per day.
/api/indexnow
Verify the key file, then submit a batch of URLs.
curl -X POST https://instantindexnow.com/api/indexnow \
-H 'Content-Type: application/json' \
-d '{
"domain": "example.com",
"apiKey": "your-indexnow-key",
"urls": ["https://example.com/a", "https://example.com/b"],
"engines": ["indexnow"]
}'
# 200 response
{
"success": true,
"submitted": true,
"host": "example.com",
"keyVerification": {
"verdict": "verified",
"ok": true,
"keyUrl": "https://example.com/your-indexnow-key.txt",
"message": "Key file verified at https://example.com/your-indexnow-key.txt.",
"warnings": []
},
"results": [
{
"engine": "indexnow",
"engineName": "IndexNow (Global)",
"success": true,
"status": 202,
"message": "IndexNow (Global) accepted the submission and will validate the key asynchronously.",
"keyConfirmedByEngine": false,
"durationMs": 412
}
],
"urls": { "accepted": 2, "rejected": 0, "duplicatesRemoved": 0, "truncated": 0 },
"quota": { "remaining": 198, "limit": 200, "resetAt": "..." }
}
/api/verify-key
Check the key file without submitting anything.
curl -X POST https://instantindexnow.com/api/verify-key \
-H 'Content-Type: application/json' \
-d '{"domain":"example.com","apiKey":"your-indexnow-key"}'
# verdict is one of: verified | not_found | mismatch | unreachable | bad_status
/api/indexnow?url=…&key=…
Single-URL submission, mirroring the protocol’s own GET form. The host is taken from the URL.
curl 'https://instantindexnow.com/api/indexnow?url=https://example.com/a&key=your-indexnow-key'
/api/engines
Machine-readable engine list, including which ones validate keys synchronously.
/api/generate-key
Returns a spec-compliant IndexNow key and the filename to publish it under.
Engine identifiers
| id | Engine | Validates key in-request |
|---|---|---|
| indexnow | IndexNow (Global) | no |
| bing | Bing | no |
| yandex | Yandex | no |
| naver | Naver | yes |
| seznam | Seznam.cz | yes |
| yep | Yep | yes |
| amazon | Amazon | yes |
Pass "engines": "all" to submit to every engine directly instead of through the global endpoint. Unrecognised values return 400 rather than falling back silently — "google" is not a valid engine because Google does not participate in IndexNow.
Authenticated endpoints
Requires an API key, sent as Authorization: Bearer <key>
or X-Api-Key: <key>. Quotas are charged in URLs, per account, per day.
Keys are issued at checkout, so the free tier has no key and uses the public endpoints above.
If a subscription lapses, the key keeps working for reads —
GET /me,
/projects,
/submissions,
/submissions.csv,
/keys — so you can always retrieve and export
your delivery history. Anything that submits or creates state returns
403 with
readOnly: true until the subscription is active again.
/api/v1/me
Account, plan and today’s usage.
/api/v1/projects
Register a host. The key is verified and the sitemap auto-detected unless you supply one.
curl -X POST https://instantindexnow.com/api/v1/projects \
-H "Authorization: Bearer $IIN_KEY" \
-H 'Content-Type: application/json' \
-d '{
"host": "example.com",
"indexnowKey": "your-indexnow-key",
"sitemapUrl": "https://example.com/sitemap.xml",
"engines": ["indexnow"],
"autoSubmit": true
}'
/api/v1/projects
List projects with their key verdict, watch state and last error.
/api/v1/projects/:id
Update the key, key location, sitemap, engines or autoSubmit flag.
/api/v1/projects/:id
Remove a project. Submission history is retained.
/api/v1/projects/:id/verify
Re-check the key file now and store the verdict.
/api/v1/projects/:id/sync
Run the sitemap watch immediately instead of waiting for the schedule. Still charged against your daily quota.
/api/v1/submit
Submit URLs against your account quota. Reference a project to avoid repeating the key.
curl -X POST https://instantindexnow.com/api/v1/submit \
-H "Authorization: Bearer $IIN_KEY" \
-H 'Content-Type: application/json' \
-d '{"projectId":"<project-id>","urls":["https://example.com/new-post"]}'
/api/v1/submissions
Delivery history, newest first. Supports limit and offset.
/api/v1/submissions/:id
One submission including the full URL list.
/api/v1/submissions.csv
The same history as CSV, one row per engine per submission.
/api/v1/keys
List active API keys.
/api/v1/keys
Create another key. The plaintext is returned once and never again.
/api/v1/keys/:id
Revoke a key. You cannot revoke your only remaining key.
Deploy-hook example
Submitting changed URLs from CI after a deploy:
#!/usr/bin/env bash
set -euo pipefail
# Let the watcher find what changed, rather than maintaining a URL list in CI.
curl -fsS -X POST "https://instantindexnow.com/api/v1/projects/$IIN_PROJECT_ID/sync" \
-H "Authorization: Bearer $IIN_KEY" | jq -r '.detail'
Errors
| Status | Meaning |
|---|---|
| 400 | Malformed body, invalid host or key, or an unknown engine id. |
| 401 | Missing, invalid or revoked API key. |
| 403 | Plan does not permit this — a lapsed subscription (readOnly: true), or a project/key limit reached. Read endpoints stay available. |
| 409 | Conflict, e.g. a project for that host already exists. |
| 422 | Key file verification failed. Nothing was submitted. |
| 429 | Rate limit or daily URL quota exceeded. Check Retry-After. |
| 502 | Every targeted engine rejected or could not be reached. Per-engine detail is in results. |
Questions about the API? Email contact@instantindexnow.com.