Getting Started
Welcome to the Tracepos Public API. Our REST API is built on high-performance infrastructure, providing developer-friendly access to inventory catalogs, multi-branch warehouses, customer ledgers, sales recording, purchase procurement, and real-time double-entry accounting.
Base URLs
All API interactions must take place over secure HTTPS:
| Environment | Base URL |
|---|---|
| Production Cloud | https://app.tracepos.net/api/v1/public/ |
| Local Development | http://localhost:8000/api/v1/public/ |
Authentication at a Glance
Tracepos uses an Enterprise Dual-Key Architecture for maximum security and warehouse-level scoping:
X-Tracepos-Public-Key: A public identifier (e.g.Trp-pk-9f8a...) used by Tracepos to route the request to the correct tenant and warehouse branch.X-Tracepos-Secret-Key: A private secret (e.g.Trp-sk-7c1b...) verified server-side against an encrypted hash. Never expose this key in client-side code.
Both headers are mandatory for every API request:
X-Tracepos-Public-Key: YOUR_PUBLIC_KEY
X-Tracepos-Secret-Key: YOUR_SECRET_KEY
Accept: application/json
Content-Type: application/json
For full details on key generation and permissions, see the Authentication Guide.
Step 1: Generate Your Warehouse API Keys
- Log in to your Tracepos Admin Dashboard.
- Navigate to Settings → API Keys.
- Click Generate New API Key.
- Give your key a label (e.g.
Main Cashier POS 1,E-Commerce Storefront,Paystack Terminal). - Select the warehouse branch that this key will operate against.
- Copy both the Public Key and Secret Key. Note that the secret key is shown once for security.
Step 2: Make Your First API Call
Test connectivity by retrieving the list of products in your warehouse catalog:
curl -X GET "https://app.tracepos.net/api/v1/public/products?limit=5" \
-H "X-Tracepos-Public-Key: YOUR_PUBLIC_KEY" \
-H "X-Tracepos-Secret-Key: YOUR_SECRET_KEY" \
-H "Accept: application/json"
const axios = require('axios');
const tracepos = axios.create({
baseURL: 'https://app.tracepos.net/api/v1/public',
headers: {
'X-Tracepos-Public-Key': process.env.TRACEPOS_PUBLIC_KEY,
'X-Tracepos-Secret-Key': process.env.TRACEPOS_SECRET_KEY,
'Accept': 'application/json',
},
});
async function getProducts() {
try {
const response = await tracepos.get('/products', { params: { limit: 5 } });
console.log('Products:', response.data);
} catch (error) {
console.error('API Error:', error.response?.data || error.message);
}
}
getProducts();
import os
import requests
BASE_URL = "https://app.tracepos.net/api/v1/public"
headers = {
"X-Tracepos-Public-Key": os.getenv("TRACEPOS_PUBLIC_KEY"),
"X-Tracepos-Secret-Key": os.getenv("TRACEPOS_SECRET_KEY"),
"Accept": "application/json",
}
response = requests.get(f"{BASE_URL}/products", headers=headers, params={"limit": 5})
if response.status_code == 200:
print("Catalog:", response.json())
else:
print("Error:", response.status_code, response.text)
<?php
require 'vendor/autoload.php';
use GuzzleHttp\Client;
$client = new Client([
'base_uri' => 'https://app.tracepos.net/api/v1/public/',
'headers' => [
'X-Tracepos-Public-Key' => getenv('TRACEPOS_PUBLIC_KEY'),
'X-Tracepos-Secret-Key' => getenv('TRACEPOS_SECRET_KEY'),
'Accept' => 'application/json',
]
]);
$response = $client->get('products', [
'query' => ['limit' => 5]
]);
echo $response->getBody();
Response Envelope Standard
Every API response follows a consistent JSON envelope structure:
Successful Response (200 OK, 201 Created)
{
"status": "success",
"data": {
"current_page": 1,
"data": [
{
"xid": "w8vBqGZ0",
"name": "Basmati Rice 50kg",
"item_code": "RICE-50KG",
"sales_price": 75000.00,
"current_stock": 142
}
]
}
}
Error Response (4xx, 5xx)
{
"status": "error",
"message": "The product items field is required.",
"errors": {
"product_items": [
"The product items field is required."
]
}
}
HTTP Status Codes
Tracepos returns standard RFC HTTP status codes:
| Code | Status | Meaning |
|---|---|---|
200 | OK | Request completed successfully. |
201 | Created | Resource created (e.g. sale, payment, or customer). |
400 | Bad Request | Malformed JSON or invalid parameter types. |
401 | Unauthorized | Missing or invalid Public Key / Secret Key headers. |
403 | Forbidden | Expired SaaS license or key deactivated. |
404 | Not Found | The requested resource (product, customer, order) does not exist in this warehouse. |
422 | Unprocessable Entity | Form validation failed (e.g. missing required line items). |
429 | Too Many Requests | Rate limit exceeded (60 requests/minute default). Retry after header indicates seconds. |
500 | Internal Server Error | Unexpected server condition. Transaction was rolled back automatically. |
Rate Limiting
The Public API enforces rate limits per active key to safeguard warehouse infrastructure:
- Default Window: 60 requests per minute.
- Custom enterprise limits can be configured in your Warehouse API Key settings.
Tracepos includes rate limit status headers with every response:
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 58
X-RateLimit-Reset: 1775040060
When throttled, the server returns HTTP 429 Too Many Requests with a Retry-After header. Learn how to handle backoff gracefully in the Security Guide.
