Auth & Limits

01Authentication

All /api/v1 requests use Bearer token auth:

Authorization: Bearer <secret-api-key>
Content-Type: application/json
  • One Secret API Key per account with full access to every scope below.
  • Create or reveal it in Settings → Integration → API.
  • Revoked keys return 401 Unauthorized.

Scopes

Scope Allows
forms:read GET /api/v1/forms, GET /api/v1/forms/:id
forms:write POST /api/v1/forms/:formId/submissions
scheduling:read GET /api/v1/scheduling/event-types
scheduling:write POST /api/v1/scheduling/:eventTypeId/bookings
contacts:read GET /api/v1/contacts, GET /api/v1/contacts/:id
contacts:write POST /api/v1/contacts (upsert by email)
tags:read GET /api/v1/tags
tags:write POST /api/v1/contacts/tags, POST /api/v1/contacts/:id/tags
checkout:read GET /api/v1/products, GET /api/v1/customers, GET /api/v1/checkout/activations/:token
checkout:write POST /api/v1/checkout/activations/:token/complete
crm:read GET /api/v1/crms, GET /api/v1/crms/:crmId/stages
crm:write POST /api/v1/crms/:crmId/leads, PATCH /api/v1/crms/:crmId/leads/:leadId
webhooks:write POST/DELETE /api/v1/webhooks/subscriptions, GET /api/v1/webhooks/events/:event

Abuse prevention & rate limits

Protection Limit
Per IP (all traffic) 300 requests / minute
Per IP (failed auth) 30 failed Bearer attempts / 15 minutes
Per account (reads) 200 requests / minute
Per account (writes) 100 requests / minute
Per account (contacts & tags) 60 writes / minute
JSON body size 256 KB max

Rate limited responses return 429 with retryAfterSeconds and a Retry-After header.

Input validation: Oversized fields, too many tags/custom fields, or malformed JSON are rejected with 400 or 413.

Ownership: Every write verifies the resource belongs to the API key's account. Cross-account access returns 403.

Response format

Success: { "success": true, "contact": {}, ... } · Errors: { "error": "message" }

Status Meaning
401 Missing or invalid Bearer token
403 Missing scope, or resource belongs to another account
404 Route or resource not found
413 Request body too large
429 Rate limit exceeded
400 Validation error

02Base URL

Production (/api/v1 only responds on the API host):

https://api.funnels.cm

Local dev: http://api.localhost:<port>

03Inbound API endpoints

Method Path Purpose
GET /api/v1/contacts List contacts (?email= filter)
GET /api/v1/contacts/:contactId Get one contact
POST /api/v1/contacts Upsert contact by email (optional tagNames or tagIds)
POST /api/v1/contacts/tags Add/remove tags by email
POST /api/v1/contacts/:contactId/tags Add/remove tags by contact ID
GET /api/v1/tags List tags (id + name)
GET /api/v1/crms List CRM pipelines
GET /api/v1/crms/:crmId/stages List stages for a CRM
POST /api/v1/crms/:crmId/leads Create a lead (upserts contact by email)
PATCH /api/v1/crms/:crmId/leads/:leadId Update lead title, stage, or amount
GET /api/v1/forms List forms (id + name + fields)
GET /api/v1/forms/:formId Get one form
POST /api/v1/forms/:formId/submissions Submit a form programmatically
GET /api/v1/scheduling/event-types List calendars
GET /api/v1/scheduling/event-types/:eventTypeId Get one calendar
POST /api/v1/scheduling/:eventTypeId/bookings Create a calendar booking
GET /api/v1/products List checkouts
GET /api/v1/products/:productId Get a checkout (pricing options + bumps)
GET /api/v1/customers List checkout customers (?email= filter)
GET /api/v1/customers/:customerId Get one checkout customer
GET /api/v1/checkout/activations/:token Validate a SaaS signup activation token
POST /api/v1/checkout/activations/:token/complete Mark SaaS signup complete
POST /api/v1/webhooks/subscriptions Create a REST Hook subscription (Zapier)
DELETE /api/v1/webhooks/subscriptions/:id Delete a REST Hook subscription
GET /api/v1/webhooks/events/:eventName Sample payloads for Zapier trigger testing

CRM pipeline moves are configured on tags in Funnels.cm - send tagNames or tagIds via the contacts API. Use the CRM endpoints when you need to create or move leads directly.