API Overview
API Overview
The Neat Profit API provides programmatic access to bar inventory management, POS integration, demand forecasting, and analytics. This guide covers the API architecture, design principles, and how to get the most out of our endpoints.
Base URLs
- Sandbox:
https://sandbox-api.theneatprofit.com/v1 - Production:
https://api.theneatprofit.com/v1
All API paths are relative to the base URL. For example, the full URL for the inventory items endpoint in production would be:
https://api.theneatprofit.com/v1/inventory/items
API Architecture
RESTful Design
The API follows REST principles:
- Resource-based URLs - Each resource has a clear, hierarchical URL structure
- HTTP methods - Use appropriate methods (GET, POST, PUT, DELETE) for operations
- Standard status codes - HTTP status codes indicate success or failure
- JSON format - All requests and responses use JSON
Versioning
The API is versioned using the URL path (/v1/). We will maintain backward compatibility within each version. When breaking changes are necessary, we will release a new version (/v2/) and maintain the old version for at least 12 months.
Request Format
Headers
All API requests must include:
X-API-Key: your-api-key
Content-Type: application/json
Query Parameters
Use query parameters for filtering, sorting, and pagination:
GET /v1/inventory/items?location=main_bar&sort=name&order=asc
Request Body
POST and PUT requests should include a JSON body:
{
"name": "Tito's Handmade Vodka",
"sku": "SKU-001",
"quantity": 12.5,
"unit": "bottle"
}
Response Format
Success Response
{
"data": {
"id": "item_abc123",
"name": "Tito's Handmade Vodka",
"sku": "SKU-001",
"quantity": 12.5
},
"meta": {
"request_id": "req_xyz789",
"timestamp": "2026-01-15T10:30:00Z"
}
}
Error Response
{
"error": {
"code": "invalid_parameter",
"message": "The 'quantity' parameter must be a positive number",
"details": {
"parameter": "quantity",
"value": "-5"
}
},
"meta": {
"request_id": "req_xyz789",
"timestamp": "2026-01-15T10:30:00Z"
}
}
Pagination
List endpoints support pagination:
{
"data": [...],
"pagination": {
"total": 150,
"page": 1,
"per_page": 50,
"total_pages": 3,
"next_page_url": "/v1/inventory/items?page=2",
"prev_page_url": null
}
}
Pagination parameters:
page- Page number (default: 1)per_page- Items per page (default: 50, max: 100)
Rate Limiting
Limits
- Sandbox: 100 requests per minute
- Production: 1,000 requests per minute
Headers
Rate limit information is included in response headers:
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 999
X-RateLimit-Reset: 1705334400
X-RateLimit-Reset-After: 59
Handling Limits
When you exceed the rate limit, you’ll receive a 429 Too Many Requests response:
{
"error": {
"code": "rate_limit_exceeded",
"message": "Rate limit exceeded. Try again in 60 seconds."
}
}
Implement exponential backoff when handling rate limits:
async function makeRequest(url, options, retries = 3) {
try {
const response = await fetch(url, options);
if (response.status === 429 && retries > 0) {
const retryAfter = parseInt(response.headers.get('Retry-After') || '5');
await new Promise(resolve => setTimeout(resolve, retryAfter * 1000));
return makeRequest(url, options, retries - 1);
}
return response;
} catch (error) {
if (retries > 0) {
await new Promise(resolve => setTimeout(resolve, 1000 * (4 - retries)));
return makeRequest(url, options, retries - 1);
}
throw error;
}
}
Idempotency
To prevent duplicate operations, use idempotency keys for POST requests:
X-Idempotency-Key: your-unique-key-here
Idempotency keys are valid for 24 hours. If you retry a request with the same key within that window, the API will return the original response.
Webhooks
Webhooks provide real-time notifications when events occur:
inventory.updated- Inventory quantity changedinventory.low_stock- Item below reorder pointvariance.detected- Variance threshold exceededorder.created- New order createdorder.shipped- Order shippedpos.sync_completed- POS sync completed
See the Webhooks documentation for details.
SDKs
Official SDKs are available:
SDKs handle authentication, pagination, error handling, and webhooks automatically.
Best Practices
Security
- Never expose API keys in client-side code
- Use environment variables for credentials
- Implement webhook signature verification
- Rotate API keys regularly
- Use HTTPS for all requests
Performance
- Use pagination for large datasets
- Cache frequently accessed data
- Use batch endpoints when available
- Implement request batching
Reliability
- Implement proper error handling
- Use idempotency keys for critical operations
- Set up monitoring and alerting
- Test in sandbox before production
Available Endpoints
Inventory
GET /v1/inventory/items- List inventory itemsPOST /v1/inventory/items- Create inventory itemGET /v1/inventory/items/:id- Get item detailsPUT /v1/inventory/items/:id- Update itemDELETE /v1/inventory/items/:id- Delete itemPOST /v1/inventory/count- Submit inventory count
POS Integration
GET /v1/pos/connections- List POS connectionsPOST /v1/pos/connections- Create POS connectionGET /v1/pos/connections/:id- Get connection detailsPUT /v1/pos/connections/:id- Update connectionDELETE /v1/pos/connections/:id- Delete connectionPOST /v1/pos/sync- Trigger POS syncGET /v1/pos/mappings- List product mappings
Ordering
GET /v1/orders- List ordersPOST /v1/orders- Create orderGET /v1/orders/:id- Get order detailsPUT /v1/orders/:id- Update orderDELETE /v1/orders/:id- Cancel orderGET /v1/distributors- List distributorsPOST /v1/distributors- Add distributor
Analytics
GET /v1/analytics/variance- Get variance reportGET /v1/analytics/forecast- Get demand forecastGET /v1/analytics/performance- Get performance metricsGET /v1/analytics/costing- Get recipe costing data
Webhooks
GET /v1/webhooks- List webhooksPOST /v1/webhooks- Create webhookGET /v1/webhooks/:id- Get webhook detailsPUT /v1/webhooks/:id- Update webhookDELETE /v1/webhooks/:id- Delete webhook
Next Steps
- Authentication - Learn about authentication methods
- Inventory API - Inventory management endpoints
- POS Integration - POS sync and mapping
- Webhooks - Real-time notifications