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
| Role | Level | Capabilities |
|---|---|---|
| SuperAdmin | 5 | Full system access |
| Admin | 4 | Tenant-wide administration |
| Manager | 3 | Location management, overrides |
| Cashier | 2 | POS operations |
| Viewer | 1 | Read-only access |
Common Response Codes
| Code | Meaning |
|---|---|
| 200 | Success |
| 201 | Created |
| 204 | No Content |
| 400 | Bad Request |
| 401 | Unauthorized |
| 403 | Forbidden |
| 404 | Not Found |
| 409 | Conflict |
| 422 | Validation Error |
| 429 | Rate Limited |
| 500 | Server 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:
| Parameter | Type | Description |
|---|---|---|
| status | string | Filter by status (active, suspended, trial) |
| page | int | Page number (default: 1) |
| limit | int | Items 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:
| Parameter | Type | Description |
|---|---|---|
| status | string | Filter by status (active, inactive) |
| type | string | Filter 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:
| Parameter | Type | Description |
|---|---|---|
| role | string | Filter by role |
| locationId | string | Filter by location |
| status | string | active, 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:
| Parameter | Type | Description |
|---|---|---|
| startDate | date | Start of date range |
| endDate | date | End 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:
| Parameter | Type | Description |
|---|---|---|
| search | string | Search by name, SKU, barcode |
| categoryId | string | Filter by category |
| vendorId | string | Filter by vendor |
| status | string | active, discontinued, draft |
| page | int | Page number |
| limit | int | Items 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:
| Parameter | Type | Description |
|---|---|---|
| locationId | string | Filter by location |
| variantId | string | Filter by variant |
| sku | string | Filter by SKU |
| belowReorder | boolean | Show 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:
| Parameter | Type | Description |
|---|---|---|
| locationId | string | Filter by location |
| type | string | cycle_count, shrinkage, damage, correction |
| startDate | date | Start date |
| endDate | date | End 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:
| Parameter | Type | Description |
|---|---|---|
| locationId | string | Filter by location |
| registerId | string | Filter by register |
| startDate | datetime | Start of date range |
| endDate | datetime | End of date range |
| customerId | string | Filter by customer |
| status | string | completed, voided, refunded |
| minAmount | decimal | Minimum total |
| maxAmount | decimal | Maximum 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:
| Parameter | Type | Description |
|---|---|---|
| search | string | Search by name, email, phone |
| tier | string | Filter by loyalty tier |
| tag | string | Filter by tag |
| hasEmail | boolean | Has email address |
| page | int | Page number |
| limit | int | Items 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:
| Parameter | Type | Description |
|---|---|---|
| since | datetime | Last sync timestamp |
| types | string[] | 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:
| Parameter | Type | Description |
|---|---|---|
| date | date | Report date |
| locationId | string | Filter 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:
| Parameter | Type | Description |
|---|---|---|
| locationId | string | Filter by location |
| asOfDate | date | Valuation 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
| Event | Description |
|---|---|
| order.completed | Sale completed |
| order.voided | Sale voided |
| order.refunded | Return processed |
| inventory.low_stock | Below reorder point |
| inventory.adjusted | Manual adjustment |
| customer.created | New customer |
| customer.updated | Customer modified |
| sync.conflict | Offline 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 Type | Rate Limit |
|---|---|
| Authentication | 10 requests/minute |
| Read operations | 1000 requests/minute |
| Write operations | 100 requests/minute |
| Bulk operations | 10 requests/minute |
| Webhooks | 1000 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.