The problem#
An agent that needs live facts ends up with a tool per website: different auth, different response shapes, different failure modes. Each extra tool adds schema text to the prompt and another thing to keep working.
With Onekey the agent gets one tool. The path (platform/endpoint) and parameters come from the catalog, every answer has the same envelope, and metadata.credits_charged lets you budget per task.
Endpoints to call#
| Endpoint | Used for | Credits | Status |
|---|---|---|---|
wikipedia.extract | Plain-text intro of an article, for quick grounding. | 1 | stable |
web.markdown | Main content of any public page as clean Markdown, ready for a context window. | 2 | stable |
hackernews.search | Search Hacker News stories by keyword. | 1 | stable |
github.repo | Repository facts: description, stars, licence, last push. | 1 | stable |
Each endpoint name links to its reference page with every parameter, the caching window and a recorded response.
Your first call#
This is web.markdown (2 credits). Replace YOUR_API_KEY with your key; sign up, no card. 1,000 free credits cover the open-platform endpoints. Hard-to-reach platforms (X, TikTok, Instagram, Reddit, and others marked on their page) need a verified email and a purchased pack.
curl "https://api.onekey.dev/v1/web/markdown?url=https%3A%2F%2Fen.wikipedia.org%2Fwiki%2FWeb_scraping" \
-H "x-api-key: YOUR_API_KEY"A working script#
A provider-neutral tool definition and its handler. Pass ONEKEY_TOOL in the tool list of whichever model API you use, and route the tool call to run_tool. The catalog for the agent's prompt is free to fetch: see the links below.
import os
import requests
API = "https://api.onekey.dev"
HEADERS = {"x-api-key": os.environ["ONEKEY_KEY"]}
def call(path, **params):
"""GET /v1/<platform>/<endpoint>; returns the data or raises with the error code."""
r = requests.get(f"{API}/v1/{path}", params=params, headers=HEADERS, timeout=30)
body = r.json()
if not body["success"]:
raise RuntimeError(f"{path}: {body['error']['code']}")
return body["data"]
def get(item, field):
"""get(item, 'content.title'): a field of the unified schema, or None."""
for key in field.split("."):
item = (item or {}).get(key)
return item
import json
ONEKEY_TOOL = {
"name": "onekey_get",
"description": (
"Read public data from a platform. 'path' is platform/endpoint, for example "
"wikipedia/extract with {\"title\": \"Alan Turing\"}, web/markdown with {\"url\": \"https://...\"} "
"or hackernews/search with {\"q\": \"rust\"}. Returns the data and what the call cost in credits."
),
"parameters": {
"type": "object",
"properties": {
"path": {"type": "string", "description": "platform/endpoint"},
"params": {"type": "object", "additionalProperties": {"type": "string"}},
},
"required": ["path"],
},
}
def run_tool(path, params=None):
r = requests.get(f"{API}/v1/{path}", params=params or {}, headers=HEADERS, timeout=30)
body = r.json()
if not body["success"]:
return json.dumps({"error": body["error"]["code"], "message": body["error"]["message"]})
return json.dumps({"data": body["data"], "credits": body["metadata"]["credits_charged"]})What a month costs#
Illustrative volume, not a benchmark: An agent that handles 1,000 tasks in a month and averages one Wikipedia lookup, one page read and one Hacker News search per task.
| Endpoint | Calls | Credits per call | Credits |
|---|---|---|---|
wikipedia.extract | 1,000 | 1 | 1,000 |
web.markdown | 1,000 | 2 | 2,000 |
hackernews.search | 1,000 | 1 | 1,000 |
| Total | 4,000 |
About 4,000 credits: the Starter pack (5,000 credits, $9) covers it, at $1.80 per 1,000 credits. Prices are in USD (regional pricing is planned); credits never expire. See pricing.
Every figure above assumes every call is a fresh fetch. These endpoints cache for 2 minutes to 1 hour. Free when served from cache (0.2 credit for a cached response over 100 KB). Repeating a call inside that window costs nothing. Invalid, failed and not-found calls are not charged either.
Good to know#
- Errors come back in the same envelope with a stable
error.code, so the agent can read them and decide whether to retry. Invalid and failed calls are not charged. - Set a per-task ceiling by summing
metadata.credits_chargedin your handler and refusing further calls past it.
Keep reading#
- AI agents guide
- Errors
- Rate limits
- Platform pages: Wikipedia, Web pages, Hacker News, GitHub