Skip to content
DEV preview — API version 1.0.0 — not the public production site — Development API: dev-api.theprioryshop.co.uk

TypeScript

Types below match the API Reference shapes - money/decimal fields are string, never number.

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;
}
const products = await eposGet<CatalogProductListResponse>("/v1/catalog/products?pageSize=20");
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;
}
}
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.