La documentación para desarrolladores solo está en inglés por ahora. El resto del sitio está en español.

Developer docs

Ask fifty verified people a question from your code or your agent, and get a distribution back in about ten minutes. Everything is plain JSON over HTTPS.

Quick start

  1. Sign in at 50heads.com/app/developers and make an API key. It starts fh_live_ and is shown once.
  2. Estimate the question. It's free and never spends.
  3. Ask it with an idempotency key, then wait for the result.
curl https://api.50heads.com/v1/billing/estimate \
  -H "Content-Type: application/json" \
  -d '{"draft":{"type":"single_choice","text":"Which menu would you order from tonight?",
       "options":[{"label":"Menu A"},{"label":"Menu B"}],"n":50,"tier":1}}'

curl https://api.50heads.com/v2/questions \
  -H "Authorization: Bearer $FIFTYHEADS_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"draft":{"type":"single_choice","text":"Which menu would you order from tonight?",
       "options":[{"label":"Menu A"},{"label":"Menu B"}],"n":50,"tier":1,"language":"en"}}'

curl "https://api.50heads.com/v2/questions/q_8k2f/wait?seconds=25" \
  -H "Authorization: Bearer $FIFTYHEADS_API_KEY"

Base URL and versions

https://api.50heads.com. Question endpoints are under /v2; pricing, config, drafts, uploads and billing under /v1. We add fields without notice and never remove or rename one within a version.

Authentication

Send Authorization: Bearer fh_live_…. Keys carry scopes and a daily spend cap, set when you make them. Keys are for servers, CI and scripts: requests from a browser origin are refused. MCP hosts use OAuth instead; see MCP server.

ScopeGrants
questions:readResults, question lists, drafts
questions:writeEstimate, ask, cancel, share, uploads
templates:readTemplates (also available without a key)
account:readBalance, ledger, what is left under the cap

Money

Everything is in credits, as integers: 1 credit is 1p. Asking reserves the full price (per answer × heads); answers not given are refunded when the question closes, is cancelled or is refused.

Idempotency

POST /v2/questions needs an Idempotency-Key header, a UUID you make per question. If a request times out, send it again with the same key: you get the original question back, never a second ask. Keys are kept for 24 hours. The same key with a different body is idempotency_conflict.

Errors

Errors are JSON: { "error": { "code": "…", "message": "…" } }. The message is one plain sentence you can show a person or hand to a model. Branch on code, never on the message.

CodeHTTPMeaning
validation400The body or query failed validation. error.validation lists each field and a fix.
unauthorized401No key or token, or it was revoked. MCP responses carry WWW-Authenticate with the resource metadata URL.
insufficient_scope403The key or token lacks the scope this call needs. Re-authorise with the scope named in the error.
not_found404No such question, draft or result, or it isn't yours.
idempotency_conflict409The Idempotency-Key was used with a different body in the last 24 hours.
insufficient_credits402Not enough credits for the full price. The error says how many are needed and links to top up.
spend_cap_exceeded402The ask would take this key or connection past its daily cap. The error says what is left and when it resets.
content_refused422The question breaks the acceptable use policy. Nothing is spent; the error names the category.
rate_limited429Too many requests. Wait for Retry-After seconds.
unavailable503Asking is paused for maintenance. The error says until when.

Rate limits

60 requests a minute per key or connection, and 10 asks a minute. Estimates count half. Over the limit you get 429 with Retry-After. Ask us to raise a key's limits.

Pagination

Lists return nextCursor. Pass it back as cursor for the next page; it is null on the last one.

Waiting for results

Don't poll. GET /v2/questions/{id}/wait?seconds=25 holds the request until the question is answered or 25 seconds pass; call it again while done is false. Or register a webhook and we'll tell you.