Appendix A: Complete API Reference
Version: 4.0.0
Last Updated: February 25, 2026
Base URL: https://api.pos-platform.com/api/v1
A.1 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 |
A.2 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"
}
A.3 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
A.4 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
A.5 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
}
A.6 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
A.7 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
A.8 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
A.9 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
A.10 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
A.11 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
A.12 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
A.13 Domain 12: RFID (Optional Module — Counting Only)
Scope: RFID endpoints support inventory counting operations only. Receiving is handled by the barcode Scanner in the POS Client. See BRD Section 5.16.6 for the Scanner vs RFID distinction.
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: Create a new RFID counting session
Authentication: Bearer token (Cashier+)
Request Body:
{
"locationId": "loc_gm",
"sectionId": "section_a_mens_tops",
"sessionType": "cycle_count",
"notes": "Pre-inventory count for Q4 audit"
}
Session Types: full_inventory, cycle_count, spot_check, find_item
Response: 201 Created
{
"sessionId": "scan_001",
"status": "active",
"startedAt": "2025-12-29T10:00:00Z",
"expectedCount": 505,
"sectionsAvailable": ["section_a_mens_tops", "section_b_mens_bottoms"]
}
POST /rfid/scans/sessions/{sessionId}/join
Description: Join an existing session as an additional operator (multi-operator counting)
Authentication: Bearer token (Cashier+)
Request Body:
{
"operatorId": "user_002",
"deviceId": "device_mc3390r_02",
"assignedSection": "section_b_mens_bottoms"
}
Response: 200 OK
{
"sessionId": "scan_001",
"operatorCount": 3,
"yourSection": "section_b_mens_bottoms",
"sessionStartedAt": "2025-12-29T10:00:00Z"
}
Business Rules:
- Maximum 10 operators per session
- One active session per operator
- Section assignment is advisory (not hardware-enforced)
POST /rfid/scans/sessions/{sessionId}/chunks
Description: Upload scan events in chunks (≤5,000 events per chunk). Idempotent — duplicate (session_id, epc) pairs are deduplicated server-side using UPSERT with highest RSSI kept.
Authentication: Bearer token (Cashier+)
Request Body:
{
"chunkIndex": 0,
"totalChunks": 10,
"operatorId": "user_001",
"deviceId": "device_mc3390r_01",
"events": [
{
"epc": "E28011606000020752345678",
"rssi": -45,
"readCount": 3,
"firstSeenAt": "2025-12-29T10:05:00Z",
"lastSeenAt": "2025-12-29T10:05:12Z"
}
]
}
Response: 200 OK
{
"eventsAccepted": 4892,
"eventsDeduplicated": 108,
"chunksReceived": 1,
"chunksExpected": 10
}
Chunk Size: Maximum 5,000 events per request. For a 100,000-tag session, this requires 20 chunks.
GET /rfid/scans/sessions/{sessionId}/upload-status
Description: Check upload progress. Used by mobile app to resume after network failure — identifies which chunks are missing so only those need retrying.
Authentication: Bearer token (Cashier+)
Response: 200 OK
{
"sessionId": "scan_001",
"status": "incomplete",
"chunksReceived": [0, 1, 2, 4, 5],
"chunksMissing": [3, 6, 7, 8, 9],
"totalEvents": 14892,
"uniqueEpcs": 14540
}
POST /rfid/scans/sessions/{sessionId}/complete
Description: Complete scan session and trigger variance calculation
Authentication: Bearer token (Cashier+)
Request Body:
{
"endedAt": "2025-12-29T10:30:00Z",
"notes": "Section A complete, 2 unknown tags flagged"
}
Response: 200 OK
{
"sessionId": "scan_001",
"status": "completed",
"summary": {
"totalTagsScanned": 47000,
"uniqueEpcs": 46540,
"expectedCount": 505,
"variance": 7,
"variancePercentage": 1.39,
"reviewRequired": false
},
"completedAt": "2025-12-29T10:30:00Z"
}
Variance Thresholds (configurable per tenant):
| Variance | Action |
|---|---|
| 0% | Auto-approve |
| 1-2% | Review recommended |
| 3-5% | Manager review required |
| > 5% | Recount required |
A.14 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"
}
A.15 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
A.16 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
}
}
A.17 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 |
A.18 Additional Endpoint References
Note (v5.0.0): The following endpoint groups are defined in Chapter 05 (Architecture Components) and are not fully duplicated here. Refer to the source chapter for complete request/response schemas.
- Tax Jurisdictions (
/api/v1/tax-jurisdictions,/api/v1/tax-rates): Compound tax configuration with 3-level (State/County/City) support. See Chapter 05 Section 1.17 for full specification. - RFID Configuration & Counting (
/api/v1/rfid/*): Tag templates, tag mappings, counting sessions, chunked sync upload. See Chapter 05 Section 5.16 for the complete RFID API specification. Also see Domain 12 (Section A.13) above for endpoint details already documented. - Integration Sync (
/api/v1/integrations/*): Shopify, Amazon SP-API, Google Merchant channel sync endpoints. See Chapter 13 (Integrations) for full specification.
A.19 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.
Document Information
| Attribute | Value |
|---|---|
| Version | 5.0.0 |
| Created | 2025-12-29 |
| Updated | 2026-02-25 |
| Author | Claude Code |
| Status | Active |
| Section | Appendix A |
This appendix is part of the POS Blueprint Book. All content is self-contained.