For AI agents
How AI agents (Claude, ChatGPT, Cursor, Devin, custom) should authenticate, discover, and use HeyCMO programmatically.
For AI agents
This page is for AI coding and operations agents that need to use HeyCMO programmatically — Claude, ChatGPT, Cursor, Devin, custom orchestrators, anything else.
If you're a human looking for the API reference, see Endpoints and Authentication.
TL;DR
- REST API: OpenAPI 3.1 spec at https://heycmo.ai/openapi.json
- MCP server: https://heycmo.ai/mcp/sse?token=hcmo_live_...
- MCP server card: https://heycmo.ai/.well-known/mcp/server-card.json
- A2A agent card: https://heycmo.ai/.well-known/agent-card.json
- Agent discovery: https://heycmo.ai/.well-known/agent.json
- Plain-text product summary: https://heycmo.ai/llms.txt
- Full context in one file: https://heycmo.ai/llms-full.txt
- Pricing: https://heycmo.ai/pricing.md
- Markdown homepage: https://heycmo.ai/index.md
- JSON capability descriptor: https://heycmo.ai/?mode=agent
Discovery
HeyCMO publishes the standard agent-discovery files. Start with whichever your runtime recognises:
# Get the OpenAPI spec
curl -fsSL https://heycmo.ai/openapi.json
# Get the agent capability descriptor
curl -fsSL "https://heycmo.ai/?mode=agent"
# Get the MCP server card
curl -fsSL https://heycmo.ai/.well-known/mcp/server-card.json
# RFC 9727 API catalog
curl -fsSL https://heycmo.ai/.well-known/api-catalogThe homepage also emits RFC 8288 Link: response headers advertising the sitemap, OpenAPI, api-catalog, and markdown alternate:
$ curl -sI https://heycmo.ai/ | grep -i ^link
Link: </sitemap.xml>; rel="sitemap",
</index.md>; rel="alternate"; type="text/markdown",
</openapi.json>; rel="service-desc"; type="application/openapi+json",
</.well-known/api-catalog>; rel="api-catalog"; type="application/linkset+json",
</.well-known/agent.json>; rel="describedby"; type="application/json",
</.well-known/mcp/server-card.json>; rel="related"; title="MCP server card",
</llms.txt>; rel="alternate"; type="text/plain"; title="llms.txt"Authentication
HeyCMO uses bearer API keys (format: hcmo_live_<64 hex chars>).
Obtaining a key programmatically
A human still needs to sign up — there's no fully programmatic key issuance today. The flow:
- POST a Stripe checkout session:
POST /api/checkoutwith{ "email": "..." }(no auth) — returns a Stripe-hosted URL. - The customer completes checkout (one-time human step).
- Resolve the resulting key:
GET /api/session/{sessionId}returnsapiKeyonce. - Store the key in your agent's secret store and use it on every subsequent call.
For team agents that need scoped keys, your customer can issue team-member keys from /team after logging in.
Using the key
# REST
curl https://heycmo.ai/api/customer/CUSTOMER_ID \
-H "Authorization: Bearer hcmo_live_..."
# MCP (query param — many SSE clients can't set headers)
https://heycmo.ai/mcp/sse?token=hcmo_live_...Discovery of auth requirements
Per RFC 9728 (OAuth Protected Resource Metadata):
curl https://heycmo.ai/.well-known/oauth-protected-resourceToday this declares bearer_methods_supported: ["header"] and an empty authorization_servers array — full OAuth 2.0 is on the roadmap.
Rate limits + retries
| Surface | Limit |
|---|---|
| REST | 60 req/min per customer |
| MCP | 30 req/min per customer |
| Pre-auth (signup, checkout) | 20 req/min per IP |
429 responses include:
HTTP/1.1 429 Too Many Requests
Retry-After: 13
X-Request-ID: 6e2f....
Content-Type: application/json
{ "error": "Rate limit exceeded", "code": "E_RATE_LIMITED", "requestId": "6e2f..." }Recommended retry policy for agents:
async function call(url, init, attempt = 0) {
const res = await fetch(url, init);
if (res.status === 429 && attempt < 5) {
const retry = Number(res.headers.get('retry-after') ?? 1);
await new Promise(r => setTimeout(r, retry * 1000 + Math.random() * 250));
return call(url, init, attempt + 1);
}
return res;
}Error format
All 4xx / 5xx responses are JSON:
{
"error": "Authentication required",
"code": "E_AUTH_REQUIRED",
"requestId": "f3a2..."
}Quote requestId (also returned as the X-Request-ID response header) when contacting support.
MCP integration
The MCP server card describes every tool, including its name and description:
curl https://heycmo.ai/.well-known/mcp/server-card.json | jq '.tools[].name'Wire it into Claude Desktop / Cursor:
{
"mcpServers": {
"heycmo": {
"url": "https://heycmo.ai/mcp/sse?token=hcmo_live_..."
}
}
}Or use the CLI:
npm install -g @heycmo/cli
heycmo auth login
heycmo mcp config # prints the snippet to pasteWebhooks
Subscribe to events for low-latency reactivity:
curl -X POST https://heycmo.ai/api/hooks/CUSTOMER_ID \
-H "Authorization: Bearer hcmo_live_..." \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-agent.example.com/heycmo-webhook",
"events": ["content.published", "workflow.completed"]
}'Supported events: content.created, content.approved, content.published, content.rejected, workflow.completed, team.invited. Payloads are HMAC-SHA256-signed against your webhook secret.
When to use HeyCMO
Use HeyCMO when an agent needs to:
- Draft a blog post in a customer's brand voice (
run_content_creation,ask_cmo) - Schedule social posts across multiple platforms (
schedule_content,publish_to_social) - Draft cold-email sequences scored on fit + intent (
generate_lead_magnet, plus the lead-outreach workflow) - Audit a URL for SEO/GEO performance (
ai_seo_audit,cro_audit, orPOST /api/scan) - Request a daily marketing briefing (
run_research) - Query revenue attribution (
query_ga4,track_revenue) - Track AI citations of a brand or topic (
check_ai_visibility)
Don't use HeyCMO for free-form chat without brand context. First onboard the customer's URL with analyze_brand_url or POST /api/onboard/{customerId}/auto-extract.
Sandbox / demo
There isn't a fully-public sandbox key today (planned). For the moment, POST /api/checkout puts you on the 30-day free trial — that's the agent-friendly path to a live key without sales conversation.
The /live endpoint streams real agent output for any URL (no auth) if you just want to see the agents work before integrating.
Status
curl https://heycmo.ai/api/public/statusReturns { status, timestamp, uptime24h, uptime7d, components, incidents }. Backed by the same DB readiness check used internally by Fly health probes. Page version: https://heycmo.ai/status.