A roster agents can read
Developers
Search the roster, filter it, or keep a local copy in sync. Reads need no key and answer at https://onepersonco.ai. To file an agent or record a deployment, issue a bearer key from your file and send it on write calls. The API returns JSON, and nothing you send goes live without review.
curl "https://onepersonco.ai/api/v1/bots"
Machine-readable contract
Agents and generated clients can use the OpenAPI 3.1 specification. The RFC 9727 API catalog advertises the same API at the standard well-known URL.
curl https://onepersonco.ai/openapi.json
curl -H "Accept: application/linkset+json" https://onepersonco.ai/.well-known/api-catalog
Browse and search
Results default to newest first. Use any combination of these query parameters:
| Parameter | Meaning | Default |
|---|---|---|
| q | Search names, missions, and prompts; 200 characters at most | — |
| category | Exact desk key, such as productivity | — |
| integration | Exact tool name | — |
| page | Page number | 1 |
| limit | Results per request; maximum 100 | 25 |
| sort | newest, name, or copies | newest |
GET https://onepersonco.ai/api/v1/bots?q=slack&category=sales&sort=copies&limit=25
The reply is a JSON array of agents. Each carries slug, name, category, addedAt, integrations, prompt, description, contributor, sourceUrl, grokShareUrl, sources, detailUrl, copies, xBotId, xHandle, and grokAppUrl. Fields are only ever added, never renamed.
Keep a local copy in sync
For a mirror, fetch https://onepersonco.ai/api/bots.json. It returns the complete live roster in one request, no pagination, in the same shape as the search reply. Rebuilt whenever the roster changes, so refetch it on a schedule and upsert by slug. Agents that leave the roster stop appearing in it.
curl https://onepersonco.ai/api/bots.json
[ { "slug": "inbox-triage", "name": "Inbox Triage", ... }, ... ]
For newest-first summaries, /updates.json is a JSON Feed 1.1 and /rss.xml is the same as RSS 2.0.
Get a key
Clients that want to write need a bearer key. Keys start with opc_live_, belong to your account, and are shown once when issued. Sign in to issue a key →
A client that already holds a key can mint another one for the same account.
curl -X POST "https://onepersonco.ai/api/v1/api_keys" \
-H "Authorization: Bearer opc_live_…"
{ "token": "opc_live_…" }
Status 200 with the new token. It is not recoverable later; revoke lost keys from your file.
Who am I
Check which account a key belongs to.
GET https://onepersonco.ai/api/v1/me
Authorization: Bearer opc_live_…
{ "username": "my-scout-bot", "email": "[email protected]" }
A missing or unknown key answers 401 with an empty body.
File an agent
Authenticated writes open a pending file. It reaches the roster only after automated vetting and desk review; the API never publishes live. Send a Grok share URL, or a name and prompt, or both. Limit: 10 submits an hour per key.
| Field | Meaning | Required |
|---|---|---|
| grokShareUrl | Official share URL only: https://x.ai/bot/<id>. Link only; never invent one. | with no prompt |
| name | Listing title; the slug is derived from it | with a prompt |
| prompt | Copy-paste agent instructions, second person (You…) | with no share URL |
| description | One-line mission shown on the card | no |
| category | A desk key from the desks, or suggest | no |
| integrations | Array of tool names the prompt connects, up to 20 | no |
| sources | Array of source links (X, YouTube, or web), up to 3 | no |
POST https://onepersonco.ai/api/v1/bots
Authorization: Bearer opc_live_…
Content-Type: application/json
{
"name": "Slack Standup Summarizer",
"category": "ops",
"prompt": "You summarize my Slack standup…",
"integrations": ["Slack", "Notion"],
"grokShareUrl": "https://x.ai/bot/Y7LbP6p5EBFjfdTp69cKr"
}
{
"slug": "pending-6f1c…",
"status": "pending_verification"
}
Status 200 with status and slug; the pending slug is replaced by the public one when the file goes live. 422 when the intake is incomplete or the prompt fails lint, 409 when the share URL is already on the roster, 401 without a valid key.
Record a deployment
Tell the roster when your client copies a prompt. One count per key per agent, and one per browser cookie for keyless calls. Limit: 30 copies an hour per address.
POST https://onepersonco.ai/api/v1/copies
Authorization: Bearer opc_live_…
slug=inbox-triage
{ "slug": "inbox-triage", "copies": 42, "counted": true }
Status 200 with the running count; counted is false when this key already counted that agent. 404 for a slug not on the roster.
MCP for agents
One JSON-RPC endpoint with the same bearer key, protocol 2025-06-18. GET and HEAD answer 405. The tools mirror the REST calls above:
- list_botsList live catalog bots. Mirrors GET /api/v1/bots.
- get_botFetch one live catalog bot by slug.
- submit_botSubmit a bot. Needs a prompt (with a name) or a grokShareUrl, or both. Never publishes live.
POST https://onepersonco.ai/mcp
Authorization: Bearer opc_live_…
Content-Type: application/json
{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"list_bots","arguments":{"q":"invoice"}}}
Auth for writes
Send the key as a bearer token on write routes and on GET /api/v1/me. Reads under GET /api/v1/bots and every feed stay keyless.
Authorization: Bearer opc_live_…
Over the limit, the API answers 429 with Retry-After and X-RateLimit-Reset headers.
Send this page to a bot
This page is the complete usage contract and reads without JavaScript. Give a bot https://onepersonco.ai/developers and ask it to browse the roster, keep a local mirror, mint a key for its user, or file an agent. https://onepersonco.ai/llms.txt lists every live agent for language clients.
Raw feeds
- OpenAPI/openapi.jsonthe contract above, as a schema
- LLMs/llms.txtroster discovery for language clients
- Bulk/api/bots.jsonevery live agent in one file
- Updates/updates.jsonnewest agents first
- RSS/rss.xmlthe same, for readers
- Catalog/.well-known/api-catalogRFC 9727 linkset
Feeds and JSON shapes only ever change by adding fields. Ads are never in them.