Skip to main content

API Integration Guide

This guide provides comprehensive information for integrating with the SBM CRM Platform APIs.

Base URL

All API requests use service-specific paths:

https://api.sbmcrm.example.com/{service}/api

Where {service} is one of:

  • auth - Authentication and member management
  • point - Points management
  • reward - Rewards management
  • cluster - Tiers, badges, and interests
  • notification - Notifications and messaging

Examples:

  • https://api.sbmcrm.example.com/auth/api/members/me
  • https://api.sbmcrm.example.com/point/api/balance/me
  • https://api.sbmcrm.example.com/reward/api/reward-catalogs

Request Format

Headers

All requests must include:

Authorization: Bearer YOUR_ACCESS_TOKEN
Content-Type: application/json
Accept: application/json

Request Body

For POST, PUT, and PATCH requests, send JSON in the request body:

{
"field1": "value1",
"field2": "value2"
}

Response Format

Success Response

HTTP/1.1 200 OK
Content-Type: application/json

{
"statusCode": 200,
"data": {
"id": "12345",
"name": "John Doe"
}
}

Error Response

HTTP/1.1 400 Bad Request
Content-Type: application/json

{
"statusCode": 400,
"data": {
"message": "The request is invalid",
"errors": [
{
"field": "email",
"message": "Email is required"
}
]
}
}

Common HTTP Status Codes

  • 200 OK - Request successful
  • 201 Created - Resource created successfully
  • 400 Bad Request - Invalid request parameters
  • 401 Unauthorized - Authentication required
  • 403 Forbidden - Insufficient permissions
  • 404 Not Found - Resource not found
  • 429 Too Many Requests - Rate limit exceeded
  • 500 Internal Server Error - Server error

Rate Limiting

API requests are rate-limited to ensure fair usage:

  • Standard Tier: 1,000 requests per hour
  • Premium Tier: 10,000 requests per hour
  • Enterprise Tier: Custom limits

Rate limit information is included in response headers:

X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 999
X-RateLimit-Reset: 1609459200

Handling Rate Limits

When rate limited, you'll receive a 429 status code:

HTTP/1.1 429 Too Many Requests
Retry-After: 60

{
"statusCode": 429,
"data": {
"message": "Rate limit exceeded. Please retry after 60 seconds."
}
}

Pagination

List endpoints support pagination:

Query Parameters

  • page - Page number (default: 1)
  • limit - Items per page (default: 20, max: 100)
  • sort - Sort field and direction (e.g., created_at:desc)

Response Format

{
"statusCode": 200,
"data": {
"meta": {
"page": 1,
"limit": 20,
"total": 150,
"totalPages": 8
},
"data": [...]
}
}

Example Request

GET /auth/api/members?page=1&limit=20

Many endpoints support filtering and search:

Query Parameters

  • filter[field] - Filter by field value
  • search - Full-text search
  • date_from / date_to - Date range filtering

Example

GET /auth/api/members?status=ACTIVE&includeTier=true
GET /point/api/history?actionType=EARN&startDate=2024-01-01&endDate=2024-12-31

Webhooks

Webhooks allow you to receive real-time notifications of events. See the Webhooks Guide for details.

Code Examples

Get Current Member (Auth Service)

const response = await fetch('https://api.sbmcrm.example.com/auth/api/members/me', {
headers: {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/json'
}
});

const result = await response.json();
const member = result.data; // Access data from statusCode/data wrapper

Get Member Point Balance (Point Service)

const response = await fetch('https://api.sbmcrm.example.com/point/api/balance/me', {
headers: {
'Authorization': `Bearer ${accessToken}`
}
});

const result = await response.json();
const balance = result.data;

Earn Points (Point Service)

const response = await fetch('https://api.sbmcrm.example.com/point/api/earn', {
method: 'POST',
headers: {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
memberId: '550e8400-e29b-41d4-a716-446655440000',
amount: 100,
purchaseAmount: 5000,
sourceBy: 'Purchase',
note: 'Purchase bonus'
})
});

const result = await response.json();

List Reward Catalogs (Reward Service)

const page = 1;
const limit = 20;

const response = await fetch(
`https://api.sbmcrm.example.com/reward/api/reward-catalogs?page=${page}&limit=${limit}&status=ACTIVE`,
{
headers: {
'Authorization': `Bearer ${accessToken}`
}
}
);

const result = await response.json();
const catalogs = result.data.data; // Nested data array
const meta = result.data.meta; // Pagination metadata

Get Member Tier (Cluster Service)

const response = await fetch('https://api.sbmcrm.example.com/cluster/api/tier-projections/me', {
headers: {
'Authorization': `Bearer ${accessToken}`
}
});

const result = await response.json();
const tierProjection = result.data;

Create In-App Notification (Notification Service)

const response = await fetch('https://api.sbmcrm.example.com/notification/api/in-apps', {
method: 'POST',
headers: {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
title_en: 'Welcome!',
content_en: 'Thank you for joining us.',
format: 'raw',
type: 'news',
memberId: '550e8400-e29b-41d4-a716-446655440000'
})
});

const result = await response.json();
const notification = result.data.data;

Error Handling

Retry Logic

Implement exponential backoff for retries:

async function apiRequest(url, options, retries = 3) {
for (let i = 0; i < retries; i++) {
try {
const response = await fetch(url, options);

if (response.status === 429) {
const retryAfter = parseInt(response.headers.get('Retry-After') || '60');
await sleep(retryAfter * 1000);
continue;
}

if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
}

return await response.json();
} catch (error) {
if (i === retries - 1) throw error;
await sleep(Math.pow(2, i) * 1000); // Exponential backoff
}
}
}

function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}

Error Handling Example

try {
const customer = await getCustomer('12345');
} catch (error) {
if (error.response) {
switch (error.response.status) {
case 401:
// Re-authenticate
await refreshToken();
break;
case 404:
// Customer not found
console.log('Customer does not exist');
break;
case 429:
// Rate limited - retry after delay
await sleep(error.response.headers['retry-after'] * 1000);
break;
default:
console.error('API Error:', error.response.data);
}
}
}

SDKs and Libraries

Official SDKs are available for:

  • JavaScript/Node.js - @sbmcrm/sdk-js
  • Python - sbmcrm-python
  • PHP - sbmcrm-php

Using the JavaScript SDK

import { SBMCRMClient } from '@sbmcrm/sdk-js';

const client = new SBMCRMClient({
apiKey: process.env.API_KEY,
baseURL: 'https://api.sbmcrm.example.com'
});

// Use the client
const member = await client.auth.members.getMe();
const balance = await client.point.balance.getMe();
const points = await client.point.earn({
memberId: 'member-id',
amount: 100,
sourceBy: 'Purchase'
});

Testing

Sandbox Environment

Use the sandbox environment for testing:

https://api-sandbox.sbmcrm.example.com/{service}/api

Test Credentials

Test API keys are available in the Admin Web App under SettingsAPI KeysTest Keys.

Best Practices

  1. Always use HTTPS - Never make API calls over HTTP
  2. Store credentials securely - Use environment variables or secure vaults
  3. Implement retry logic - Handle transient failures gracefully
  4. Respect rate limits - Implement rate limiting on your side
  5. Use webhooks - Prefer webhooks over polling for real-time updates
  6. Cache when appropriate - Cache static or infrequently changing data
  7. Handle errors gracefully - Provide meaningful error messages to users
  8. Log API calls - Log requests and responses for debugging (excluding sensitive data)