Skip to content

Search Seonio

Type a keyword, domain, or paste a URL

Start free with $1 to see full results. Powered by Seonio
SEO API

Seonio SEO Agent

Ask an SEO question; the SEO agent calls Seonio's data tools and answers.

POST /api/v1/agent/chat$2 / M input tokens + $6 / M output tokens + data toolsAuth: X-API-Key header
seonio / rest apiFrom the API docs
RequestPOST /api/v1/agent/chat
curl -X POST https://seonio.com/api/v1/agent/chat \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $SEONIO_API_KEY" \
  -d '{"message": "What is the search intent of these keywords: standing desk, best standing desk, standing desk benefits, buy standing desk, standing desk vs sitting, flexispot standing desk?"}'
Response200 OK
{
  "conversation_id": "01a15f2c-8d41-7b3e-9c52-4e7f0a6b1d93",
  "status": "done",
  "answer": "Most of these are **commercial or transactional**: people are close to buying a desk.\n\n| Keyword | Intent |\n|---|---|\n| standing desk | commercial |\n| best standing desk | commercial |\n| standing desk benefits | informational |\n| buy standing desk | transactional |\n| standing desk vs sitting | informational |\n| flexispot standing desk | navigational |\n\nFor a store, target *buy standing desk* and *best standing desk* with product and comparison pages; answer *benefits* and *vs sitting* in a guide that links to them.",
  "error": null,
  "tools": [
    {
      "name": "keywords_intent",
      "args": {
        "keywords": [
          "standing desk",
          "best standing desk",
          "standing desk benefits",
          "buy standing desk",
          "standing desk vs sitting",
          "flexispot standing desk"
        ]
      },
      "ok": true,
      "cost_usd": 0.006
    }
  ],
  "usage": {
    "input_tokens": 9412,
    "output_tokens": 1187
  },
  "cost": {
    "model_usd": 0.026,
    "tools_usd": 0.006,
    "total_usd": 0.032
  },
  "pending": null,
  "quote_id": null
}
Contract

What to send and what comes back

Seonio's SEO agent answers an SEO question in Markdown by calling Seonio's data tools itself (keyword metrics, Google results, traffic, rankings, backlinks, page audits). One call is one message and a new conversation, saved to your SEO agent chats on seonio.com, where you can continue it; put everything the SEO agent needs in the message. The answer comes back whole, within about 90 seconds. Price: $2 per million input tokens and $6 per million output tokens for the model, plus each data tool it calls at its normal price. You pay what is used: the model part settles to the tokens of this message, and each data tool call is its own charge, listed in `tools`. A lookup that costs more than the data a message may use on its own is not run: the answer offers it in `pending` (its name, arguments and price, nothing charged) with a `quote_id`. Show the user that price. Send the quote_id only after the user approved this lookup at that price. That call (a message is optional) continues the conversation and runs the lookup first. A message that cannot start is refused before anything is charged: 402 (balance), 403 (account), 404 (an unknown quote_id), 409 (an approval already used, or the conversation went on), 422 (no message and no quote_id, over 4,000 characters, or another field), 429 (rate limit, with Retry-After), 503 (unavailable); "detail" says why (a string; an object for 402, a list for a malformed request's 422). Once it ran, the answer is a 200, also when the SEO agent could not answer: then `status` is "failed", the model part was not charged, and data tools that ran stay charged.

Request body

Request body
FieldTypeRequiredDescription
message string optional The question, 1 to 4,000 characters. Required unless quote_id is sent.
quote_id string optional Runs the lookup an answer offered (its `quote_id`), first, in that answer's conversation. Send the quote_id only after the user approved this lookup at that price.

Response

Response fields
FieldTypeDescription
conversation_id string The new conversation this message started (in your SEO agent chats on seonio.com).
status string "done", "failed" (no answer: the model part was not charged) or "interrupted".
answer string The answer in Markdown (empty when failed). An answer cut by the time limit ends with a note saying it may be incomplete.
error string | null Why there is no answer, else null.
tools object[] The data tools the SEO agent called, in order: each {"name", "args", "ok", "cost_usd"}; a call that failed is free.
usage object The model's tokens for this message: input_tokens, output_tokens (reasoning included); both null when the model did not report them (then the model part was free).
cost object What this message cost in US dollars: model_usd, tools_usd, total_usd.
pending object | null A lookup the answer offers instead of running it, because it costs more than the message's data budget: {"name", "args", "cost_usd"}; nothing was charged for it. Else null.
quote_id string | null With `pending`: send it back to run that lookup. Send the quote_id only after the user approved this lookup at that price. Else null.
Code

Copy, paste, add your key

The same request in cURL, Python and Node.js.

cURL
curl -X POST https://seonio.com/api/v1/agent/chat \
  -H "Content-Type: application/json" \
  -H "X-API-Key: YOUR_API_KEY" \
  -d '{"message": "What is the search intent of these keywords: standing desk, best standing desk, standing desk benefits, buy standing desk, standing desk vs sitting, flexispot standing desk?"}'
Python
import requests

resp = requests.post(
    "https://seonio.com/api/v1/agent/chat",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={"message": "What is the search intent of these keywords: standing desk, best standing desk, standing desk benefits, buy standing desk, standing desk vs sitting, flexispot standing desk?"},
)
print(resp.json())
Node.js
const resp = await fetch("https://seonio.com/api/v1/agent/chat", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "X-API-Key": "YOUR_API_KEY",
  },
  body: JSON.stringify({"message": "What is the search intent of these keywords: standing desk, best standing desk, standing desk benefits, buy standing desk, standing desk vs sitting, flexispot standing desk?"}),
});
console.log(await resp.json());
Playground

Run a real request

Send this request from your browser with your API key, or leave the key empty to see the sample response.

A successful run costs $2 / M input tokens + $6 / M output tokens + data tools. With no key, you see the sample response and nothing is charged.

POST /api/v1/agent/chatSample response
{
  "answer": "Most of these are **commercial or transactional**: people are close to buying a desk.\n\n| Keyword | Intent |\n|---|---|\n| standing desk | commercial |\n| best standing desk | commercial |\n| standing desk benefits | informational |\n| buy standing desk | transactional |\n| standing desk vs sitting | informational |\n| flexispot standing desk | navigational |\n\nFor a store, target *buy standing desk* and *best standing desk* with product and comparison pages; answer *benefits* and *vs sitting* in a guide that links to them.",
  "conversation_id": "01a15f2c-8d41-7b3e-9c52-4e7f0a6b1d93",
  "cost": {
    "model_usd": 0.026,
    "tools_usd": 0.006,
    "total_usd": 0.032
  },
  "error": null,
  "pending": null,
  "quote_id": null,
  "status": "done",
  "tools": [
    {
      "args": {
        "keywords": [
          "standing desk",
          "best standing desk",
          "standing desk benefits",
          "buy standing desk",
          "standing desk vs sitting",
          "flexispot standing desk"
        ]
      },
      "cost_usd": 0.006,
      "name": "keywords_intent",
      "ok": true
    }
  ],
  "usage": {
    "input_tokens": 9412,
    "output_tokens": 1187
  }
}
Use cases

What developers build with it

  • SEO answers in your own app or chatbot, backed by real data.
  • Agents that hand a whole SEO question to the SEO agent instead of picking tools.
Status codes

The same contract on every endpoint

Error responses are JSON with a "detail" field. It is a message string unless the row above says otherwise.

Status codes
CodeWhen
200Success. The lookup completed and was charged, even if the response is empty. /keywords/global charges only the keywords it looked up.
401Missing or unknown API key.
402Not enough balance. "detail" is an object with "error", "message", "balance_required" and "balance_available". Requests still running hold their price until they finish, so a retry can succeed once they do.
403The account is not verified yet, or it is locked.
409Another AI Visibility Report of this account is running, a start sent with free_only found no free report or site audit left, or the site was audited less than 30 days ago ("detail" is then an object with "error": "too_soon", "message", "audit_id" and "next_audit_at"); the detail says which. Not charged.
422Invalid request (wrong shape or types, a keyword over 200 characters, a URL the page checker cannot audit, a domain that does not exist, or a bare public suffix such as co.uk that groups many websites) — never charged. "detail" is usually a list of validation errors; an answer that retrying cannot change (such as a domain without a DNS record) is a message string with an X-Outcome header naming it: missing, unsupported, too_large or refused_input.
429Rate limit exceeded, never charged. Requests per second per account by plan: 5 on a free account, 10 on Starter, 15 on Pro and 20 on Business; retry after the Retry-After header. Also the page checker's provider limit and the AI Visibility Report's hourly limit on new reports.
503A data provider failed or timed out (X-Outcome: temporary). Nothing was charged; retry after the seconds in the Retry-After header.
FAQ

Questions, answered

Simple answers for developers using the API.

Every endpoint has a published USD price or formula. Requests draw from the same testing, included and Extra Usage balance as website and MCP actions: testing first, then included usage, then Extra Usage expiring soonest.

API actions require a verified account with a free $1 balance or an active subscription balance. Create and manage API keys from your account, then send the key in the X-API-Key header.

Yes. Your account shows API usage and remaining balance, so you can track costs while building and running automated workflows.

REST API and MCP requests per second depend on your plan: 5 on a free account, 10 on Starter, 15 on Pro and 20 on Business. Website data requests from the same account count toward the same second. Requests above the limit return HTTP 429 with a Retry-After header and are not charged; wait a second and retry.

Free $1 to test · No card required

Turn search insights into measurable growth

Start your SEO research in seconds.

SEO researchREST APIMCP