A first call
The CHeKT API uses standard HTTPS + JSON with OAuth 2.0 Client Credentials. Exchange your client_id and client_secret for an access token, then send it as a Bearer header. If you've called any modern OAuth API, this will feel familiar.
# 1) Exchange client credentials for an access token
curl -X POST https://api.chekt.com/oauth/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials" \
-d "client_id=${CLIENT_ID}" \
-d "client_secret=${CLIENT_SECRET}"
# 2) Call the API
curl https://api.chekt.com/partner/v1/dealers/${DEALER_ID}/sites \
-H "Authorization: Bearer ${ACCESS_TOKEN}" \
-H "x-partner-trace-id: 550e8400-e29b-41d4-a716-123456789000"[
{
"site_id": 1,
"external_site_id": "1234567890",
"name": "Gangnam Headquarters",
"monitoring_station_id": 12345,
"external_monitoring_station_id": "12345",
"account_number": "1234567890",
"address1": "123 Teheran-ro, Gangnam-gu, Seoul",
"address2": "7th Floor, Suite 701",
"timezone": "Asia/Seoul",
"is_activated": 1,
"created_at": "2025-01-01 00:00:00"
}
]Request lifecycle
Every request follows the same five-step path. Knowing this helps when debugging 401 vs 403, and when reading our logs alongside yours.
- 01Your serviceCHeKT authPOST /oauth/token (client credentials)
- 02CHeKT authYour serviceIssue access_token (Bearer)
- 03Your serviceCHeKT Partner APIGET /partner/v1/dealers/{dealerId}/...Authorization: Bearer + x-partner-trace-id
- 04CHeKT Partner APICHeKT Partner APIVerify token, resolve dealer scope
- 05CHeKT Partner APIYour serviceReturn JSON + standard error codes
Authentication
Two flavours of auth, depending on which endpoint you're calling:
OAuth 2.0 — Client Credentials
Standard M2M flow. POST /oauth/token with client_id and client_secret; receive an access_token and use it as a Bearer header.
Authorization access token
The /partner/v1/dealers/connect endpoint accepts a user-authorized access token instead — that flow binds the dealer in the token to your external system's identifier.
Query strings on list endpoints
List endpoints (e.g. GET /partner/v1/dealers/{dealerId}/sites) accept a small, well-defined set of query parameters. No custom DSL — just the six parameters below.
fields- Comma-separated columns to select. Prefix with tableName when joining. Example: fields=site_id,name,timezone
filter- Format: filter=column,value,operator. Operators: eq (default), neq, lt, lte, gt, gte, regex. Repeatable — multiple filter params combine with AND.
sort- Single column name. Example: sort=created_at
dir- asc (default) or desc.
limit- Maximum rows. Example: limit=50
offset- Skip this many rows. Use with limit for offset-based pagination.
GET /partner/v1/dealers/42/sites
?fields=site_id,name,timezone
&filter=is_activated,1,eq
&filter=name,Gangnam,regex
&sort=created_at
&dir=desc
&limit=50
&offset=0Endpoints by resource family
The Partner API exposes seven resource families. Each is a path under /partner/v1/dealers/{dealerId}/.... See the full reference for every endpoint with parameters, auth scope, and response DTOs.
Dealers
/partner/v1/dealers/connectBind the dealer in the access token to your external_dealer_id.
Responses
- 200ResponseDealerDto with the connected mapping.
- 401Invalid or missing access token.
/partner/v1/dealers/{dealerId}Retrieve a single dealer by ID.
Responses
- 200ResponseDealerDto.
- 404Dealer not found.
Sites
/partner/v1/dealers/{dealerId}/sitesCreate a site under a dealer.
Parameters
external_site_idstringrequiredYour system's identifier.
namestringrequiredDisplay name.
timezonestringrequiredIANA timezone ID.
Responses
- 201ResponseSiteBasicDto.
/partner/v1/dealers/{dealerId}/sitesList sites under a dealer.
Responses
- 200Array of ResponseSiteBasicDto.
/partner/v1/dealers/{dealerId}/sites/{siteId}/activation-statusToggle a site between active and inactive.
Responses
- 200ResponseSiteBasicDto with updated is_activated.
Devices
/partner/v1/dealers/{dealerId}/sites/{siteId}/devicesBulk-create devices. Send an array; receive per-item success/failure.
Responses
- 201BulkDeviceCreationResponseDto.
/partner/v1/dealers/{dealerId}/sites/{siteId}/devicesBulk-update devices in one call.
Responses
- 200BulkDeviceUpdateResponseDto.
/partner/v1/dealers/{dealerId}/sites/{siteId}/devices/bulk-deleteBulk-delete devices by ID list.
Responses
- 200BulkDeviceDeleteResponseDto.
Alarm Verifications
/partner/v1/dealers/{dealerId}/sites/{siteId}/alarm-verifications/{verificationId}Submit dispatch or disregard for a pending verification.
Parameters
contact_idnumberrequiredContact who handled the verification.
actionenumrequireddispatch | disregard.
responded_atISO-8601requiredWhen the action was taken.
Responses
- 200ResponseAlarmVerificationDto.
The reference page covers the rest: Monitoring Stations, Contacts, Arming Settings, plus DTOs for every response shape.
Pagination
List endpoints use offset-based pagination via limit and offset. To page through all items, increase the offset by your limit each call until you get a short page.
async function listAllSites(dealerId: number) {
const limit = 100;
let offset = 0;
const all: Site[] = [];
while (true) {
const page = await chekt.get(
`/partner/v1/dealers/${dealerId}/sites?limit=${limit}&offset=${offset}`,
);
all.push(...page);
if (page.length < limit) break;
offset += limit;
}
return all;
}Error responses
Every endpoint uses the same four HTTP error codes. The response body always tells you which field or constraint failed.
- 400 Bad Request
- Invalid input — missing required field, wrong type, or failed validation.
- 401 Unauthorized
- Token missing, expired, or invalid. Refresh via /oauth/token.
- 403 Forbidden
- Token is valid but lacks scope for this dealer or resource.
- 404 Not Found
- Resource ID does not exist on this dealer.
Versioning & stability
The Partner API is versioned in the URL: /partner/v1/.... The current spec is version 0.8 — in active draft. Breaking changes are still possible during this phase; subscribe to the changelog to track them.
- New endpoints
- New optional request parameters
- New optional response fields
- Removing or renaming endpoints
- Removing or renaming response fields
- Changing field types
- Tightening required scopes