API reference

Base URL, authentication, request conventions, filter rows, error codes and plan responses for the SalesFlow HTTP API.

Overview

Everything the application does is available over a JSON HTTP API.

All endpoints live under /api on your own SalesFlow domain. Requests and responses are JSON unless noted, and every endpoint operates inside the organization you are signed in to — you never pass an organization identifier yourself.

Authentication

Session
The default. The signed-in user's session is used, and the endpoint applies that user's role and permissions. This is how the application itself calls the API.
Form secret
Used only by the public lead capture endpoint. Your website sends an x-contact-secret header instead of a session.

Permissions apply to the API, not just the interface

Where an endpoint lists a required permission, calling it as a user who lacks that permission returns 403 — the same rules that hide a button also block the request.

Conventions

ConventionDetail
Content typeapplication/json, except file upload endpoints which accept multipart/form-data
IdentifiersRecord ids are opaque strings; always pass back exactly what you received
DatesISO 8601 strings in responses
Pagingpage and limit query parameters; responses include totalPages and currentPage
FilteringA filters query parameter containing a JSON array of filter rows

Filter rows

List endpoints that support filtering accept the same structure the filter bar produces. Each row names a field, an operator and a value, and all rows must match.

The filters query parameter, before URL encoding
[
  { "field": "status", "operator": "is", "value": "hot" },
  { "field": "source", "operator": "is not", "value": "Import" }
]

Errors

Errors return a non-2xx status and a JSON body with a human-readable message. Validation failures include the specific problem so it can be shown next to the offending field.

StatusMeaning
400The request was malformed or failed validation
401Not signed in, or the form secret was missing or wrong
403Signed in, but not allowed — a permission, a plan limit or an expired trial
404The record does not exist in your organization
409A record with that email or phone number already exists
429Too many form submissions from the same lead in a short window
500Something went wrong on the server

Plan and trial responses

When a request is refused for subscription reasons the 403 body carries a code so the interface can show the right prompt.

CodeRaised when
PLAN_LIMITA usage cap such as contacts or deals has been reached
FEATURE_GATEDThe feature is not part of the current plan
SEAT_LIMITThe organization has no seats left for another member
FEATURE_COMING_SOONThe feature is entitled but not yet available
FREE_TRIAL_EXPIREDThe free trial has ended and no subscription is active
A plan limit response
{
  "code": "PLAN_LIMIT",
  "message": "You have reached the contact limit for your plan.",
  "plan": "starter",
  "upgradePlan": "pro",
  "limitKey": "contacts",
  "current": 500,
  "max": 500
}