Skip to main content

Ecommerce API Integration

The Ecommerce API gives an approved website a read-only view of products explicitly published by one ERP tenant. It is disabled by default and does not accept orders or payments.

Before you connect​

  1. Ask eSecured support to enable Ecommerce API for the tenant. This is a platform-controlled feature flag; tenant users cannot enable it themselves.
  2. In ERP, open Settings → Integrations → Ecommerce API as the tenant's Tenant Admin.
  3. Publish only the products intended for the storefront using Items → Edit Product → Publish to ecommerce. A product is returned only when it is a Product, Active, and explicitly published.
  4. Create a named API key for the website environment (for example, staging website).

Use separate credentials for staging and production. The API key is shown once; store it in the website's server-side secret manager or environment configuration. Never place it in browser JavaScript, a mobile app, source control, or a public repository. Revoke a key immediately if it is exposed or no longer needed.

The public API hostname is api.erp.co.tz. It resolves through Cloudflare, but the Cloudflare Worker route for the catalog endpoint must be deployed before sharing this address with a live storefront. Until then, requests to this hostname will not reach the API. The hostname is a stable public address, not a security control: the upstream remains protected by the API key and tenant-bound authorization.

Endpoint​

GET https://api.erp.co.tz/ecommerce/v1/products
Authorization: Bearer <ecommerce-api-key>

The credential is bound to its tenant when created. Do not send a tenant ID to choose the data source; the API derives the tenant from the verified credential.

Query parameters​

ParameterDefaultLimitsMeaning
limit501–100Maximum products in this page
cursornoneopaque string returned by the APIContinue after the last product in the previous page

Example response​

{
"products": [
{
"id": "item-id",
"sku": "MAR-001",
"name": "Event T-shirt",
"description": "Official event shirt",
"unit": "Each",
"price": 25000,
"currency": "TZS",
"brand": null,
"barcode": null,
"category": "Apparel",
"updatedAt": "2026-10-25T12:00:00.000Z"
}
],
"page": {
"limit": 50,
"hasMore": false,
"nextCursor": null
}
}
FieldSource
skuThe item's Item Code
priceThe item's Selling Price as entered in ERP. It is VAT-inclusive or VAT-exclusive according to the tenant's price-entry VAT setting (Settings → Company → Regional & Tax); the API doesn't convert it
currencyThe tenant's base currency
categoryThe item's Item Category. If none is set, the Food / Beverage tag used by Restaurant POS; otherwise null
description, brand, barcodenull when not set on the item

Only public catalog fields are returned. Internal cost prices, account mappings, stock movements, and customer records are never included. Inventory availability is not part of this first version.

Treat name, description, and other catalog values as text supplied by tenant users. Escape them when rendering in a storefront; do not inject them as HTML.

Server-side JavaScript example​

Keep ESECURED_ECOMMERCE_API_KEY in the server's secret manager or environment configuration:

const response = await fetch(
"https://api.erp.co.tz/ecommerce/v1/products?limit=50",
{
headers: {
Authorization: `Bearer ${process.env.ESECURED_ECOMMERCE_API_KEY}`,
Accept: "application/json",
},
},
);

if (!response.ok) {
throw new Error(`ERP catalog request failed: ${response.status}`);
}

const catalogPage = await response.json();

For more products, request the next page using page.nextCursor while page.hasMore is true. Do not log the Authorization header or API key.

Credential lifecycle and safeguards​

  • Keys are random, tenant-bound, read-only (products:read), and stored as hashes.
  • A newly created key is returned once to the Tenant Admin; the ERP does not display it later.
  • Up to 10 active credentials can exist for a tenant. Give each integration environment its own key.
  • Each key is limited to 60 requests per minute. A 429 response includes Retry-After.
  • Revocation takes effect immediately on the next request.
  • Product API requests are read-only, limited to published active products, and paginated with a maximum page size of 100.
  • The catalog endpoint rejects browser-originated requests. Keep credentials on the website server; CORS is not an authentication mechanism.
  • Responses use Cache-Control: no-store. Catalog reads update the credential's last-used time but are excluded from per-request API telemetry to avoid storing product data or generating excessive logs. Credential-management operations are logged without request or response bodies.

Errors​

StatusErrorAction
400Invalid limit or cursorCorrect the query parameters; use the cursor returned by the previous page
401unauthorizedThe key is missing, malformed, unknown or revoked. Check the key; create a replacement if it was lost or revoked
403ecommerce_api_disabled or server_to_server_onlyAsk eSecured support to check the tenant feature flag; make the request from the website server, not a browser
429rate_limit_exceededWait for the Retry-After interval before retrying
500internal_errorRetry with backoff; contact support if it persists
503service_unavailableRetry with backoff; contact support if it persists

API contract​

The machine-readable OpenAPI specification describes the product endpoint and the Tenant Admin credential-management operations. Only GET /ecommerce/v1/products is available at https://api.erp.co.tz. The credential-management operations are internal: they are what Settings → Integrations → Ecommerce API uses, they need a signed-in Tenant Admin's ERP session, and they can't be called through the public hostname.