Skip to main content

Getting Started

Base URL

All endpoints are versioned under /v1.
Building an integration? Start with objects.md. GET /v1/objects and GET /v1/objects/{object}/schema let you discover the available entities and their fields at runtime, including fields the tenant has added or disabled — so you do not have to hard-code a field list that a customer can invalidate. Then see records.md for reading and writing those records, and webhooks.md for receiving events in real time.

Authentication

Every request (except the public endpoints /v1/health, /v1/onboarding and /v1/availability) must carry a credential — an API key in the x-api-key header, or an OAuth 2.1 access token as Authorization: Bearer <jwt> (see auth.md):
Keys are f9_live_… (real data) or f9_test_… (sandbox — see test-mode.md). API keys are created in Settings > API Keys within the CRM dashboard, or headlessly via POST /v1/api-keys. Each key has:
  • Scopes that control which endpoints it can access
  • Rate limits (per minute and per hour — see rate-limits.md)
  • Optional IP allowlist (supports CIDR notation)
  • Optional expiration date

Request Format

  • All request bodies must be valid JSON with Content-Type: application/json
  • Maximum request body size: 100 KB
  • Maximum JSON nesting depth: 5 levels
  • Maximum keys per JSON object: 100

Response Format

All responses use a consistent envelope: Success:
Error:

Response Headers

Every response includes: On 429 responses, Retry-After is also included (seconds to wait).

Rate Limiting

Rate limits are enforced per API key at two windows: Both windows use a sliding window algorithm. If either is exceeded, you’ll receive a 429 response.

Handling 429 Responses

Best Practices

  1. Respect Retry-After headers — don’t retry immediately
  2. Monitor X-RateLimit-Remaining to pace your requests
  3. Use exponential backoff for retries
  4. Batch operations where possible instead of individual calls

Endpoints

Health Check

Check if the API is operational. No authentication required.
Response:

Onboard Company

Create a new company with an admin user and default configuration.
Required scope: onboarding Request body: Example:
What gets created:
  • Company record with active status
  • Default branch (“Main Branch”)
  • Auth user (with auto-generated password if not provided)
  • User record linked to company and branch
  • Company_Admin role assignment
  • 6 default deal statuses (New, Contacted, Qualified, Proposal, Won, Lost)
  • 5 default lead statuses (New, Contacted, Qualified, Converted, Disqualified)
  • 10 default activity types (Call, Email, Meeting, Note, Task, LinkedIn, WhatsApp, SMS, Postal Mail, Other)
  • Welcome email (unless send_welcome_email: false)
  • Audit log entry
Rollback: If user creation fails, the company is automatically deleted.

Get Customer by ID

Retrieve a customer profile with optional related data.
Required scope: customers:read Path parameters: Query parameters: Example:

Lookup Customer by Email

Find a customer by their email address.
Required scope: customers:read Query parameters: Example:

Create Lead

Create a new lead with optional assignment, tags, and custom fields.
Required scope: leads:write Request body: Example:
Notes:
  • If the company has duplicate detection enabled, a 409 is returned when a lead with the same email exists
  • The lead_status and source fields are resolved by name (case-insensitive) against the company’s configured values
  • If assigned_to_email is omitted, the lead is assigned to the first active company user

Create Activity

Log a new activity against a deal or lead.
Required scope: activities:write Request body: Example:
Side effects:
  • Updates the entity’s last_contacted_at
  • Updates next_followup_at if followup_at is provided
  • Triggers SLA tracking update
  • Creates audit log entry

Update Activity

Update an existing activity.
Required scope: activities:update Path parameters: Query parameters: Updatable fields: summary, details, activity_type, followup_at, performed_at At least one field must be provided. Example:
Notes:
  • Set followup_at to null to clear the scheduled follow-up
  • The activity must belong to an entity within your company

Error Code Reference


Available Scopes

Partial wildcards are also supported: leads:* matches leads:write and leads:read.

Changelog

v1.0.0 (2026-02-15)

  • Initial release
  • Endpoints: health, onboard, customers (by ID / by email), leads create, activities create/update
  • API key authentication with SHA-256 hashing
  • Multi-window rate limiting (per minute + per hour)
  • Input sanitization, security headers, IP allowlisting
  • Audit logging and abuse detection