Skip to main content

Onboard your Agent

Paste this into Claude Code, Cursor, Windsurf, or any coding agent — it’ll read the full API index and set itself up:
Read https://docs.openfunnel.dev/llms.txt
Follow setup instructions to authenticate and start using OpenFunnel APIs.

Authentication

Every request authenticates with a single header:
HeaderValue
X-API-KeyYour API key (of_...)
Content-Typeapplication/json
No OAuth, no dashboard — agents and humans get a key the same way.

Get a key

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": "you@example.com"}'
2

Verify

POST /api/v1/agent/verify with the code returns your key.
curl -X POST https://api.openfunnel.dev/api/v1/agent/verify \
  -H "Content-Type: application/json" \
  -d '{"email": "you@example.com", "otp_code": "123456"}'
{
  "email": "you@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 endpoint:
curl https://api.openfunnel.dev/api/v1/credits/balance \
  -H "X-API-Key: $OPENFUNNEL_API_KEY" \
  -H "Content-Type: application/json"
import os, requests

resp = requests.get(
    "https://api.openfunnel.dev/api/v1/credits/balance",
    headers={"X-API-Key": os.environ["OPENFUNNEL_API_KEY"]},
)
resp.raise_for_status()
const resp = await fetch(
  "https://api.openfunnel.dev/api/v1/credits/balance",
  {
    method: "GET",
    headers: {
      "X-API-Key": process.env.OPENFUNNEL_API_KEY!,
      "Content-Type": "application/json",
    },
  },
);

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.