Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Appendix A: Complete API Reference

Version: 1.0.0 Last Updated: December 29, 2025 Base URL: https://api.pos-platform.com/api/v1


Overview

This appendix contains the complete API reference for the POS Platform, organized by domain. All endpoints require authentication unless marked as public.

Authentication

All authenticated requests must include a Bearer token:

Authorization: Bearer <jwt_token>

Role Hierarchy

RoleLevelCapabilities
SuperAdmin5Full system access
Admin4Tenant-wide administration
Manager3Location management, overrides
Cashier2POS operations
Viewer1Read-only access

Common Response Codes

CodeMeaning
200Success
201Created
204No Content
400Bad Request
401Unauthorized
403Forbidden
404Not Found
409Conflict
422Validation Error
429Rate Limited
500Server Error

Domain 1: Authentication

POST /auth/login

Description: Authenticate user and receive JWT token

Authentication: None (public)

Request Body:

{
  "email": "user@example.com",
  "password": "securePassword123",
  "tenantId": "tenant_nexus"
}

Response: 200 OK

{
  "token": "eyJhbGciOiJIUzI1NiIs...",
  "refreshToken": "dGhpcyBpcyBhIHJlZnJl...",
  "expiresAt": "2025-12-29T16:00:00Z",
  "user": {
    "id": "usr_abc123",
    "email": "user@example.com",
    "firstName": "John",
    "lastName": "Doe",
    "role": "cashier",
    "locationId": "loc_gm",
    "permissions": ["sales.create", "sales.void", "inventory.view"]
  }
}

Errors: 401 Invalid credentials, 423 Account locked


POST /auth/refresh

Description: Refresh an expired access token

Authentication: None (requires valid refresh token)

Request Body:

{
  "refreshToken": "dGhpcyBpcyBhIHJlZnJl..."
}

Response: 200 OK

{
  "token": "eyJhbGciOiJIUzI1NiIs...",
  "refreshToken": "bmV3IHJlZnJlc2ggdG9r...",
  "expiresAt": "2025-12-29T18:00:00Z"
}

Errors: 401 Invalid or expired refresh token


POST /auth/logout

Description: Invalidate current session

Authentication: Bearer token (Any role)

Request Body: None

Response: 204 No Content


POST /auth/password/change

Description: Change current user’s password

Authentication: Bearer token (Any role)

Request Body:

{
  "currentPassword": "oldPassword123",
  "newPassword": "newSecurePassword456"
}

Response: 204 No Content

Errors: 400 Password requirements not met, 401 Current password incorrect


POST /auth/password/reset

Description: Request password reset email

Authentication: None (public)

Request Body:

{
  "email": "user@example.com",
  "tenantId": "tenant_nexus"
}

Response: 202 Accepted

{
  "message": "If the email exists, a reset link has been sent"
}

Domain 2: Tenants

GET /tenants

Description: List all tenants (SuperAdmin only)

Authentication: Bearer token (SuperAdmin)

Query Parameters:

ParameterTypeDescription
statusstringFilter by status (active, suspended, trial)
pageintPage number (default: 1)
limitintItems per page (default: 20, max: 100)

Response: 200 OK

{
  "data": [
    {
      "id": "tenant_nexus",
      "name": "Nexus Clothing",
      "subdomain": "nexus",
      "status": "active",
      "plan": "enterprise",
      "createdAt": "2025-01-01T00:00:00Z",
      "locationCount": 5,
      "userCount": 25
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 20,
    "total": 45,
    "pages": 3
  }
}

POST /tenants

Description: Create a new tenant

Authentication: Bearer token (SuperAdmin)

Request Body:

{
  "name": "New Retail Store",
  "subdomain": "newretail",
  "plan": "professional",
  "adminUser": {
    "email": "admin@newretail.com",
    "firstName": "Jane",
    "lastName": "Smith",
    "password": "initialPassword123"
  },
  "settings": {
    "timezone": "America/New_York",
    "currency": "USD",
    "taxRate": 6.0
  }
}

Response: 201 Created

{
  "id": "tenant_newretail",
  "name": "New Retail Store",
  "subdomain": "newretail",
  "status": "trial",
  "trialEndsAt": "2025-01-28T00:00:00Z",
  "adminUserId": "usr_admin123"
}

Errors: 409 Subdomain already exists, 422 Validation error


GET /tenants/

Description: Get tenant details

Authentication: Bearer token (SuperAdmin or tenant Admin)

Response: 200 OK

{
  "id": "tenant_nexus",
  "name": "Nexus Clothing",
  "subdomain": "nexus",
  "status": "active",
  "plan": "enterprise",
  "settings": {
    "timezone": "America/New_York",
    "currency": "USD",
    "taxRate": 6.0,
    "loyaltyEnabled": true,
    "rfidEnabled": true
  },
  "usage": {
    "locations": 5,
    "users": 25,
    "monthlyTransactions": 12500,
    "storageUsedMB": 2048
  },
  "createdAt": "2025-01-01T00:00:00Z",
  "updatedAt": "2025-12-29T10:00:00Z"
}

PATCH /tenants/

Description: Update tenant settings

Authentication: Bearer token (SuperAdmin or tenant Admin)

Request Body:

{
  "name": "Nexus Clothing Inc.",
  "settings": {
    "taxRate": 6.5
  }
}

Response: 200 OK (returns updated tenant)


POST /tenants/{tenantId}/suspend

Description: Suspend a tenant account

Authentication: Bearer token (SuperAdmin)

Request Body:

{
  "reason": "Payment overdue",
  "suspendAt": "2025-12-30T00:00:00Z"
}

Response: 200 OK


POST /tenants/{tenantId}/activate

Description: Reactivate a suspended tenant

Authentication: Bearer token (SuperAdmin)

Response: 200 OK


Domain 3: Locations

GET /locations

Description: List all locations for current tenant

Authentication: Bearer token (Viewer+)

Query Parameters:

ParameterTypeDescription
statusstringFilter by status (active, inactive)
typestringFilter by type (store, warehouse, popup)

Response: 200 OK

{
  "data": [
    {
      "id": "loc_gm",
      "code": "GM",
      "name": "Greenbrier Mall",
      "type": "store",
      "status": "active",
      "address": {
        "street": "1401 Greenbrier Pkwy",
        "city": "Chesapeake",
        "state": "VA",
        "zip": "23320"
      },
      "phone": "757-555-0100",
      "timezone": "America/New_York",
      "shopifyLocationId": "19718045760"
    }
  ]
}

POST /locations

Description: Create a new location

Authentication: Bearer token (Admin)

Request Body:

{
  "code": "NL",
  "name": "New Location",
  "type": "store",
  "address": {
    "street": "123 Main St",
    "city": "Norfolk",
    "state": "VA",
    "zip": "23510"
  },
  "phone": "757-555-0200",
  "timezone": "America/New_York",
  "settings": {
    "fulfillmentPriority": 5,
    "canShipOnline": true
  }
}

Response: 201 Created


GET /locations/

Description: Get location details

Authentication: Bearer token (Viewer+)

Response: 200 OK

{
  "id": "loc_gm",
  "code": "GM",
  "name": "Greenbrier Mall",
  "type": "store",
  "status": "active",
  "address": {
    "street": "1401 Greenbrier Pkwy",
    "city": "Chesapeake",
    "state": "VA",
    "zip": "23320"
  },
  "phone": "757-555-0100",
  "timezone": "America/New_York",
  "settings": {
    "fulfillmentPriority": 1,
    "canShipOnline": true,
    "showInventoryOnWeb": true
  },
  "registers": [
    {
      "id": "reg_01",
      "name": "Register 1",
      "status": "active"
    }
  ],
  "operatingHours": {
    "monday": { "open": "10:00", "close": "21:00" },
    "tuesday": { "open": "10:00", "close": "21:00" },
    "wednesday": { "open": "10:00", "close": "21:00" },
    "thursday": { "open": "10:00", "close": "21:00" },
    "friday": { "open": "10:00", "close": "21:00" },
    "saturday": { "open": "10:00", "close": "21:00" },
    "sunday": { "open": "12:00", "close": "18:00" }
  }
}

PATCH /locations/

Description: Update location details

Authentication: Bearer token (Admin)

Request Body:

{
  "name": "Greenbrier Mall Store",
  "settings": {
    "fulfillmentPriority": 2
  }
}

Response: 200 OK


Domain 4: Users & Employees

GET /users

Description: List all users for current tenant

Authentication: Bearer token (Admin)

Query Parameters:

ParameterTypeDescription
rolestringFilter by role
locationIdstringFilter by location
statusstringactive, inactive, locked

Response: 200 OK

{
  "data": [
    {
      "id": "usr_abc123",
      "email": "john.doe@example.com",
      "firstName": "John",
      "lastName": "Doe",
      "role": "cashier",
      "locationId": "loc_gm",
      "status": "active",
      "lastLoginAt": "2025-12-29T08:00:00Z"
    }
  ]
}

POST /users

Description: Create a new user

Authentication: Bearer token (Admin)

Request Body:

{
  "email": "newuser@example.com",
  "firstName": "Jane",
  "lastName": "Smith",
  "role": "cashier",
  "locationId": "loc_gm",
  "pin": "1234",
  "permissions": ["sales.create", "sales.void"]
}

Response: 201 Created


GET /users/

Description: Get user details

Authentication: Bearer token (Admin or self)

Response: 200 OK


PATCH /users/

Description: Update user details

Authentication: Bearer token (Admin)

Request Body:

{
  "role": "manager",
  "permissions": ["sales.create", "sales.void", "inventory.adjust"]
}

Response: 200 OK


DELETE /users/

Description: Deactivate user (soft delete)

Authentication: Bearer token (Admin)

Response: 204 No Content


POST /users/{userId}/reset-pin

Description: Reset user’s POS PIN

Authentication: Bearer token (Admin)

Request Body:

{
  "newPin": "5678"
}

Response: 204 No Content


GET /employees/{employeeId}/timeclock

Description: Get employee time clock entries

Authentication: Bearer token (Manager+)

Query Parameters:

ParameterTypeDescription
startDatedateStart of date range
endDatedateEnd of date range

Response: 200 OK

{
  "data": [
    {
      "id": "tc_001",
      "employeeId": "usr_abc123",
      "clockIn": "2025-12-29T08:00:00Z",
      "clockOut": "2025-12-29T17:00:00Z",
      "hoursWorked": 9.0,
      "breaks": [
        {
          "start": "2025-12-29T12:00:00Z",
          "end": "2025-12-29T12:30:00Z",
          "type": "lunch"
        }
      ]
    }
  ]
}

POST /employees/{employeeId}/clock-in

Description: Clock in employee

Authentication: Bearer token (Cashier+ or self)

Request Body:

{
  "locationId": "loc_gm",
  "registerId": "reg_01"
}

Response: 201 Created

{
  "id": "tc_002",
  "employeeId": "usr_abc123",
  "clockIn": "2025-12-29T08:00:00Z",
  "locationId": "loc_gm"
}

POST /employees/{employeeId}/clock-out

Description: Clock out employee

Authentication: Bearer token (Cashier+ or self)

Response: 200 OK

{
  "id": "tc_002",
  "clockOut": "2025-12-29T17:00:00Z",
  "hoursWorked": 9.0
}

Domain 5: Products & Catalog

GET /products

Description: List products in catalog

Authentication: Bearer token (Viewer+)

Query Parameters:

ParameterTypeDescription
searchstringSearch by name, SKU, barcode
categoryIdstringFilter by category
vendorIdstringFilter by vendor
statusstringactive, discontinued, draft
pageintPage number
limitintItems per page

Response: 200 OK

{
  "data": [
    {
      "id": "prod_abc123",
      "name": "Classic V-Neck Tee",
      "sku": "NXP0323",
      "barcode": "657381512532",
      "categoryId": "cat_shirts",
      "vendorId": "vendor_abc",
      "status": "active",
      "basePrice": 29.99,
      "cost": 12.50,
      "variants": [
        {
          "id": "var_001",
          "sku": "NXP0323-S-BLK",
          "options": { "size": "S", "color": "Black" },
          "price": 29.99,
          "barcode": "657381512533"
        }
      ],
      "images": [
        {
          "url": "https://cdn.example.com/images/nxp0323.jpg",
          "alt": "Classic V-Neck Tee",
          "position": 1
        }
      ]
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 20,
    "total": 5000
  }
}

POST /products

Description: Create a new product

Authentication: Bearer token (Admin)

Request Body:

{
  "name": "New Product",
  "sku": "NXP9999",
  "categoryId": "cat_shirts",
  "vendorId": "vendor_abc",
  "basePrice": 39.99,
  "cost": 15.00,
  "description": "Product description here",
  "variants": [
    {
      "sku": "NXP9999-S-BLK",
      "options": { "size": "S", "color": "Black" },
      "price": 39.99,
      "barcode": "657381599999"
    }
  ]
}

Response: 201 Created


GET /products/

Description: Get product details

Authentication: Bearer token (Viewer+)

Response: 200 OK


PATCH /products/

Description: Update product

Authentication: Bearer token (Admin)

Request Body:

{
  "basePrice": 34.99,
  "status": "active"
}

Response: 200 OK


DELETE /products/

Description: Discontinue product (soft delete)

Authentication: Bearer token (Admin)

Response: 204 No Content


GET /products/{productId}/variants

Description: List all variants for a product

Authentication: Bearer token (Viewer+)

Response: 200 OK


POST /products/{productId}/variants

Description: Add variant to product

Authentication: Bearer token (Admin)

Request Body:

{
  "sku": "NXP0323-XL-BLK",
  "options": { "size": "XL", "color": "Black" },
  "price": 29.99,
  "barcode": "657381512599"
}

Response: 201 Created


GET /categories

Description: List product categories

Authentication: Bearer token (Viewer+)

Response: 200 OK

{
  "data": [
    {
      "id": "cat_shirts",
      "name": "Shirts",
      "parentId": null,
      "children": [
        {
          "id": "cat_tees",
          "name": "T-Shirts",
          "parentId": "cat_shirts"
        },
        {
          "id": "cat_polos",
          "name": "Polos",
          "parentId": "cat_shirts"
        }
      ]
    }
  ]
}

GET /vendors

Description: List vendors

Authentication: Bearer token (Viewer+)

Response: 200 OK


Domain 6: Inventory

GET /inventory

Description: Get inventory levels across locations

Authentication: Bearer token (Viewer+)

Query Parameters:

ParameterTypeDescription
locationIdstringFilter by location
variantIdstringFilter by variant
skustringFilter by SKU
belowReorderbooleanShow only items below reorder point

Response: 200 OK

{
  "data": [
    {
      "variantId": "var_001",
      "sku": "NXP0323-S-BLK",
      "productName": "Classic V-Neck Tee - S Black",
      "levels": [
        {
          "locationId": "loc_gm",
          "locationName": "Greenbrier Mall",
          "onHand": 15,
          "available": 13,
          "reserved": 2,
          "reorderPoint": 5,
          "reorderQty": 20
        },
        {
          "locationId": "loc_hm",
          "locationName": "Peninsula Town Center",
          "onHand": 8,
          "available": 8,
          "reserved": 0,
          "reorderPoint": 5,
          "reorderQty": 20
        }
      ],
      "totalOnHand": 23,
      "totalAvailable": 21
    }
  ]
}

GET /inventory/locations/

Description: Get inventory for specific location

Authentication: Bearer token (Viewer+)

Response: 200 OK


POST /inventory/adjustments

Description: Create inventory adjustment

Authentication: Bearer token (Manager+)

Request Body:

{
  "locationId": "loc_gm",
  "adjustmentType": "cycle_count",
  "items": [
    {
      "variantId": "var_001",
      "systemQty": 15,
      "countedQty": 13,
      "reason": "shrinkage"
    }
  ],
  "notes": "Quarterly cycle count - Section A"
}

Response: 201 Created

{
  "id": "adj_001",
  "status": "completed",
  "items": [
    {
      "variantId": "var_001",
      "variance": -2,
      "previousOnHand": 15,
      "newOnHand": 13,
      "costImpact": -25.00
    }
  ],
  "totalVariance": -2,
  "totalCostImpact": -25.00
}

GET /inventory/adjustments

Description: List inventory adjustments

Authentication: Bearer token (Manager+)

Query Parameters:

ParameterTypeDescription
locationIdstringFilter by location
typestringcycle_count, shrinkage, damage, correction
startDatedateStart date
endDatedateEnd date

Response: 200 OK


POST /inventory/transfers

Description: Create inventory transfer request

Authentication: Bearer token (Manager+)

Request Body:

{
  "fromLocationId": "loc_hq",
  "toLocationId": "loc_gm",
  "priority": "normal",
  "reason": "low_stock",
  "items": [
    {
      "variantId": "var_001",
      "quantity": 10
    }
  ],
  "notes": "Restocking for weekend sale"
}

Response: 201 Created

{
  "id": "xfer_001",
  "status": "pending",
  "fromLocationId": "loc_hq",
  "toLocationId": "loc_gm",
  "items": [
    {
      "variantId": "var_001",
      "quantityRequested": 10
    }
  ],
  "expectedShipDate": "2025-12-30",
  "expectedArrivalDate": "2025-12-31"
}

GET /inventory/transfers/

Description: Get transfer details

Authentication: Bearer token (Viewer+)

Response: 200 OK


POST /inventory/transfers/{transferId}/ship

Description: Mark transfer as shipped

Authentication: Bearer token (Manager+)

Request Body:

{
  "items": [
    {
      "variantId": "var_001",
      "quantityShipped": 10
    }
  ],
  "trackingNumber": "1Z999AA10123456784",
  "carrier": "UPS"
}

Response: 200 OK


POST /inventory/transfers/{transferId}/receive

Description: Receive transfer at destination

Authentication: Bearer token (Manager+)

Request Body:

{
  "items": [
    {
      "variantId": "var_001",
      "quantityReceived": 10,
      "quantityDamaged": 0
    }
  ],
  "notes": null
}

Response: 200 OK


Domain 7: Sales & Orders

POST /sales

Description: Create a new sale transaction

Authentication: Bearer token (Cashier+)

Request Body:

{
  "locationId": "loc_gm",
  "registerId": "reg_01",
  "customerId": "cust_john_doe",
  "lineItems": [
    {
      "variantId": "var_001",
      "quantity": 2,
      "unitPrice": 29.99,
      "discountAmount": 0,
      "discountReason": null
    }
  ],
  "discounts": [
    {
      "type": "percentage",
      "value": 10,
      "code": "SAVE10",
      "appliesTo": "order"
    }
  ],
  "payments": [
    {
      "method": "card",
      "amount": 53.98,
      "reference": "tok_visa_4242"
    }
  ]
}

Response: 201 Created

{
  "id": "ord_xyz789",
  "orderNumber": "ORD-2025-00001",
  "receiptNumber": "GM-2025-001234",
  "status": "completed",
  "lineItems": [
    {
      "id": "li_001",
      "variantId": "var_001",
      "sku": "NXP0323-S-BLK",
      "name": "Classic V-Neck Tee - S Black",
      "quantity": 2,
      "unitPrice": 29.99,
      "lineTotal": 59.98
    }
  ],
  "subtotal": 59.98,
  "discountTotal": 6.00,
  "taxAmount": 3.24,
  "total": 57.22,
  "payments": [
    {
      "id": "pay_001",
      "method": "card",
      "amount": 57.22,
      "status": "completed",
      "authCode": "AUTH123456",
      "lastFour": "4242"
    }
  ],
  "customerId": "cust_john_doe",
  "loyaltyPointsEarned": 57,
  "createdAt": "2025-12-29T14:30:00Z",
  "createdBy": "usr_cashier1"
}

Errors: 400 Bad Request, 422 Validation Error, 402 Payment Failed


GET /sales/

Description: Get sale details

Authentication: Bearer token (Cashier+)

Response: 200 OK


GET /sales

Description: List sales with filters

Authentication: Bearer token (Cashier+)

Query Parameters:

ParameterTypeDescription
locationIdstringFilter by location
registerIdstringFilter by register
startDatedatetimeStart of date range
endDatedatetimeEnd of date range
customerIdstringFilter by customer
statusstringcompleted, voided, refunded
minAmountdecimalMinimum total
maxAmountdecimalMaximum total

Response: 200 OK


POST /sales/{saleId}/void

Description: Void a sale (requires manager)

Authentication: Bearer token (Manager+)

Request Body:

{
  "reason": "customer_changed_mind",
  "managerPin": "1234"
}

Response: 200 OK

{
  "id": "ord_xyz789",
  "status": "voided",
  "voidedAt": "2025-12-29T14:35:00Z",
  "voidedBy": "usr_manager1",
  "voidReason": "customer_changed_mind",
  "refundAmount": 57.22
}

POST /returns

Description: Process a return

Authentication: Bearer token (Cashier+)

Request Body:

{
  "originalOrderId": "ord_xyz789",
  "originalReceiptNumber": "GM-2025-001234",
  "locationId": "loc_gm",
  "items": [
    {
      "originalLineItemId": "li_001",
      "variantId": "var_001",
      "quantityReturned": 1,
      "reason": "wrong_size",
      "condition": "resaleable"
    }
  ],
  "refundMethod": "original_payment"
}

Response: 201 Created

{
  "id": "ret_abc123",
  "returnReceiptNumber": "RET-GM-2025-0001",
  "originalOrderId": "ord_xyz789",
  "items": [
    {
      "variantId": "var_001",
      "quantityReturned": 1,
      "refundAmount": 28.61,
      "inventoryRestocked": true
    }
  ],
  "totalRefund": 28.61,
  "refundTransactionId": "refund_001",
  "loyaltyPointsDeducted": 29,
  "createdAt": "2025-12-29T15:00:00Z"
}

GET /returns/

Description: Get return details

Authentication: Bearer token (Cashier+)

Response: 200 OK


Domain 8: Customers & Loyalty

GET /customers

Description: List customers

Authentication: Bearer token (Cashier+)

Query Parameters:

ParameterTypeDescription
searchstringSearch by name, email, phone
tierstringFilter by loyalty tier
tagstringFilter by tag
hasEmailbooleanHas email address
pageintPage number
limitintItems per page

Response: 200 OK

{
  "data": [
    {
      "id": "cust_john_doe",
      "customerNumber": "CUST-2025-00001",
      "firstName": "John",
      "lastName": "Doe",
      "email": "john.doe@example.com",
      "phone": "555-0100",
      "loyalty": {
        "tier": "gold",
        "pointsBalance": 1250,
        "lifetimeSpend": 2500.00
      },
      "tags": ["vip", "birthday_month"],
      "createdAt": "2025-01-15T00:00:00Z"
    }
  ]
}

POST /customers

Description: Create a new customer

Authentication: Bearer token (Cashier+)

Request Body:

{
  "firstName": "Jane",
  "lastName": "Smith",
  "email": "jane.smith@example.com",
  "phone": "555-0200",
  "address": {
    "street": "123 Main St",
    "city": "Chesapeake",
    "state": "VA",
    "zip": "23320"
  },
  "marketingOptIn": true,
  "smsOptIn": false,
  "enrollInLoyalty": true
}

Response: 201 Created


GET /customers/

Description: Get customer details

Authentication: Bearer token (Cashier+)

Response: 200 OK

{
  "id": "cust_john_doe",
  "customerNumber": "CUST-2025-00001",
  "firstName": "John",
  "lastName": "Doe",
  "email": "john.doe@example.com",
  "phone": "555-0100",
  "address": {
    "street": "456 Oak Ave",
    "city": "Virginia Beach",
    "state": "VA",
    "zip": "23451"
  },
  "loyalty": {
    "programId": "loyalty_standard",
    "tier": "gold",
    "pointsBalance": 1250,
    "pointsToNextTier": 750,
    "lifetimeSpend": 2500.00,
    "lifetimePoints": 3000
  },
  "preferences": {
    "marketingOptIn": true,
    "smsOptIn": true,
    "preferredContactMethod": "email"
  },
  "tags": ["vip", "birthday_month"],
  "purchaseHistory": {
    "totalOrders": 25,
    "totalSpend": 2500.00,
    "averageOrderValue": 100.00,
    "lastPurchase": "2025-12-28T14:00:00Z"
  },
  "createdAt": "2025-01-15T00:00:00Z",
  "updatedAt": "2025-12-28T14:00:00Z"
}

PATCH /customers/

Description: Update customer details

Authentication: Bearer token (Cashier+)

Request Body:

{
  "phone": "555-0300",
  "preferences": {
    "smsOptIn": true
  }
}

Response: 200 OK


GET /customers/{customerId}/orders

Description: Get customer’s order history

Authentication: Bearer token (Cashier+)

Response: 200 OK


POST /customers/{customerId}/loyalty/redeem

Description: Redeem loyalty points

Authentication: Bearer token (Cashier+)

Request Body:

{
  "points": 500,
  "orderId": "ord_xyz790"
}

Response: 200 OK

{
  "pointsRedeemed": 500,
  "discountAmount": 5.00,
  "previousBalance": 1250,
  "newBalance": 750
}

POST /customers/merge

Description: Merge duplicate customer records

Authentication: Bearer token (Admin)

Request Body:

{
  "survivingCustomerId": "cust_john_doe",
  "mergeCustomerIds": ["cust_john_d", "cust_jdoe"],
  "conflictResolutions": {
    "email": "cust_john_doe"
  }
}

Response: 200 OK


Domain 9: Payments

POST /payments/process

Description: Process a payment

Authentication: Bearer token (Cashier+)

Request Body:

{
  "orderId": "ord_xyz789",
  "method": "card",
  "amount": 57.22,
  "token": "tok_visa_4242",
  "terminalId": "term_verifone_01"
}

Response: 200 OK

{
  "id": "pay_001",
  "status": "approved",
  "amount": 57.22,
  "authorizationCode": "AUTH123456",
  "transactionId": "txn_gateway_abc",
  "cardBrand": "visa",
  "lastFour": "4242",
  "entryMethod": "chip",
  "batchId": "batch_2025-12-29"
}

Errors: 402 Payment Declined


POST /payments/refund

Description: Process a refund

Authentication: Bearer token (Manager+)

Request Body:

{
  "originalPaymentId": "pay_001",
  "amount": 28.61,
  "reason": "return"
}

Response: 200 OK


GET /payments/batch/

Description: Get payment batch details

Authentication: Bearer token (Manager+)

Response: 200 OK


POST /payments/batch/{batchId}/settle

Description: Settle payment batch

Authentication: Bearer token (Manager+)

Response: 200 OK


Domain 10: Gift Cards

POST /giftcards

Description: Create/sell a gift card

Authentication: Bearer token (Cashier+)

Request Body:

{
  "amount": 50.00,
  "purchasedBy": "cust_john_doe",
  "recipientEmail": "jane@example.com",
  "recipientName": "Jane",
  "message": "Happy Birthday!",
  "type": "digital"
}

Response: 201 Created

{
  "id": "gc_001",
  "cardNumber": "6012XXXXXXXXXXXX1234",
  "balance": 50.00,
  "status": "active",
  "expiresAt": null
}

GET /giftcards/{cardNumber}/balance

Description: Check gift card balance

Authentication: Bearer token (Cashier+)

Response: 200 OK

{
  "cardNumber": "6012XXXXXXXXXXXX1234",
  "balance": 50.00,
  "status": "active",
  "expiresAt": null
}

POST /giftcards/{cardNumber}/redeem

Description: Redeem gift card for payment

Authentication: Bearer token (Cashier+)

Request Body:

{
  "orderId": "ord_xyz790",
  "amount": 35.00
}

Response: 200 OK


Domain 11: Cash Management

POST /shifts/open

Description: Open a new shift

Authentication: Bearer token (Manager+)

Request Body:

{
  "registerId": "reg_01",
  "openingFloat": 267.50,
  "floatBreakdown": {
    "bills_20": 5,
    "bills_10": 5,
    "bills_5": 10,
    "bills_1": 50,
    "quarters": 40,
    "dimes": 50,
    "nickels": 40,
    "pennies": 50
  }
}

Response: 201 Created

{
  "id": "shift_001",
  "registerId": "reg_01",
  "openedAt": "2025-12-29T08:00:00Z",
  "openedBy": "usr_manager1",
  "openingFloat": 267.50,
  "status": "active"
}

POST /shifts/{shiftId}/close

Description: Close shift and reconcile

Authentication: Bearer token (Manager+)

Request Body:

{
  "closingCount": {
    "bills_100": 2,
    "bills_50": 3,
    "bills_20": 15,
    "bills_10": 10,
    "bills_5": 20,
    "bills_1": 75,
    "quarters": 80,
    "dimes": 100,
    "nickels": 80,
    "pennies": 100
  }
}

Response: 200 OK

{
  "id": "shift_001",
  "closedAt": "2025-12-29T17:00:00Z",
  "expectedCash": 725.50,
  "actualCash": 723.00,
  "variance": -2.50,
  "varianceSeverity": "notable",
  "summary": {
    "cashSales": 458.00,
    "cardSales": 1250.00,
    "returns": 45.00,
    "paidOuts": 25.00,
    "tillDrops": 200.00
  }
}

POST /shifts/{shiftId}/till-drop

Description: Record till drop to safe

Authentication: Bearer token (Cashier+)

Request Body:

{
  "amount": 200.00,
  "breakdown": {
    "bills_100": 2
  }
}

Response: 201 Created


POST /shifts/{shiftId}/paid-out

Description: Record paid out (petty cash)

Authentication: Bearer token (Manager+)

Request Body:

{
  "amount": 25.00,
  "category": "office_supplies",
  "description": "Printer paper",
  "receiptAttached": true
}

Response: 201 Created


GET /shifts/

Description: Get shift details

Authentication: Bearer token (Manager+)

Response: 200 OK


Domain 12: RFID (Optional Module)

POST /rfid/tags/print

Description: Queue RFID tags for printing

Authentication: Bearer token (Manager+)

Request Body:

{
  "printerId": "printer_zebra_01",
  "items": [
    {
      "variantId": "var_001",
      "quantity": 50
    }
  ],
  "templateId": "tmpl_standard"
}

Response: 202 Accepted

{
  "jobId": "print_job_001",
  "status": "queued",
  "totalTags": 50
}

GET /rfid/tags/print/

Description: Get print job status

Authentication: Bearer token (Manager+)

Response: 200 OK


POST /rfid/scans/sessions

Description: Start RFID scan session

Authentication: Bearer token (Cashier+)

Request Body:

{
  "locationId": "loc_gm",
  "zoneId": "zone_sales_floor",
  "sessionType": "cycle_count"
}

Response: 201 Created

{
  "sessionId": "scan_001",
  "status": "active",
  "startedAt": "2025-12-29T10:00:00Z"
}

POST /rfid/scans/sessions/{sessionId}/tags

Description: Submit scanned tags (batch)

Authentication: Bearer token (Cashier+)

Request Body:

{
  "tags": [
    {
      "epc": "30340123456789012345678901",
      "rssi": -45,
      "timestamp": "2025-12-29T10:05:00Z"
    }
  ]
}

Response: 200 OK


POST /rfid/scans/sessions/{sessionId}/complete

Description: Complete scan session

Authentication: Bearer token (Cashier+)

Response: 200 OK

{
  "sessionId": "scan_001",
  "summary": {
    "totalTagsScanned": 145,
    "uniqueSkus": 142,
    "expected": 150,
    "variance": 8,
    "variancePercentage": 5.33
  },
  "completedAt": "2025-12-29T10:30:00Z"
}

Domain 13: Sync & Offline

POST /sync/push

Description: Push offline changes to server

Authentication: Bearer token (Cashier+)

Request Body:

{
  "deviceId": "dev_pos_01",
  "lastSyncTimestamp": "2025-12-29T10:00:00Z",
  "events": [
    {
      "localSequence": 1,
      "eventType": "OrderCompleted",
      "timestamp": "2025-12-29T10:30:00Z",
      "payload": { }
    }
  ],
  "inventoryDeltas": [
    {
      "variantId": "var_001",
      "locationId": "loc_gm",
      "lastSyncQty": 15,
      "delta": -2
    }
  ]
}

Response: 200 OK

{
  "success": true,
  "syncedEvents": 5,
  "conflicts": [
    {
      "type": "inventory",
      "variantId": "var_001",
      "resolution": "delta_merged",
      "serverValue": 12,
      "localDelta": -2,
      "resolvedValue": 10
    }
  ],
  "serverTimestamp": "2025-12-29T12:00:00Z"
}

GET /sync/pull

Description: Pull updates from server

Authentication: Bearer token (Cashier+)

Query Parameters:

ParameterTypeDescription
sincedatetimeLast sync timestamp
typesstring[]Event types to pull

Response: 200 OK


GET /sync/status

Description: Get sync status for device

Authentication: Bearer token (Cashier+)

Response: 200 OK

{
  "deviceId": "dev_pos_01",
  "lastSync": "2025-12-29T12:00:00Z",
  "pendingPush": 0,
  "pendingPull": 15,
  "status": "synced"
}

Domain 14: Reports

GET /reports/sales/daily

Description: Daily sales summary

Authentication: Bearer token (Manager+)

Query Parameters:

ParameterTypeDescription
datedateReport date
locationIdstringFilter by location

Response: 200 OK

{
  "date": "2025-12-29",
  "summary": {
    "grossSales": 5250.00,
    "discounts": 250.00,
    "returns": 150.00,
    "netSales": 4850.00,
    "tax": 291.00,
    "transactionCount": 85,
    "averageTicket": 57.06,
    "unitsPerTransaction": 2.3
  },
  "byPaymentMethod": {
    "cash": 1250.00,
    "card": 3500.00,
    "giftCard": 100.00
  },
  "byCategory": [
    { "category": "Shirts", "sales": 2500.00, "units": 75 },
    { "category": "Pants", "sales": 1500.00, "units": 30 }
  ],
  "topItems": [
    { "sku": "NXP0323", "name": "Classic V-Neck", "units": 25, "sales": 749.75 }
  ]
}

GET /reports/inventory/valuation

Description: Inventory valuation report

Authentication: Bearer token (Manager+)

Query Parameters:

ParameterTypeDescription
locationIdstringFilter by location
asOfDatedateValuation date

Response: 200 OK


GET /reports/employees/timeclock

Description: Employee time clock report

Authentication: Bearer token (Manager+)

Response: 200 OK


GET /reports/customers/loyalty

Description: Loyalty program report

Authentication: Bearer token (Manager+)

Response: 200 OK


Webhooks

Configuring Webhooks

Description: Register webhook endpoints

Authentication: Bearer token (Admin)

Request Body:

{
  "url": "https://your-server.com/webhooks",
  "events": [
    "order.completed",
    "order.refunded",
    "inventory.low_stock",
    "customer.created"
  ],
  "secret": "whsec_your_secret_key"
}

Webhook Events

EventDescription
order.completedSale completed
order.voidedSale voided
order.refundedReturn processed
inventory.low_stockBelow reorder point
inventory.adjustedManual adjustment
customer.createdNew customer
customer.updatedCustomer modified
sync.conflictOffline conflict detected

Webhook Payload Format

{
  "id": "evt_webhook_001",
  "type": "order.completed",
  "timestamp": "2025-12-29T14:30:00Z",
  "tenantId": "tenant_nexus",
  "data": {
    "orderId": "ord_xyz789",
    "orderNumber": "ORD-2025-00001",
    "total": 57.22
  }
}

Rate Limits

Endpoint TypeRate Limit
Authentication10 requests/minute
Read operations1000 requests/minute
Write operations100 requests/minute
Bulk operations10 requests/minute
Webhooks1000 events/minute

API Versioning

The API uses URL versioning:

  • Current version: v1
  • URL format: /api/v1/{resource}
  • Deprecated versions are supported for 12 months
  • Version header: X-API-Version: 2025-12-29

This API reference covers 75+ endpoints across 14 domains. For additional details, see the OpenAPI specification at /api/v1/docs.