API reference
Submit a question to an AI platform and retrieve its answer and cited sources.
Register and confirm your email with the verification code. Existing accounts must bind an email. An API key or a balance does not by itself grant Workspace or API access; accounts without access receive billing_not_ready.
Open personal settings Open WorkspaceQuick start
For a no-code workflow, use Workspace. The examples below are for API integration; this page does not submit tasks.
Prepare your account and API key
Create an account, verify your email, then generate an API key.
Create a key in Console token management and set it locally as GEO_API_KEY. Do not put it in a webpage, public repository or screenshot. Multiple keys share the account balance; they do not multiply free credit.
Open token managementSubmit one question
Shell / curlcurl --fail-with-body --max-time 210 \ https://api.geotoolhub.com/v1/tasks \ -H "Authorization: Bearer ${GEO_API_KEY}" \ -H "Content-Type: application/json" \ -d '{ "prompts": ["What are the best CRM tools?"], "platforms": [{"platform": "deepseek", "mode": "search", "screenshot": 0}] }'Example response (placeholder ID){"task_id": "example-task-id", "status": "pending"}Poll status, then fetch the result
Save the returned task_id as GEO_TASK_ID. Start polling every 10 seconds and back off to 30 seconds. Stop on a failed state or an error.
Shell / curlcurl --fail-with-body --max-time 30 \ "https://api.geotoolhub.com/v1/tasks/${GEO_TASK_ID}/status" \ -H "Authorization: Bearer ${GEO_API_KEY}" # Fetch only after status is completed. curl --fail-with-body --max-time 30 \ "https://api.geotoolhub.com/v1/tasks/${GEO_TASK_ID}/result" \ -H "Authorization: Bearer ${GEO_API_KEY}"
Complete Python example: timeouts and error handling
Install httpx first. This example submits once and waits up to 20 minutes. A local wait timeout does not cancel the task; do not automatically resubmit.
import os
import time
import httpx
base = "https://api.geotoolhub.com"
headers = {"Authorization": f"Bearer {os.environ['GEO_API_KEY']}"}
with httpx.Client(headers=headers, timeout=30.0) as client:
response = client.post(f"{base}/v1/tasks", timeout=210.0, json={
"prompts": ["What are the best CRM tools?"],
"platforms": [{"platform": "deepseek", "mode": "search", "screenshot": 0}],
})
response.raise_for_status()
task_id = response.json()["task_id"]
print("Save this task ID:", task_id)
deadline = time.monotonic() + 20 * 60
interval = 10
while time.monotonic() < deadline:
response = client.get(f"{base}/v1/tasks/{task_id}/status")
response.raise_for_status()
status = response.json()["status"]
if status == "completed":
response = client.get(f"{base}/v1/tasks/{task_id}/result")
response.raise_for_status()
print(response.json()["data"])
break
if status not in {"submitting", "pending", "processing"}:
raise RuntimeError(f"Task {task_id}: {status}")
remaining = deadline - time.monotonic()
if remaining <= 0:
raise TimeoutError(f"Wait expired; check existing task {task_id}")
time.sleep(min(interval, remaining))
interval = min(30, interval + 5)
else:
raise TimeoutError(f"Wait expired; check existing task {task_id}")Base URL
https://api.geotoolhub.comHTTPSWorkspace is the browser interface; /v1/tasks is the asynchronous API. This reference contains no administrative endpoints or internal credentials.
Account & authentication
Authorization: Bearer ${GEO_API_KEY}
Submission, status and result endpoints require a valid key. Status and results are scoped to the owning account; another account receives 404. Public metadata does not grant submission access.
A token budget is a spending cap, not a top-up. Requests remain subject to the account balance, token cap, email and access requirements.
Task workflow
- Submit
POST /v1/tasks - Wait
GET /v1/tasks/{task_id}/status - Fetch
GET /v1/tasks/{task_id}/result
An accepted submission is not a completed answer. Some platforms, including Doubao, may take longer. Keep the task_id rather than repeatedly submitting while waiting.
POST/v1/tasks
Submit one question and one platform per request. Use Workspace for batches or cross-platform comparisons.
| Field | Type | Description |
|---|---|---|
prompts | string[] | Required; one non-empty question. |
platforms | object[] | Required; one configuration containing platform, mode and screenshot. |
monitorKeywords | string | Optional comma-separated keywords. |
regionCode | string | Optional region catalog code; omit for default region selection. |
mode / screenshot | string / integer | Optional overrides of the platform fields; the platform must support the mode. |
GET/v1/tasks/{task_id}/status
{"task_id": "example-task-id", "status": "processing"}
| State | Next step |
|---|---|
submitting / pending / processing | Continue bounded polling. |
completed | Fetch the result. |
failed | Stop polling; retain the ID and investigate. |
Responses may include created_at and completed_at. Do not assume a fixed completion time.
GET/v1/tasks/{task_id}/result
Fetch after completion. A task that is not ready returns 400, not an empty success. This example is abbreviated; optional fields vary by platform.
{
"task_id": "example-task-id",
"status": "completed",
"data": {
"subTaskList": [{
"platform": "deepseek",
"mode": "search",
"answerContent": "Example answer in Markdown",
"referenceList": [],
"citationList": []
}]
}
}POST/v1/chat/completions
An OpenAI-shaped request and response, not synchronous chat or streaming answers. choices[0].message.content is a JSON string containing task_id. Use the same polling workflow. The same access and balance checks apply; zero usage does not mean the task is free.
{
"model": "geo-monitor",
"messages": [{"role": "user", "content": "What are the best CRM tools?"}],
"platforms": [{"platform": "deepseek", "mode": "search", "screenshot": 0}]
}model names the compatibility entry. platforms selects the target; a platform name is not an enabled model alias. Prefer /v1/tasks for new integrations.
GET/v1/regions
Public region catalog; no key required. Cache locally and respect Cache-Control instead of fetching for each task.
{"regions": [{"province": "北京市", "regionCode": ["110000"]}]}
Platforms & modes
Use GET /v1/platforms for current platform IDs, supported modes, screenshot options and enabled status. An example is not a guarantee of access. ChatGPT is currently paused; do not submit to a disabled platform.
View current platform catalogPlatforms include DeepSeek, Doubao, Qianwen, Yuanbao and Kimi. search is search mode; other modes and screenshot options depend on the returned capabilities.
Result fields
| Field | Description |
|---|---|
answerContent | Answer, usually Markdown. Sanitize untrusted HTML before rendering. |
referenceList / citationList | Reference sources / cited sources; may be empty. |
reasoningProcess | Optional platform-provided reasoning; not present in every mode. |
recommendedQuestions / mediaContent | Optional follow-up questions and media. Treat external links as untrusted. |
pageScreenshot | May be returned when screenshots are supported and enabled; examples disable them. |
Error handling
Check the HTTP status before parsing. Errors use detail, which can be a string or an object containing code / message.
{"detail": {"code": "billing_not_ready", "message": "GEO task billing is not enabled for this account"}}
| HTTP | Meaning / action |
|---|---|
| 400 / 422 | Invalid input or result not ready. Correct the request; do not retry indefinitely. |
| 401 / 403 | Key, account or permission issue; email_required_for_free_trial requires email binding. Check account status. |
| 402 | insufficient_balance: account or token budget is insufficient. More keys do not add funds. |
| 404 | Task missing or not owned by this account. |
| 429 | If the gateway rate-limits, respect Retry-After and back off. |
| 503 | billing_not_ready, platform_unavailable or platform_pricing_not_ready: account or platform not ready, not insufficient funds. Contact support; do not loop submissions. |
| 500 / 502 / 504 | Service or upstream error. Retain any task_id; a submission timeout is not proof that no task was created. Check before retrying. |
Waiting, retries & billing
- Completion time varies by platform and queue; there is no two-to-three-minute guarantee. A client wait deadline does not cancel the server task.
- Repeated submissions may create separate tasks and charges. Keep the task ID; status polling and repeated result reads do not charge again.
- Billing uses successful question-platform results and platform weights, not chat token counts. Budget is reserved first, then settled for completed results; failed portions are released through settlement.
- Credit, purchases, plans and access depend on actual account availability. Email binding does not guarantee immediate API access. This reference promises neither auto-renewal nor free caching of repeated questions.