Tracepos Developer HubTracepos Developer Hub
Home
Guide
POS & Integrations
API Reference
Webhooks
Home
Guide
POS & Integrations
API Reference
Webhooks
  • Getting Started

    • Getting Started
    • Authentication
    • Architecture & Core Concepts
    • Security & Best Practices
    • Deployment & Hosting Guide

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:

EnvironmentBase URL
Production Cloudhttps://app.tracepos.net/api/v1/public/
Local Developmenthttp://localhost:8000/api/v1/public/

Authentication at a Glance

Tracepos uses an Enterprise Dual-Key Architecture for maximum security and warehouse-level scoping:

  1. 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.
  2. 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

  1. Log in to your Tracepos Admin Dashboard.
  2. Navigate to Settings → API Keys.
  3. Click Generate New API Key.
  4. Give your key a label (e.g. Main Cashier POS 1, E-Commerce Storefront, Paystack Terminal).
  5. Select the warehouse branch that this key will operate against.
  6. 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
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"
Node.js (Axios)
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();
Python (Requests)
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 (Guzzle)
<?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:

CodeStatusMeaning
200OKRequest completed successfully.
201CreatedResource created (e.g. sale, payment, or customer).
400Bad RequestMalformed JSON or invalid parameter types.
401UnauthorizedMissing or invalid Public Key / Secret Key headers.
403ForbiddenExpired SaaS license or key deactivated.
404Not FoundThe requested resource (product, customer, order) does not exist in this warehouse.
422Unprocessable EntityForm validation failed (e.g. missing required line items).
429Too Many RequestsRate limit exceeded (60 requests/minute default). Retry after header indicates seconds.
500Internal Server ErrorUnexpected 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.

Next
Authentication