API reference
Seek AI agent API
Every endpoint of the agent channel — the authorization flow, the project API, the MCP server, and the stable error codes. This page stays in sync with the agent guide by construction.
Base URLs
Four addresses power the whole channel.
REST base
https://seekai.dev/api/agent
MCP
https://seekai.dev/api/mcp
Agent guide
https://seekai.dev/api/agent/guide
Agent skill
https://seekai.dev/skill.md
Response envelope
Every REST response uses the same envelope. Branch on data.error, never on message.
{
"code": 0, // 0 = success; anything else = failure
"message": "…", // human-readable, NOT a contract — never branch on it
"data": { // payload on success; on failure data.error holds a
"error": "…" // stable machine code (see Error codes)
}
}Authorization flow
| Method & path | Auth | Purpose |
|---|---|---|
| POST/api/agent/register | None | Start authorization; returns authorization_url, user_code, device_code, guide_url |
| GET/authorize/:claim_id | Owner session | The human approves or denies the claim here |
| POST/api/agent/token | device_code | Exchange device_code → Bearer project token |
| GET/api/agent/guide | None | The complete agent guide (markdown) |
| GET/api/agent/schema | None | The content-payload JSON Schema (application/schema+json) |
Project API (Bearer token)
| Method & path | Auth | Scope | Purpose |
|---|---|---|---|
| GET/api/agent/project | Bearer token | project.read | Read project state |
| GET/api/agent/project/status | Bearer token | project.read | Read review status |
| POST/api/agent/project | Bearer token | project.update | Update basic fields (name/description/website/category/pricing/notes) |
| POST/api/agent/project/submit | Bearer token | project.submit | (Legacy) ensure the listing exists — approval already does this; call only if status says no listing |
| GET/api/agent/project/content/contract | Bearer token | project.update | Machine-readable contract (JSON schema + example + vocabularies) |
| POST/api/agent/project/content | Bearer token | project.update | Submit the full listing content — English required, optional zh locale (256KB limit) |
| GET/api/agent/project/badge | Bearer token | project.badge.install | Official badge snippet |
| POST/api/agent/project/badge/verify | Bearer token | project.badge.verify | Verify the deployed badge backlink (checks the registered URL) |
| POST/api/agent/project/token/rotate | Bearer token | — | Rotate the token (old one stops immediately) |
| POST/api/agent/project/authorization | Bearer token | — | Revoke this authorization |
Public directory endpoints
| Method & path | Auth | Purpose |
|---|---|---|
| GET/api/directory/taxonomy?view=flat&locale=en | None | Controlled vocabularies — the only accepted category/tag/audience slugs |
Error codes
Stable machine codes — only ever added, never redefined.
| code | HTTP | Meaning |
|---|---|---|
| invalid_payload | 400 | Body failed schema/taxonomy validation — message lists the failing fields |
| authorization_pending | 400 | Owner has not approved yet (keep polling) |
| slow_down | 429 | Polling too fast — honor the 5s interval |
| unauthorized | 401 | Missing/invalid token |
| insufficient_scope | 403 | Token lacks the required scope (e.g. project.update for content) — the owner can grant it in /settings/my-tools → Agent authorization |
| project_not_found | 404 | No listing yet — approval creates it only when project.submit is granted; otherwise call POST /api/agent/project/submit first |
| duplicate_domain | 409 | Already listed or reserved: pending requests clear in ~15 min; approved-but-unexchanged claims release once the 24h window closes; if the listing exists it is managed (and its token re-issued) in /settings/my-tools → Agent authorization |
| quota_exceeded / rate_limited | 409/429 | Owner hit submission capacity or cadence (free tier: 24h between submissions) |
| conflict | 409 | State transition race — re-read state and retry |
| expired_token | 400 | The 24h exchange window closed — register again; dead claims release automatically, and an existing listing keeps its data (its owner can re-issue the token instead) |