Overview
BROSH CRM exposes an OAuth2 integration plus a table-based records API.
Supported objects are accessed by passing :tableName in the URL.
access_token via OAuth2 token exchange.
For authenticated endpoints, send Authorization: Bearer <access_token>.
Supported Objects
Use these values as :tableName:
| Object / tableName | Notes |
|---|---|
accounts | Account / company records |
activity | Activities / tasks / events / campaigns members(implementation-specific) |
campaigns | Marketing campaigns |
contacts | People / contacts |
currency | Currency data |
objects | System objects / metadata (implementation-specific) |
opportunities | Deals / opportunities |
opportunity_products | Line items linking products to opportunities |
payments | Payments / transactions |
products | Product catalog |
projects | Projects |
tickets | Support tickets |
timesheet | Timesheets |
custom_object | Custom objects (table schema varies) |
Common Fields (Available on All Objects)
All objects in BROSH CRM include the following standard fields, which can be used in queries, filters, and sorting:
| Field Name | Type | Description |
|---|---|---|
id | Integer | Unique identifier for the record |
name | String | Display name or title of the record |
created_by | Integer | User ID who created the record |
created_date | DateTime | Timestamp when the record was created |
last_modified_by | Integer | User ID who last modified the record |
last_modified_date | DateTime | Timestamp of the last modification |
fields, filter.where, and sort parameters. Each object may have additional custom fields specific to your BROSH deployment.
OAuth2 Authentication
BROSH CRM provides three OAuth-related endpoints: token exchange, token refresh, and a "me" call to validate tokens.
Authorization: Bearer <access_token>application/jsonExchange Authorization Code → Token
Exchange an OAuth2 authorization code for an access token (and typically a refresh token).
Request (example)
{
"code": "AUTH_CODE_FROM_BROSH_OAUTH_FLOW",
"redirect_uri": "https://yourapp.example.com/oauth/callback",
"client_id": "YOUR_CLIENT_ID",
"client_secret": "YOUR_CLIENT_SECRET",
"grant_type": "authorization_code"
}
Response (example)
{
"access_token": "eyJhbGciOi...",
"refresh_token": "def50200...",
"token_type": "Bearer",
"expires_in": 3600
}
Fields depend on your BROSH OAuth2 configuration; the example matches typical OAuth2 responses.
Refresh Token
Use a refresh token to obtain a new access token.
Request (example)
{
"refresh_token": "def50200...",
"client_id": "YOUR_CLIENT_ID",
"client_secret": "YOUR_CLIENT_SECRET",
"grant_type": "refresh_token"
}
Response (example)
{
"access_token": "eyJhbGciOi...NEW",
"refresh_token": "def50200...MAYBE_NEW",
"token_type": "Bearer",
"expires_in": 3600
}
Test Token (Me)
Validate an access token and return information about the current identity/session.
Headers
Authorization: Bearer <access_token> Content-Type: application/json
Request
{}
Response (example)
{
"id": "encoded_account_user_id",
"userid": 123,
"name": "oauthuser"
}
Get Records (by IDs)
Provide an array of record IDs and receive the full records.
limit parameter to control the maximum number of records returned. Valid range: 1 to 10,000. If not specified, a default limit of 10 is applies.
Headers
Authorization: Bearer <access_token> Content-Type: application/json
Request Body Parameters
The request body should be an array of record IDs (numbers).
You can also pass objects with an id property, or a mix of both.
Query Parameters
| Parameter | Type | Description |
|---|---|---|
limit |
number |
Maximum number of records to return. Valid range: 1 to 10,000. Defaults to 10. |
Request (example - array of IDs)
[101, 102, 205]
Request (example - array of objects)
[{"id": 101}, {"id": 102}, {"id": 205}]
Request with limit query parameter
POST /api/oauth2/getRecords/contacts?limit=100 [101, 102, 205]
Response (example)
[
{
"id": 101,
"name": "Acme Ltd",
"created_by": 5,
"created_date": "2025-01-15T10:30:00Z",
"last_modified_by": 5,
"last_modified_date": "2025-01-20T14:22:00Z"
},
{
"id": 102,
"name": "Globex",
"created_by": 3,
"created_date": "2025-01-10T09:15:00Z",
"last_modified_by": 7,
"last_modified_date": "2025-01-18T16:45:00Z"
}
]
Find Records (filter / fields / sort / paging)
A powerful flexible querying endpoint supporting: selecting specific fields, filtering with advanced operators, text search, multi-field sorting, and pagination.
id, name, created_by, created_date, last_modified_by, last_modified_date)
as well as any custom fields specific to your table schema.
Request Body
| Field | Type | Description |
|---|---|---|
fields |
string[] |
List of columns to return. If omitted/empty, returns * (all fields). |
filter |
object |
Filtering object with multiple options (see below). |
filter.id |
string|number |
Exact match by ID. |
filter.where |
object |
Field conditions. Supports simple values for equality (e.g., {"status":"Open"}) or operator objects for advanced queries (see examples below). |
filter.search |
string |
Text search applied to the name field with pattern matching support (use % for wildcards). |
sort |
{field:string, direction:"ASC"|"DESC"}[] |
Array of sort clauses. Invalid directions default to ASC. Supports multi-field sorting. |
page_size |
number|string |
Number of records per page. Defaults to 50 if missing. |
page |
number|string |
Page number for pagination. Defaults to 1 if missing. |
Query Parameters
| Parameter | Type | Description |
|---|---|---|
limit |
number |
Optional. Maximum number of records to return. Valid range: 1 to 10,000. Defaults to 10. Can override pagination settings. |
filter.where field supports multiple operators for complex queries:
=- Equality (default)>,<,>=,<=- Comparison operators!=- Not equalLIKE- Pattern matching (use % wildcards)IN- Match any value in arrayNOT IN- Exclude values in array
{"field": {"operator": ">=", "value": 100}}
Example 1: Simple equality filter with search
{
"fields": ["id", "name", "email", "phone"],
"filter": {
"search": "john"
},
"sort": [
{ "field": "name", "direction": "ASC" }
],
"page_size": 25,
"page": 1
}
Example 2: Multiple equality conditions
{
"filter": {
"where": {
"status": "Open",
"assigned_to": 17
}
},
"sort": [
{ "field": "updated_at", "direction": "DESC" }
],
"page_size": 50,
"page": 2
}
Example 3: Using comparison operators
{
"fields": ["id", "name", "amount", "deal_date"],
"filter": {
"where": {
"amount": {
"operator": ">=",
"value": 10000
},
"deal_date": {
"operator": ">",
"value": "2025-01-01"
}
}
},
"sort": [
{ "field": "amount", "direction": "DESC" }
],
"page_size": 100
}
Example 4: Using IN operator for multiple values
{
"fields": ["id", "name", "status", "priority"],
"filter": {
"where": {
"status": {
"operator": "IN",
"value": ["Open", "In Progress", "Pending"]
},
"priority": {
"operator": "!=",
"value": "Low"
}
}
},
"sort": [
{ "field": "priority", "direction": "ASC" },
{ "field": "created_date", "direction": "DESC" }
]
}
Example 5: Using LIKE operator for pattern matching
{
"fields": ["id", "name", "email"],
"filter": {
"where": {
"email": {
"operator": "LIKE",
"value": "%@company.com"
}
}
},
"page_size": 50
}
Example 6: Common fields filter with NOT IN
{
"fields": ["id", "name", "created_by", "created_date", "last_modified_date"],
"filter": {
"where": {
"created_by": {
"operator": "NOT IN",
"value": [1, 2, 3]
}
}
},
"sort": [
{ "field": "last_modified_date", "direction": "DESC" }
],
"page_size": 20,
"page": 1
}
Response (example)
[
{
"id": 501,
"name": "Contact Name",
"created_by": 5,
"created_date": "2025-01-15T10:30:00Z",
"last_modified_date": "2025-01-21T09:15:00Z"
},
{
"id": 498,
"name": "Another Contact",
"created_by": 5,
"created_date": "2025-01-12T14:20:00Z",
"last_modified_date": "2025-01-20T16:45:00Z"
}
]
Create Records
Create one or more records in the specified table.
Headers
Authorization: Bearer <access_token> Content-Type: application/json
Request Body
The request body must be an array of record objects to create.
Request (example)
[
{ "name": "New Account", "phone": "+1-555-0100" },
{ "name": "Another Account", "phone": "+1-555-0200" }
]
Response (example)
{
"id": 901,
"affectedRows": 2,
"insertId": 901
}
Update Records
Update one or more records by ID.
Headers
Authorization: Bearer <access_token> Content-Type: application/json
Request Body
The request body must be an array of record objects to update. Each object must include an id field.
Request (example)
[
{ "id": 101, "phone": "+1-555-9999", "status": "Active" },
{ "id": 102, "status": "Inactive" }
]
Response (example)
{
"id": 0,
"affectedRows": 2,
"changedRows": 2
}
Delete Records
Delete one or more records by ID.
Headers
Authorization: Bearer <access_token> Content-Type: application/json
Request Body
The request body must be an array of objects with id fields to delete.
Request (example)
[
{"id": 101},
{"id": 102}
]
Response (example)
{
"id": 0,
"affectedRows": 2
}
Errors & Notes
Common HTTP statuses
| Status | Meaning |
|---|---|
200 | Success (some implementations may still return ok:false in body on logical errors) |
400 | Bad request (missing/invalid parameters) |
401 | Unauthorized (missing/invalid/expired token) |
403 | Forbidden (token valid but insufficient permissions) |
404 | Unknown endpoint or invalid tableName |
500 | Server error |
fields selection to minimize payload size.
Example cURL - Find Records
curl -X POST "https://app.brosh.io/api/oauth2/findRecords/contacts" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"fields":["id","name","email","created_date","last_modified_date"],
"filter":{"search":"john"},
"sort":[{"field":"last_modified_date","direction":"DESC"}],
"page_size":25,
"page":1
}'
Example cURL - Get Records with Limit
curl -X POST "https://app.brosh.io/api/oauth2/getRecords/contacts?limit=100" \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d '[101,102,205]'
