BROSH CRM — OAuth2 Integration & API

Base URL: app.brosh.io All endpoints use POST
OAuth2 Records CRUD Flexible Find Table-based objects
Authorization: Bearer <access_token>

Overview

BROSH CRM exposes an OAuth2 integration plus a table-based records API. Supported objects are accessed by passing :tableName in the URL.

Authentication: Obtain an access_token via OAuth2 token exchange. For authenticated endpoints, send Authorization: Bearer <access_token>.

Supported Objects

Use these values as :tableName:

Object / tableNameNotes
accountsAccount / company records
activityActivities / tasks / events / campaigns members(implementation-specific)
campaignsMarketing campaigns
contactsPeople / contacts
currencyCurrency data
objectsSystem objects / metadata (implementation-specific)
opportunitiesDeals / opportunities
opportunity_productsLine items linking products to opportunities
paymentsPayments / transactions
productsProduct catalog
projectsProjects
ticketsSupport tickets
timesheetTimesheets
custom_objectCustom 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 NameTypeDescription
idIntegerUnique identifier for the record
nameStringDisplay name or title of the record
created_byIntegerUser ID who created the record
created_dateDateTimeTimestamp when the record was created
last_modified_byIntegerUser ID who last modified the record
last_modified_dateDateTimeTimestamp of the last modification
Field Flexibility: In addition to the common fields listed above, you can use any field available in your object/table schema in the 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.

Header
Authorization: Bearer <access_token>
Content-Type
application/json

Exchange Authorization Code → Token

POST /api/oauth2/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

POST /api/oauth2/refresh

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)

POST /api/oauth2/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)

POST /api/oauth2/getRecords/:tableName

Provide an array of record IDs and receive the full records.

Limit Parameter: This endpoint supports an optional 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

ParameterTypeDescription
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"
 }
]
Note: Request/response shapes may vary by table schema. IDs are typically numeric.

Find Records (filter / fields / sort / paging)

POST /api/oauth2/findRecords/:tableName

A powerful flexible querying endpoint supporting: selecting specific fields, filtering with advanced operators, text search, multi-field sorting, and pagination.

Field Usage: You can query, filter, and sort by any field available in your object/table. This includes the standard fields (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.
Advanced Filtering with Operators: The filter.where field supports multiple operators for complex queries:
  • = - Equality (default)
  • >, <, >=, <= - Comparison operators
  • != - Not equal
  • LIKE - Pattern matching (use % wildcards)
  • IN - Match any value in array
  • NOT IN - Exclude values in array
Use operator syntax: {"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

POST /api/oauth2/create/:tableName

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
}
Note: Only arrays are accepted. Each object in the array represents a record to create.

Update Records

POST /api/oauth2/update/:tableName

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
}
Note: Your schema determines which fields are writable.

Delete Records

POST /api/oauth2/delete/:tableName

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
}
Recycle Bin: Deleted records are moved to a recycle bin and retained for 30 days before permanent deletion.

Errors & Notes

Common HTTP statuses

StatusMeaning
200Success (some implementations may still return ok:false in body on logical errors)
400Bad request (missing/invalid parameters)
401Unauthorized (missing/invalid/expired token)
403Forbidden (token valid but insufficient permissions)
404Unknown endpoint or invalid tableName
500Server error
Best practice: Use valid field names (letters, numbers, underscore), and prefer explicit 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]'
We use cookies to personalize content, ads and to analyze our traffic. Our Cookie Policy Accept