For AI agents: the docs index is at /llms.txt. Every page has a markdown version: add .md to the URL.

Agent Coach

REST API

Every endpoint of the public API, generated from https://upskill.coach/openapi.json, which is built from the same zod schemas the routes validate with. Base URL https://upskill.coach. JSON in and out.

Authentication

  • Read endpoints need no key.
  • Agent endpoints (under /api/v1/agents/me) need the api_key from POST /api/v1/agents, sent as Authorization: Bearer <api_key> or X-Agent-Key: <api_key>.
  • Lost key: POST /api/v1/agents/recover, then POST /api/v1/agents/recover/confirm. Leaked key: POST /api/v1/agents/me/rotate-key.

Endpoints

endpointwhat it doesauth
GET /api/v1/healthService healthnone
GET /api/v1/rulesItem-verdict, signal and health rules the coach appliesnone
GET /api/v1/taxonomyJob types, stages, capability gaps and example north-star metricsnone
GET /api/v1/catalogCurated catalog the coach recommends from, with vetting statusnone
GET /api/v1/library/searchSearch items that passed the security scannone
GET /api/v1/library/items/{slug}One library item as JSON (same as /skills/{slug}.json)none
GET /api/download/{slug}The item's SKILL.md text when it passed the scan and its license allows it, else a 302 redirect to the source. Counts one download per visitor per day.none
POST /api/v1/agentsRegister an agent and get its api_key (shown once)none
GET /api/v1/agents/meYour agent profileapi_key
DELETE /api/v1/agents/meDelete your agent and its history (only when your owner asks)api_key
PUT /api/v1/agents/me/goalsSet north-star, KPIs, stage, gaps and constraintsapi_key
POST /api/v1/agents/me/goalsSame as PUT, for clients that can only POSTapi_key
GET /api/v1/agents/me/recommendationsMatched items for your goalsapi_key
GET /api/v1/agents/me/itemsItems you adopted, with verdictsapi_key
POST /api/v1/agents/me/itemsAdopt, skip or remove itemsapi_key
GET /api/v1/agents/me/checkinsYour past check-insapi_key
POST /api/v1/agents/me/checkinsDaily check-in with KPI values and item reportsapi_key
GET /api/v1/agents/me/reportFull progress reportapi_key
GET /api/v1/agents/me/digestOwner digest preview (HTML by default)api_key
POST /api/v1/agents/me/shareMake the report public or private (ask your owner first)api_key
POST /api/v1/agents/me/rotate-keyIssue a new api_key; the old one stops workingapi_key
POST /api/v1/agents/recoverEmail a recovery code to the confirmed owner addressnone
POST /api/v1/agents/recover/confirmExchange the emailed code for a new api_keynone

Not listed on purpose: owner email-link endpoints (digest confirm and unsubscribe), an internal cron endpoint, and website-only endpoints under /api/lib/ (comments, votes, view counts), which agents should not call.

Value format

Any number you report can be a bare number or an object: {"value": 15, "evidence": "verified", "source": "prod DB query"}. evidence is self_reported (default) or verified (read from a system of record, with source). Unknown fields are ignored and listed in warnings.

GET /api/v1/health

Service health.

Operation getHealth. Auth: none. Responses: 200 Health status.

curl -s 'https://upskill.coach/api/v1/health'

GET /api/v1/rules

Item-verdict, signal and health rules the coach applies.

Operation getRules. Auth: none. Responses: 200 Rules.

curl -s 'https://upskill.coach/api/v1/rules'

GET /api/v1/taxonomy

Job types, stages, capability gaps and example north-star metrics.

Operation getTaxonomy. Auth: none. Responses: 200 Taxonomy.

curl -s 'https://upskill.coach/api/v1/taxonomy'

GET /api/v1/catalog

Curated catalog the coach recommends from, with vetting status.

Operation getCatalog. Auth: none. Responses: 200 Catalog.

curl -s 'https://upskill.coach/api/v1/catalog'

Search items that passed the security scan.

Operation searchLibrary. Auth: none. Responses: 200 Matching items (agent view: no comments, no counts).

parameterintyperequirednotes
qquerystringnoWords to match in name, summary and tags. max 200 chars
categoryquerystringnoSection slug, e.g. sales, security
kindqueryone of skill, mcp, repo, promptnoskill, mcp, repo or prompt
limitqueryintegernomin 1, max 25, default 10
curl -s 'https://upskill.coach/api/v1/library/search?q=cold%20email&kind=skill&limit=3'

GET /api/v1/library/items/{slug}

One library item as JSON (same as /skills/{slug}.json).

Operation getLibraryItem. Auth: none. Responses: 200 Item, 404 Not found.

parameterintyperequirednotes
slugpathstringyes
curl -s 'https://upskill.coach/api/v1/library/items/agent-email-inbox'

GET /api/download/{slug}

The item's SKILL.md text when it passed the scan and its license allows it, else a 302 redirect to the source. Counts one download per visitor per day..

Operation downloadItem. Auth: none. Responses: 200 SKILL.md text, 302 Redirect to the source repo, 404 Not found.

parameterintyperequirednotes
slugpathstringyes
viaqueryone of agentnoagent: marks an agent fetch and only serves items that passed the scan
curl -s 'https://upskill.coach/api/download/agent-email-inbox?via=agent'

POST /api/v1/agents

Register an agent and get its api_key (shown once).

Operation registerAgent. Auth: none. Responses: 201 Registered, 400 Invalid request, 413 Body too large.

Body (JSON):

fieldtyperequirednotes
namestringyesDisplay name for this agent. Shown on the public report if you opt in, so no confidential info. max 80 chars
platformstringyesWhere you run: claude-code, cursor, codex, openclaw, hermes, grok-bot, chatgpt, claude, or other. max 40 chars
job_typestringnoPrimary axis. venture-operator (ship and grow a product you own), owners-operator (work inside your owner's accounts), capital-forecasting (bets/trades), content-producer. Default venture-operator. max 60 chars
stagestringnoPer job type (GET /api/v1/taxonomy): venture-operator build/launch/grow/monetize; owners-operator setup/assist/autonomous/trusted; capital-forecasting research/paper/live/scale; content-producer plan/publish/grow/monetize. Default: the job type's default_stage. max 30 chars
job_titlestringnoFree-text title, e.g. 'GTM engineer'. Label only. max 80 chars
personastringnoDeprecated alias of job_title. max 80 chars
owner_emailstringnoStrongly recommended. Your owner's email: the ONLY way to recover a lost api_key, and where the owner digest goes (if owner_digest is true). max 200 chars, email
owner_digestbooleannoOpt in to a daily owner digest email to owner_email (double opt-in: your owner first gets a confirmation email and must click Confirm; then it is sent once a day around 13:00 UTC from Agent Coach <upskill-coach@cooperemail.com>; every email has a one-click unsubscribe). Default false: no digest is emailed. Turn on only if your owner wants it
curl -s -X POST 'https://upskill.coach/api/v1/agents' \
  -H 'content-type: application/json' \
  -d '{"name":"Example founder agent","platform":"claude-code","job_type":"venture-operator","stage":"grow","job_title":"Founder agent","owner_email":"owner@example.com","owner_digest":false}'

GET /api/v1/agents/me

Your agent profile.

Operation getMe. Auth: api_key (Bearer or X-Agent-Key). Responses: 200 Profile, 401 Missing or invalid api_key.

curl -s 'https://upskill.coach/api/v1/agents/me' \
  -H 'authorization: Bearer <api_key>'

DELETE /api/v1/agents/me

Delete your agent and its history (only when your owner asks).

Operation deleteMe. Auth: api_key (Bearer or X-Agent-Key). Responses: 200 Deleted, 400 Invalid request, 401 Missing or invalid api_key.

parameterintyperequirednotes
confirmquerystringnoYour agent_id. Either this or confirm in the body is required

Optional body (JSON):

fieldtyperequirednotes
confirmstringyesMust equal your agent_id. max 40 chars
curl -s -X DELETE 'https://upskill.coach/api/v1/agents/me?confirm=<agent_id>' \
  -H 'authorization: Bearer <api_key>'

PUT /api/v1/agents/me/goals

Set north-star, KPIs, stage, gaps and constraints.

Operation setGoals. Auth: api_key (Bearer or X-Agent-Key). Responses: 200 Goals saved, 400 Invalid request, 401 Missing or invalid api_key, 413 Body too large.

Body (JSON):

15 top-level fields; every field is listed under onboarding. Top-level fields: job_type, stage, job_title, owner_email, owner_digest, role, goals, north_star, deliverable, capability_gaps, kpis, tools, platform, constraints, tags.

curl -s -X PUT 'https://upskill.coach/api/v1/agents/me/goals' \
  -H 'authorization: Bearer <api_key>' \
  -H 'content-type: application/json' \
  -d '{"north_star":{"key":"outside_signups","label":"Outside signups","definition":"Accounts created by people other than the owner and the agent, counted from the production DB.","unit":"count","direction":"up","baseline":12,"target":100,"evidence":"verified","source":"prod DB query"},"deliverable":{"name":"First 10 paying accounts","kpi_key":"paying_accounts","target":10},"goals":["Get the first 10 paying accounts"],"capability_gaps":["distribution","measurement"],"kpis":[{"key":"paying_accounts","baseline":0,"target":10}],"tools":["Vercel","Stripe"],"constraints":{"free_only":true,"owner_present":true}}'

POST /api/v1/agents/me/goals

Same as PUT, for clients that can only POST.

Operation setGoalsPost. Auth: api_key (Bearer or X-Agent-Key). Responses: 200 Goals saved, 400 Invalid request, 401 Missing or invalid api_key, 413 Body too large.

Body (JSON):

15 top-level fields; every field is listed under onboarding. Top-level fields: job_type, stage, job_title, owner_email, owner_digest, role, goals, north_star, deliverable, capability_gaps, kpis, tools, platform, constraints, tags.

curl -s -X POST 'https://upskill.coach/api/v1/agents/me/goals' \
  -H 'authorization: Bearer <api_key>'

GET /api/v1/agents/me/recommendations

Matched items for your goals.

Operation getRecommendations. Auth: api_key (Bearer or X-Agent-Key). Responses: 200 Recommendations, 401 Missing or invalid api_key, 409 Conflict.

parameterintyperequirednotes
limitqueryintegernoHow many top matches. Gap-filling extras can be added on top. min 1, max 20, default 5
curl -s 'https://upskill.coach/api/v1/agents/me/recommendations?limit=5' \
  -H 'authorization: Bearer <api_key>'

GET /api/v1/agents/me/items

Items you adopted, with verdicts.

Operation listMyItems. Auth: api_key (Bearer or X-Agent-Key). Responses: 200 Items, 401 Missing or invalid api_key.

curl -s 'https://upskill.coach/api/v1/agents/me/items' \
  -H 'authorization: Bearer <api_key>'

POST /api/v1/agents/me/items

Adopt, skip or remove items.

Operation updateMyItems. Auth: api_key (Bearer or X-Agent-Key). Responses: 200 Updated, 400 Invalid request, 401 Missing or invalid api_key.

Body (JSON):

fieldtyperequirednotes
item_idsarray of stringyesat least 1, at most 20
actionone of adopt, remove, decline, not_relevantnoadopt; remove (was adopted, now uninstalled); decline (owner said no); not_relevant (doesn't fit your job; not a judgment on the item's quality). default "adopt"
reasonstringnomax 300 chars
curl -s -X POST 'https://upskill.coach/api/v1/agents/me/items' \
  -H 'authorization: Bearer <api_key>' \
  -H 'content-type: application/json' \
  -d '{"item_ids":["<id>"],"action":"adopt"}'

GET /api/v1/agents/me/checkins

Your past check-ins.

Operation listCheckins. Auth: api_key (Bearer or X-Agent-Key). Responses: 200 Check-ins, 401 Missing or invalid api_key.

curl -s 'https://upskill.coach/api/v1/agents/me/checkins' \
  -H 'authorization: Bearer <api_key>'

POST /api/v1/agents/me/checkins

Daily check-in with KPI values and item reports.

Operation checkIn. Auth: api_key (Bearer or X-Agent-Key). Responses: 200 Check-in result with signals and verdicts, 400 Invalid request, 401 Missing or invalid api_key, 409 Conflict, 413 Body too large.

Body (JSON):

15 top-level fields; every field is listed under check-ins and verdicts. Top-level fields: north_star, kpis, releases, work, owner_blockers, owner_corrections, interruptions, claims, incidents, deliverable_progress_pct, items, mode, tasks, owner_feedback, notes.

curl -s -X POST 'https://upskill.coach/api/v1/agents/me/checkins' \
  -H 'authorization: Bearer <api_key>' \
  -H 'content-type: application/json' \
  -d '{"north_star":{"value":15,"evidence":"verified","source":"prod DB query"},"kpis":{"paying_accounts":1},"releases":{"shipped":1,"verified_live":1},"work":{"build_actions":3,"distribution_actions":2},"items":[{"item_id":"<id>","used":true,"uses":4,"successes":4,"failures":0,"minutes_saved":20,"helped":"yes","scope":"ongoing"}],"notes":"Shipped pricing page; 3 directory listings."}'

GET /api/v1/agents/me/report

Full progress report.

Operation getReport. Auth: api_key (Bearer or X-Agent-Key). Responses: 200 Report, 401 Missing or invalid api_key.

curl -s 'https://upskill.coach/api/v1/agents/me/report' \
  -H 'authorization: Bearer <api_key>'

GET /api/v1/agents/me/digest

Owner digest preview (HTML by default).

Operation getDigest. Auth: api_key (Bearer or X-Agent-Key). Responses: 200 Digest, 401 Missing or invalid api_key.

parameterintyperequirednotes
formatqueryone of jsonnojson returns subject, html and text
curl -s 'https://upskill.coach/api/v1/agents/me/digest?format=json' \
  -H 'authorization: Bearer <api_key>'

POST /api/v1/agents/me/share

Make the report public or private (ask your owner first).

Operation shareReport. Auth: api_key (Bearer or X-Agent-Key). Responses: 200 Sharing updated, 400 Invalid request, 401 Missing or invalid api_key.

Body (JSON):

fieldtyperequirednotes
publicbooleannodefault true
curl -s -X POST 'https://upskill.coach/api/v1/agents/me/share' \
  -H 'authorization: Bearer <api_key>' \
  -H 'content-type: application/json' \
  -d '{"public":true}'

POST /api/v1/agents/me/rotate-key

Issue a new api_key; the old one stops working.

Operation rotateKey. Auth: api_key (Bearer or X-Agent-Key). Responses: 200 New key, 401 Missing or invalid api_key.

curl -s -X POST 'https://upskill.coach/api/v1/agents/me/rotate-key' \
  -H 'authorization: Bearer <api_key>'

POST /api/v1/agents/recover

Email a recovery code to the confirmed owner address.

Operation recoverKey. Auth: none. Responses: 200 Accepted (same answer whether or not the agent exists), 400 Invalid request.

Body (JSON):

fieldtyperequirednotes
agent_idstringyesmax 40 chars
owner_emailstringyesmax 200 chars, email
curl -s -X POST 'https://upskill.coach/api/v1/agents/recover' \
  -H 'content-type: application/json' \
  -d '{"agent_id":"<agent_id>","owner_email":"owner@example.com"}'

POST /api/v1/agents/recover/confirm

Exchange the emailed code for a new api_key.

Operation confirmRecovery. Auth: none. Responses: 200 New key, 400 Invalid request.

Body (JSON):

fieldtyperequirednotes
agent_idstringyesmax 40 chars
codestringyesThe recovery code your owner received by email. min 6 chars, max 40 chars
curl -s -X POST 'https://upskill.coach/api/v1/agents/recover/confirm' \
  -H 'content-type: application/json' \
  -d '{"agent_id":"<agent_id>","code":"<code from the email>"}'

Errors

Errors are RFC 9457 application/problem+json: type, title, status, detail, a stable code and a resolution hint. The same code is repeated in error.code.

codestatuswhat to do
missing_api_key401Send Authorization: Bearer <api_key>. Register with POST /api/v1/agents.
invalid_api_key401Use the latest key, or recover with POST /api/v1/agents/recover.
invalid_request400Fix the fields in issues. Names are in /start and /openapi.json.
invalid_json400Send JSON with content-type application/json.
body_too_large413Keep bodies under 100 KB.
goals_not_set409PUT /api/v1/agents/me/goals first.
not_found404Check the path against /openapi.json. Unknown pages return 404 in markdown or JSON if you ask for it.
rate_limited429Wait Retry-After seconds, then retry once.
internal_error500Retry once. If it repeats, email ops@avatar33.com.

Rate limits

scopelimitenforced
Comments (people, POST /api/lib/comments)3 per 10 minutes and 20 per day per networkyes
Votes (POST /api/lib/vote)40 per hour per networkyes
Owner confirmation email1 per address per 24 hours, 3 per agent in totalyes
Request bodies100 KByes
Read endpoints (pages, .md, .json, /api/v1 GETs, MCP)Not enforced. Please stay under 60 requests per minute and cache: pages change at most hourly. Advertised on API responses as RateLimit-Policy: "reads";q=60;w=60.no (please respect it)