Clearmargin
API

API Reference

Clearmargin REST API — authentication, endpoints, query syntax, and error handling.

Programmatic access to your Clearmargin data via the REST API. Create integrations, automate workflows, and connect with third-party tools.

Base URL

All endpoint paths in this reference are relative to the base URL:

https://www.clearmargin.app/api

Authentication

All API requests require authentication via an API key. Create keys in your dashboard at Settings > API Keys.

Include your API key using either method:

Authorization header (recommended):

Authorization: Bearer sk_live_your_api_key_here

x-api-key header (alternative):

x-api-key: sk_live_your_api_key_here

Organization scoping

API keys are scoped to your organization. All data returned is automatically filtered to your organization. You cannot access data from other organizations.

Rate Limits

API requests are rate-limited to ensure platform stability.

LimitWindow
100 requestsPer minute, per API key

Rate limit status is included in every response via headers:

HeaderDescription
X-RateLimit-LimitMaximum requests allowed per window
X-RateLimit-RemainingRequests remaining in the current window
X-RateLimit-ResetUnix timestamp when the window resets

When rate-limited, the API returns HTTP 429 with a Retry-After header indicating when you can retry.

Resources

Clearmargin exposes a RESTful API following standard CRUD patterns. Each resource supports list, get, create, update, and delete operations.

ResourceEndpointDescription
Clients/api/clientsClient and company records
Projects/api/projectsClient projects with scope tracking
Invoices/api/invoicesClient invoices and billing
Proposals/api/proposalsClient proposals with line items
Time Entries/api/time-entriesTime logged against projects
Transactions/api/transactionsUnified cost and revenue ledger
Catalog Items/api/catalog-itemsService and product catalog
Contacts/api/contactsContact people on clients
Milestones/api/milestonesProject and proposal milestones
Calendar Events/api/calendar-eventsSchedule calendar events
Webhooks/api/webhooksWebhook endpoint configuration

Each resource supports these operations:

  • GET /api/{resource} --- List all records
  • GET /api/{resource}/:id --- Get a single record
  • POST /api/{resource} --- Create a new record
  • PATCH /api/{resource}/:id --- Update a record
  • DELETE /api/{resource}/:id --- Delete a record

Query Syntax

List endpoints support filtering, sorting, pagination, and relationship population via query parameters.

Parameters

ParameterTypeDescription
whereObjectFilter results using Payload query syntax
sortStringField name to sort by. Prefix with - for descending
limitNumberResults per page (default: 10, max: 100)
pageNumberPage number for pagination (starts at 1)
depthNumberRelationship population depth (default: 1, max: 3)

Filtering

The where parameter uses Payload query syntax. Pass conditions as nested query parameters:

# Filter clients by status
GET /api/clients?where[status][equals]=active

# Filter invoices by amount greater than 1000
GET /api/invoices?where[total][greater_than]=1000

# Filter time entries by date range
GET /api/time-entries?where[date][greater_than_equal]=2026-01-01&where[date][less_than]=2026-02-01

# Combine filters with AND (default)
GET /api/projects?where[status][equals]=active&where[client][equals]=client_id_here

Operators

OperatorDescription
equalsExact match
not_equalsNot equal to
greater_thanGreater than
greater_than_equalGreater than or equal
less_thanLess than
less_than_equalLess than or equal
likeCase-insensitive partial match
containsString contains
inValue is in array
existsField exists / is not null

Sorting

Sort results by any field. Prefix the field name with - for descending order:

# Newest first
GET /api/clients?sort=-createdAt

# Oldest due dates first
GET /api/invoices?sort=dueDate

Pagination

# Page 2, 25 results per page
GET /api/clients?page=2&limit=25

List endpoints return paginated results in this format:

{
  "docs": [...],
  "totalDocs": 42,
  "limit": 10,
  "totalPages": 5,
  "page": 1,
  "pagingCounter": 1,
  "hasPrevPage": false,
  "hasNextPage": true,
  "prevPage": null,
  "nextPage": 2
}

Depth

Control how deeply related documents are populated:

# Populate one level of relationships (default)
GET /api/invoices?depth=1

# Populate nested relationships (e.g., invoice > client > contacts)
GET /api/invoices?depth=2

Examples

List clients

curl -H "Authorization: Bearer sk_live_your_key" \
  "https://www.clearmargin.app/api/clients?limit=10&sort=-createdAt"

Create a client

curl -X POST \
  -H "Authorization: Bearer sk_live_your_key" \
  -H "Content-Type: application/json" \
  -d '{"name": "Acme Corp", "email": "billing@acme.com"}' \
  "https://www.clearmargin.app/api/clients"

Get unpaid invoices

curl -H "Authorization: Bearer sk_live_your_key" \
  "https://www.clearmargin.app/api/invoices?where[status][not_equals]=paid&sort=dueDate"

Log a time entry

curl -X POST \
  -H "Authorization: Bearer sk_live_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "project": "project_id_here",
    "hours": 2.5,
    "date": "2026-03-14",
    "description": "API integration work",
    "billable": true
  }' \
  "https://www.clearmargin.app/api/time-entries"

Error Handling

The API uses standard HTTP status codes to indicate success or failure.

StatusDescription
200Success
201Created (for POST requests)
400Bad request (invalid parameters or body)
401Unauthorized (missing or invalid API key)
403Forbidden (key lacks required permissions)
404Resource not found
429Rate limited (too many requests)
500Internal server error

Error responses include a JSON body describing what went wrong:

{
  "errors": [
    {
      "message": "You are not allowed to perform this action.",
      "data": {
        "collection": "invoices"
      }
    }
  ]
}

Integration guides

Looking to connect Clearmargin with other tools? Check out the step-by-step guides for Zapier, n8n, and Make.

On this page