Skip to main content
The CRM REST API is a generic resource router mounted at /api. Every CRM record type shares the same endpoint shape, so once you learn the pattern you can work with any resource. All endpoints require authentication (see Authentication).

Built-in resources

Use any of these as the :resource segment in the endpoints below:
Resource slugDescription
contactsPeople in your CRM
companiesOrganizations
dealsSales opportunities / pipeline records
tasksAction items linked to records
contact_notesNotes attached to contacts
deal_notesNotes attached to deals
company_notesNotes attached to companies
tagsLabels for organizing records
configurationCRM configuration entries
automation_rulesAutomation rule definitions
crm_usersCRM user records
companies_summaryAggregated company data (read-only)
contacts_summaryAggregated contact data (read-only)

Custom CRM objects

If your organization defines custom objects in the database, the :resource segment can also be the custom object’s slug. These resolve dynamically per organization and support the same CRUD endpoints as built-in resources.

Endpoints

List records

GET /api/:resource
Returns a JSON array of records. See Query parameters for filtering, sorting, and pagination.
curl "https://your-app.up.railway.app/api/contacts?range=[0,24]" \
  -H "Authorization: Bearer bos_crm_your_token_here"
Response: JSON array of record objects. The response includes a Content-Range header for pagination:
Content-Range: contacts 0-24/142
Format: <resource> <start>-<end>/<total>

Get one record

GET /api/:resource/:id
curl https://your-app.up.railway.app/api/contacts/c_abc123 \
  -H "Authorization: Bearer bos_crm_your_token_here"

Create a record

POST /api/:resource
curl -X POST https://your-app.up.railway.app/api/contacts \
  -H "Authorization: Bearer bos_crm_your_token_here" \
  -H "Content-Type: application/json" \
  -d '{
    "first_name": "Ada",
    "last_name": "Lovelace",
    "email": "ada@example.com",
    "company_id": "comp_xyz789"
  }'

Update a record

PUT /api/:resource/:id
curl -X PUT https://your-app.up.railway.app/api/contacts/c_abc123 \
  -H "Authorization: Bearer bos_crm_your_token_here" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "ada.new@example.com"
  }'

Delete a record

DELETE /api/:resource/:id
Deletes or archives the record depending on the resource type’s rules.
curl -X DELETE https://your-app.up.railway.app/api/deals/d_deal456 \
  -H "Authorization: Bearer bos_crm_your_token_here"

Restore a record

POST /api/:resource/:id/restore
Restores a previously deleted/archived record. Supported where the backend allows (e.g. deals).
curl -X POST https://your-app.up.railway.app/api/deals/d_deal456/restore \
  -H "Authorization: Bearer bos_crm_your_token_here"

Merge contacts

POST /api/merge_contacts
A special action to merge two or more contact records. This is not part of the generic :resource pattern.
curl -X POST https://your-app.up.railway.app/api/merge_contacts \
  -H "Authorization: Bearer bos_crm_your_token_here" \
  -H "Content-Type: application/json" \
  -d '{
    "source_ids": ["c_abc123", "c_def456"],
    "target_id": "c_abc123"
  }'

Endpoint summary

MethodPathDescription
GET/api/:resourceList records (paginated).
GET/api/:resource/:idGet one record.
POST/api/:resourceCreate a record.
PUT/api/:resource/:idUpdate a record.
DELETE/api/:resource/:idDelete or archive a record.
POST/api/:resource/:id/restoreRestore an archived record.
POST/api/merge_contactsMerge contacts (special action).

Query parameters

Use these on GET /api/:resource to control pagination, filtering, and sorting.

range

JSON array specifying the inclusive start and end indices for pagination.
# Fetch records 0 through 24 (first 25 records)
GET /api/contacts?range=[0,24]
If omitted, the server defaults to [0, 24].

filter

JSON object for legacy filter support. Keys are field names, values are the match criteria.
# Filter contacts where status is "active"
GET /api/contacts?filter={"status":"active"}

filters

JSON array of filter objects for advanced filtering. Each object specifies a field, operator, value, and optional logical operator.
GET /api/contacts?filters=[{"field":"status","op":"eq","value":"active","logicalOp":"and"},{"field":"city","op":"eq","value":"London"}]
PropertyTypeDescription
fieldstringThe field name to filter on.
opstringOperator (e.g. eq, neq, gt, lt, gte, lte, contains, starts_with).
valueanyThe value to compare against.
logicalOpstring"and" or "or". Combines with the next filter. Optional.

sort and order

Single-field sort.
# Sort by created_at descending
GET /api/contacts?sort=created_at&order=DESC
ParameterValues
sortAny field name
orderASC or DESC

sorts

JSON array of sort objects for multi-field sorting.
GET /api/contacts?sorts=[{"field":"last_name","order":"ASC"},{"field":"created_at","order":"DESC"}]

Full example

curl -G "https://your-app.up.railway.app/api/contacts" \
  --data-urlencode 'range=[0,49]' \
  --data-urlencode 'filters=[{"field":"status","op":"eq","value":"active"}]' \
  --data-urlencode 'sorts=[{"field":"last_name","order":"ASC"}]' \
  -H "Authorization: Bearer bos_crm_your_token_here"

Pagination with Content-Range

List responses include a Content-Range header:
Content-Range: contacts 0-24/142
SegmentMeaning
contactsThe resource name.
0-24Start and end indices of the returned window.
142Total number of records matching the query.
Use this to build pagination controls on the client side. Increment the range parameter to fetch the next page:
# Page 1
GET /api/contacts?range=[0,24]
# Page 2
GET /api/contacts?range=[25,49]
# Page 3
GET /api/contacts?range=[50,74]

Request body format

  • Send JSON with Content-Type: application/json.
  • The API accepts snake_case field names (e.g. first_name, company_id). The server maps these to internal camelCase for built-in tables automatically.
  • Writable fields per resource are enforced server-side via a whitelist. Fields not in the whitelist are silently ignored.
To discover the exact fields available for a resource, use the schema introspection endpoint: GET /api/schema/:tableName. See Related APIs for details.