Send URLs to Google straight from your scripts, CMS and services. Same balance as in the bot, every URL checked, and you only pay for accepted ones.
Grab a key in the bot, paste it and send your URL list. The response is instant, the rest runs in the background.
$ curl -X POST https://api.indexforge.help/v1/submit -H "Authorization: Bearer YOUR_KEY" -H "Content-Type: application/json" -d '{"urls": ["https://site.com/page-1", "https://site.com/page-2"]}'
import requests, time API = "https://api.indexforge.help" H = {"Authorization": "Bearer YOUR_KEY"} task = requests.post(API + "/v1/submit", headers=H, json={"urls": urls}).json()["task"] while task["status"] in ("queued", "checking", "submitting"): time.sleep(10) task = requests.get(API + "/v1/tasks/" + task["id"], headers=H).json()["task"] print(task["accepted"], "accepted", task.get("rejected", 0), "rejected")
const API = "https://api.indexforge.help"; const H = { Authorization: "Bearer YOUR_KEY", "Content-Type": "application/json" }; let { task } = await (await fetch(API + "/v1/submit", { method: "POST", headers: H, body: JSON.stringify({ urls }) })).json(); while (["queued", "checking", "submitting"].includes(task.status)) { await new Promise(r => setTimeout(r, 10000)); ({ task } = await (await fetch(API + "/v1/tasks/" + task.id, { headers: H })).json()); } console.log(task.accepted, "accepted");
$ch = curl_init("https://api.indexforge.help/v1/submit"); curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => ["Authorization: Bearer YOUR_KEY", "Content-Type: application/json"], CURLOPT_POSTFIELDS => json_encode(["urls" => $urls]), ]); $task = json_decode(curl_exec($ch), true)["task"]; // then poll /v1/tasks/{id} until the status is done
«🔑 API» button in @IndexForgeBot. The key is shown once, regenerate it in one tap.
POST /v1/submit with up to 10,000 URLs. Instant response with a task id.
Every URL is checked the Googlebot way: 404, redirects, noindex, robots.txt, canonical.
Clean URLs go to work. They usually land in the index within 1–3 days.
No SDKs, no complex auth. A key in the header and JSON.
| urls array | http(s) URLs, up to 10,000. Duplicates are removed for you. |
| check bool | Default true. false skips the check, then all URLs are charged. |
{ "ok": true,
"task": { "id": "3f9c2a7d1b6e4c80",
"status": "queued", "urls": 2 } }| checked | how many URLs were checked |
| rejected · rejected_urls | how many were rejected and why: 404, redirect, noindex, robots, canonical |
| accepted | how many were accepted for indexing |
| charged · refunded | credits charged and refunded |
{ "ok": true, "task": {
"id": "3f9c2a7d1b6e4c80", "status": "done",
"urls": 2, "checked": 2, "rejected": 1,
"accepted": 1, "charged": 1, "refunded": 0,
"rejected_urls": { "404": ["https://site.com/old"] } } }Recent tasks for your key, newest first. limit from 1 to 100.
{ "ok": true, "tasks": [ { … }, { … } ] }Current balance in credits. 1 credit = 1 URL = $0.01. Top up in the bot with USDT.
{ "ok": true, "balance": 1250,
"price_per_url_usd": 0.01 }Poll GET /v1/tasks/{id} every 10 seconds until the task reaches a final status.
queuedqueuedcheckingchecking URLssubmittingsubmittingdonedoneEvery error response has a status code, an error field and a message.
bad_json · no_urls · too_many_urlsNo URLs, broken JSON or more than 10,000 at once.
unauthorizedMissing or invalid key. Check the header.
insufficient_creditsNot enough credits. Top up in the bot.
rate_limited · too_many_tasksMore than 60 requests a minute or 3 tasks at once.
Key, balance, top-ups and support in one bot. Message us if you need help with the setup.

URLs rejected by the check are never charged.
If a submission fails, unaccepted credits go straight back to your balance.
We store only a hash of your key. Regenerating it in the bot disables the old one instantly.