Skip to main content
Every OpenFunnel API request authenticates with a single header:
HeaderValue
X-API-KeyYour API key (of_...)
Content-Typeapplication/json
There is no OAuth dance and no dashboard step required, agents and humans get a key the same way. Agents can read the machine-friendly version of this page at auth.md.

Get a key (Agent Auth)

1

Sign up / sign in

POST /api/v1/agent/sign-up sends a 6-digit code to your email. New users get an account; existing users use this to recover a lost key.
curl -X POST https://api.openfunnel.dev/api/v1/agent/sign-up \
  -H "Content-Type: application/json" \
  -d '{"email": "founder@example.com"}'
{ "email": "founder@example.com", "message": "Verification code sent to your email" }
2

Verify

POST /api/v1/agent/verify with the code returns your key. New users receive a fresh key; existing users get their current key back.
curl -X POST https://api.openfunnel.dev/api/v1/agent/verify \
  -H "Content-Type: application/json" \
  -d '{"email": "founder@example.com", "otp_code": "123456"}'
{
  "email": "founder@example.com",
  "api_key": "of_1234567890abcdef...",
  "is_new_user": true
}
The key is only returned at verification time and is not retrievable later. Store it securely. To recover a lost key, call sign-up again with the same email.

Authenticate requests

Send the key as X-API-Key on every other endpoint:
curl https://api.openfunnel.dev/api/v1/credits/balance \
  -H "X-API-Key: $OPENFUNNEL_API_KEY" \
  -H "Content-Type: application/json"

Errors and limits

The sign-up and verify endpoints return structured errors:
Statuserror_codeMeaning
400OTP_EXPIREDNo pending code, call sign-up again.
400OTP_INVALIDWrong code (details.remaining_attempts shows how many tries are left).
429RATE_LIMITEDToo many sign-up attempts (details.retry_after_seconds).
429OTP_MAX_ATTEMPTSCode exhausted after 10 tries, call sign-up again.
500INTERNAL_ERRORTransient server error, retry.
Verification codes expire after 24 hours and allow up to 10 attempts.