Skip to content

API Reference

REST API for integrating with the Booksui platform

Authentication

All API endpoints require authentication via a Supabase session token. Include the session cookie with your requests, or pass a Bearer token in the Authorization header.

// Using Bearer token
fetch('/api/v1/contacts?account_id=YOUR_ACCOUNT_ID', {
  headers: {
    'Authorization': 'Bearer YOUR_SESSION_TOKEN',
    'Content-Type': 'application/json'
  }
})

Every request that accesses account data requires a valid account_id parameter. The authenticated user must be the account owner or a team member.

Contacts

GET/api/v1/contacts

List contacts for an account with pagination, search, and type filtering.

Auth:Session token (Bearer or cookie)
Rate limit:60 requests/minute

Query Parameters

NameTypeRequiredDescription
account_idUUIDRequiredThe account to list contacts for
pagenumberOptionalPage number (default: 1)
page_sizenumberOptionalResults per page, 1-100 (default: 25)
searchstringOptionalSearch by first name, last name, or email
typestringOptionalFilter by type: lead, client, past_client, vendor, other

Response

{
  "data": [
    {
      "id": "uuid",
      "first_name": "Jane",
      "last_name": "Smith",
      "email": "jane@example.com",
      "phone": "+1234567890",
      "company": "Acme Inc",
      "contact_type": "client",
      "source": "referral",
      "created_at": "2025-01-15T10:00:00Z"
    }
  ],
  "total": 42,
  "page": 1,
  "page_size": 25
}
POST/api/v1/contacts

Create a new contact in an account.

Auth:Session token (Bearer or cookie)
Rate limit:30 requests/minute

Request Body

{
  "account_id": "uuid",        // required
  "first_name": "Jane",        // required
  "last_name": "Smith",        // optional
  "email": "jane@example.com", // optional, must be valid email
  "phone": "+1234567890",      // optional
  "company": "Acme Inc",       // optional
  "contact_type": "lead",      // optional: lead|client|past_client|vendor|other
  "source": "website"          // optional: website|referral|social_media|advertising|cold_outreach|repeat_client|other
}

Response

// 201 Created
{
  "data": {
    "id": "uuid",
    "first_name": "Jane",
    "last_name": "Smith",
    "email": "jane@example.com",
    "contact_type": "lead",
    "source": "website",
    "created_at": "2025-01-15T10:00:00Z"
  }
}
GET/api/v1/contacts/export

Export all contacts for an account as a CSV file download.

Auth:Session token (Bearer or cookie)
Rate limit:5 requests/minute

Query Parameters

NameTypeRequiredDescription
account_idUUIDRequiredThe account to export contacts from

Response

// Content-Type: text/csv
// Content-Disposition: attachment; filename="contacts-2025-01-15.csv"

First Name,Last Name,Email,Phone,Company,...
Jane,Smith,jane@example.com,+1234567890,Acme Inc,...

Deals

GET/api/v1/deals

List deals for an account with pagination and status filtering. Includes related contact and pipeline stage data.

Auth:Session token (Bearer or cookie)
Rate limit:60 requests/minute

Query Parameters

NameTypeRequiredDescription
account_idUUIDRequiredThe account to list deals for
pagenumberOptionalPage number (default: 1)
page_sizenumberOptionalResults per page, 1-100 (default: 25)
statusstringOptionalFilter by status: open, won, lost, abandoned

Response

{
  "data": [
    {
      "id": "uuid",
      "title": "Johnson Wedding Package",
      "value": 3500,
      "probability": 75,
      "status": "open",
      "expected_close_date": "2025-06-15",
      "contacts": { "id": "uuid", "first_name": "Jane", "last_name": "Smith" },
      "pipeline_stages": { "id": "uuid", "name": "Proposal Sent" }
    }
  ],
  "total": 12,
  "page": 1,
  "page_size": 25
}
POST/api/v1/deals

Create a new deal in an account.

Auth:Session token (Bearer or cookie)
Rate limit:30 requests/minute

Request Body

{
  "account_id": "uuid",              // required
  "title": "Johnson Wedding",        // required
  "contact_id": "uuid",              // optional, link to a contact
  "stage_id": "uuid",                // optional, pipeline stage
  "value": 3500,                     // optional, deal value (default: 0)
  "probability": 75,                 // optional, 0-100 (default: 50)
  "expected_close_date": "2025-06-15" // optional
}

Response

// 201 Created
{
  "data": {
    "id": "uuid",
    "title": "Johnson Wedding",
    "value": 3500,
    "probability": 75,
    "status": "open",
    "created_at": "2025-01-15T10:00:00Z"
  }
}

Invoices

GET/api/v1/invoices

List invoices for an account with pagination and status filtering. Includes related contact data.

Auth:Session token (Bearer or cookie)
Rate limit:60 requests/minute

Query Parameters

NameTypeRequiredDescription
account_idUUIDRequiredThe account to list invoices for
pagenumberOptionalPage number (default: 1)
page_sizenumberOptionalResults per page, 1-100 (default: 25)
statusstringOptionalFilter: draft, sent, viewed, partial, paid, overdue, cancelled, refunded

Response

{
  "data": [
    {
      "id": "uuid",
      "invoice_number": "INV-001",
      "amount": 2500.00,
      "status": "sent",
      "due_date": "2025-02-15",
      "contacts": { "id": "uuid", "first_name": "Jane", "last_name": "Smith" },
      "created_at": "2025-01-15T10:00:00Z"
    }
  ],
  "total": 8,
  "page": 1,
  "page_size": 25
}

Lead Forms

POST/api/v1/forms/[formId]/submit

Submit a lead capture form. Creates or updates a contact and records the submission. No authentication required (public endpoint).

Auth:None (public endpoint)
Rate limit:5 requests/minute per IP

Request Body

{
  "data": {
    "field_id_1": "Jane",
    "field_id_2": "Smith",
    "field_id_3": "jane@example.com",
    "field_id_4": "Tell me about your wedding photography packages"
  },
  "metadata": {
    "referrer": "https://google.com",
    "page": "/contact"
  }
}

Response

{
  "success": true,
  "contact_id": "uuid",
  "successMessage": "Thank you for your submission!",
  "redirectUrl": null
}

Account & Data Export

GET/api/v1/account/export

GDPR-compliant full data export. Downloads a JSON file with all account data including contacts, deals, invoices, proposals, contracts, galleries, bookings, workflows, and more. Restricted to account owners.

Auth:Session token (Bearer or cookie) - Account owner only
Rate limit:1 request/hour

Query Parameters

NameTypeRequiredDescription
account_idUUIDRequiredThe account to export data from (must be owner)

Response

// Content-Type: application/json
// Content-Disposition: attachment; filename="booksui-data-export-uuid-2025-01-15.json"

{
  "export_metadata": {
    "exported_at": "2025-01-15T10:00:00Z",
    "account_id": "uuid",
    "format_version": "1.0",
    "gdpr_request": true
  },
  "account": { ... },
  "contacts": [ ... ],
  "deals": [ ... ],
  "invoices": [ ... ],
  "proposals": [ ... ],
  "contracts": [ ... ],
  "galleries": [ ... ],
  "bookings": [ ... ],
  "workflows": [ ... ],
  ...
}

Error Handling

All error responses follow a consistent format:

// 400 Bad Request
{ "error": "Invalid payload", "details": { "first_name": ["Required"] } }

// 401 Unauthorized
{ "error": "Unauthorized" }

// 403 Forbidden
{ "error": "Forbidden: no access to this account" }

// 404 Not Found
{ "error": "Form not found or inactive" }

// 429 Too Many Requests
{ "error": "Rate limit exceeded" }

// 500 Internal Server Error
{ "error": "Internal server error" }

Need Help?

Have questions about integrating with the Booksui API? We are here to help.