API Documentation

REST API for building mobile apps, integrations, and custom frontends on SetiaPoints. All responses are JSON.

Base URL: https://setiapoints.com/api/{shop_slug}
Authentication Customer Staff Admin Public Errors

Authentication

The API uses two layers of authentication:

1. API Key (app-level) — Required for all endpoints except /shop and /auth. Pass via the X-API-Key header. Generate keys in your admin Settings page.

2. Bearer Token (user-level) — Required for user-specific endpoints. Obtained by calling /auth or /auth/staff. JWT with 7-day expiry. Pass via Authorization: Bearer {token} header.

// Example: both headers on a protected request
X-API-Key: sp_a1b2c3d4e5f6...
Authorization: Bearer eyJhbGciOiJIUzI1NiJ9...
POST /api/{slug}/auth Customer login (phone)

Authenticate a customer by phone number. Auto-registers if the number is new.

ParameterTypeDescription
phone requiredstringPhone number, e.g. "0179064733"
// Request
POST /api/bosscafe/auth
Content-Type: application/json

{ "phone": "0179064733" }

// Response
{
  "error": false,
  "message": "Login successful",
  "token": "eyJhbGciOiJIUzI1NiJ9...",
  "user": {
    "id": 3,
    "name": "0179064733",
    "phone": "0179064733",
    "role": "customer"
  }
}
POST /api/{slug}/auth/staff Staff/Admin login (email+password)
ParameterTypeDescription
email requiredstringStaff email
password requiredstringStaff password
// Request
POST /api/bosscafe/auth/staff
Content-Type: application/json

{ "email": "[email protected]", "password": "staff123" }

// Response — same format as customer auth

Public

GET /api/{slug}/shop Get shop info

No authentication required.

// Response
{
  "error": false,
  "shop": {
    "id": 1,
    "name": "BossCafe",
    "slug": "bosscafe",
    "logo": null,
    "brand_color": "#FF6B9D",
    "reward_threshold": 10
  }
}

Customer Auth Required

GET /api/{slug}/customer/dashboard Stamp count & progress
// Headers
Authorization: Bearer {token}

// Response
{
  "stamps": 7,
  "threshold": 10,
  "progress": 70.0,
  "rewards_available": 0,
  "stamps_to_next_reward": 3
}
GET /api/{slug}/customer/history Stamp & reward history
Query ParamTypeDescription
limitintMax results (default 20, max 100)
offsetintPagination offset (default 0)
// Response
{
  "history": [
    { "type": "stamp", "value": 1, "notes": "Coffee", "created_at": "2026-04-01 14:30:00" },
    { "type": "reward", "value": 10, "notes": "Free item", "created_at": "2026-03-20 11:00:00" }
  ]
}

Staff Auth Required

GET /api/{slug}/staff/search?q={query} Search customers
Query ParamTypeDescription
q requiredstringSearch by phone or name (min 2 chars)
// Response
{
  "results": [
    {
      "id": 3,
      "name": "0179064733",
      "phone": "0179064733",
      "stamps": 7,
      "can_stamp": true,
      "can_redeem": false
    }
  ]
}
POST /api/{slug}/staff/stamp Issue a stamp
ParameterTypeDescription
customer_id requiredintCustomer user ID
notesstringPurchase note (optional)
// Request
POST /api/bosscafe/staff/stamp
Authorization: Bearer {token}
Content-Type: application/json

{ "customer_id": 3, "notes": "Double espresso" }

// Response
{
  "stamp_id": 15,
  "new_stamp_count": 8,
  "can_redeem": false
}

Returns 429 if cooldown is active (5 min between stamps to same customer).

POST /api/{slug}/staff/redeem Redeem a reward
ParameterTypeDescription
customer_id requiredintCustomer user ID
reward_descriptionstringReward name (default: "Free item")
// Response
{
  "redemption_id": 5,
  "new_stamp_count": 0,
  "reward": "Free coffee"
}
GET /api/{slug}/staff/recent Recent stamps by this staff
Query ParamTypeDescription
limitintMax results (default 10, max 50)

Admin Auth Required

GET /api/{slug}/admin/stats Dashboard statistics
// Response
{
  "stats": {
    "total_customers": 150,
    "total_stamps": 843,
    "total_redemptions": 27,
    "total_staff": 3
  }
}
GET /api/{slug}/admin/customers List all customers
Query ParamTypeDescription
limitintMax results (default 50, max 200)
offsetintPagination offset
GET /api/{slug}/admin/staff List staff members

GET to list, POST to add a new staff member.

POST /api/{slug}/admin/staff Add staff member
ParameterTypeDescription
name requiredstringStaff name
email requiredstringStaff email
password requiredstringPassword (min 6 chars)
GET /api/{slug}/admin/logs Audit logs
Query ParamTypeDescription
limitintMax results (default 50, max 200)
offsetintPagination offset

Error Handling

All errors return a consistent JSON format:

{
  "error": true,
  "message": "Description of what went wrong"
}
StatusMeaning
200Success
400Bad request — missing or invalid parameters
401Unauthorized — missing or invalid token
403Forbidden — insufficient role or shop mismatch
404Not found — shop, customer, or endpoint not found
405Method not allowed — wrong HTTP method
429Rate limited — stamp cooldown active