API / v1Updated 2026-10-13

API reference

Submit a question to an AI platform and retrieve its answer and cited sources.

Quick start

For a no-code workflow, use Workspace. The examples below are for API integration; this page does not submit tasks.

  1. 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 management
  2. Submit one question

    Shell / curl
    curl --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"}
  3. 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 / curl
    curl --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.

Python / httpx
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.comHTTPS

Workspace 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

  1. SubmitPOST /v1/tasks
  2. WaitGET /v1/tasks/{task_id}/status
  3. FetchGET /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.

FieldTypeDescription
promptsstring[]Required; one non-empty question.
platformsobject[]Required; one configuration containing platform, mode and screenshot.
monitorKeywordsstringOptional comma-separated keywords.
regionCodestringOptional region catalog code; omit for default region selection.
mode / screenshotstring / integerOptional overrides of the platform fields; the platform must support the mode.

GET/v1/tasks/{task_id}/status

{"task_id": "example-task-id", "status": "processing"}
StateNext step
submitting / pending / processingContinue bounded polling.
completedFetch the result.
failedStop 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.

JSON
{
  "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.

JSON request
{
  "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 catalog

Platforms include DeepSeek, Doubao, Qianwen, Yuanbao and Kimi. search is search mode; other modes and screenshot options depend on the returned capabilities.

Result fields

FieldDescription
answerContentAnswer, usually Markdown. Sanitize untrusted HTML before rendering.
referenceList / citationListReference sources / cited sources; may be empty.
reasoningProcessOptional platform-provided reasoning; not present in every mode.
recommendedQuestions / mediaContentOptional follow-up questions and media. Treat external links as untrusted.
pageScreenshotMay 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"}}
HTTPMeaning / action
400 / 422Invalid input or result not ready. Correct the request; do not retry indefinitely.
401 / 403Key, account or permission issue; email_required_for_free_trial requires email binding. Check account status.
402insufficient_balance: account or token budget is insufficient. More keys do not add funds.
404Task missing or not owned by this account.
429If the gateway rate-limits, respect Retry-After and back off.
503billing_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 / 504Service 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.