TypeScript
Types below match the API Reference shapes - money/decimal fields are string,
never number.
A small typed client
Section titled “A small typed client”const BASE_URL = "https://dev-api.theprioryshop.co.uk";const API_KEY = process.env.EPOS_API_KEY as string; // never hardcode this
interface EposErrorBody { error: { code: string; message: string; details: Record<string, unknown>; requestId: string };}
class EposApiError extends Error { constructor(public code: string, public requestId: string, public status: number, message: string) { super(message); }}
async function eposGet<T>(path: string): Promise<T> { const res = await fetch(`${BASE_URL}${path}`, { headers: { Authorization: `Bearer ${API_KEY}` } }); if (!res.ok) { const body = (await res.json()) as EposErrorBody; throw new EposApiError(body.error.code, body.error.requestId, res.status, body.error.message); } return res.json() as Promise<T>;}
interface CatalogProduct { id: string; storeId: string; categoryId: string | null; name: string; sku: string; barcode: string | null; sellingPriceGross: string; // decimal string, not a number sellingPriceNet: string; isActive: boolean; updatedAt: string; // ISO 8601}
interface CatalogProductListResponse { rows: CatalogProduct[]; page: number; pageSize: number; total: number; totalPages: number;}List products
Section titled “List products”const products = await eposGet<CatalogProductListResponse>("/v1/catalog/products?pageSize=20");Handle an error
Section titled “Handle an error”try { await eposGet<CatalogProduct>("/v1/catalog/products/does-not-exist");} catch (err) { if (err instanceof EposApiError) { if (err.code === "not_found") { // ... } else if (err.code === "rate_limited") { // back off and retry - see Rate Limits } else { console.error(`EPOS API error ${err.code} (request ${err.requestId})`); } } else { throw err; }}Paginate through every product
Section titled “Paginate through every product”async function* allProducts(): AsyncGenerator<CatalogProduct> { let page = 1; while (true) { const { rows, totalPages } = await eposGet<CatalogProductListResponse>( `/v1/catalog/products?pageSize=100&page=${page}` ); yield* rows; if (page >= totalPages) break; page += 1; }}The full field list for every response type is generated straight from the OpenAPI document - see the API Reference rather than re-declaring every interface here by hand.