Skip to main content

Using Edify APIs to pull data

The Edify API lets you pull your operational data directly into your own systems — whether that's a BI tool, a finance platform, or a custom dashboard.

This article covers everything you need to get started and make your first requests.


Before you start

To use the API you'll need an API key. Your API key is specific to your account and determines which sites and data you can access.

Please contact Customer Support on hello@edifysystems.io who will assist with setting up your API key.


Authentication

Every request to the API requires your API key as a Bearer token in the Authorization header:

Authorization: Bearer eak_1...

If your key is missing or invalid, the API will return a 401 Unauthorized response.


Base URL

All API requests go to:


Available endpoints

Endpoint

Method

What it returns

/reports/external/sites

GET

Your accessible sites and locations

/reports/external/profitability

POST

Sold item profitability by day

/reports/external/waste

POST

Waste events for products and recipes

/reports/external/cogs

POST

COGS summary with per-class breakdown

/reports/external/variance

POST

Per-item COGS variance

/reports/external/deliveries

POST

Delivery orders with product line items

/reports/external/suppliers

GET

Your suppliers with contacts and site links

/reports/external/suppliers/:id/products

GET

Products for a specific supplier

/reports/external/recipes

POST

Recipes with ingredients, costs, and timing

/reports/external/transfers

POST

Inter-site stock transfers


How requests work

GET vs POST

  • GET endpoints (sites, suppliers, supplier products) use query parameters in the URL

  • POST endpoints accept a JSON body

Standard POST parameters

Most POST endpoints accept these parameters:

Parameter

Type

Required

Description

siteId

UUID

Yes

The Edify site ID you're querying

startDate

string

Yes

Start of the date range — YYYY-MM-DD format

endDate

string

Yes

End of the date range — YYYY-MM-DD format

format

string

No

json (default) or csv

Note: the recipes endpoint doesn't take date parameters — it returns all recipes for a site.

Response format

JSON responses return your data in a data field:

{

"data": [...]

}

CSV responses return a plain CSV with PascalCase column headers.


Pagination

The following endpoints support pagination: deliveries, suppliers, supplier products, recipes, and transfers.

Parameter

Type

Default

Description

page

integer

1

Page number

pageSize

integer

50

Records per page (max: 100)

Paginated JSON responses include a pagination object alongside your data:

{

"data": [...],

"pagination": {

"page": 1,

"pageSize": 50,

"total": 142,

"totalPages": 3

}

}

When using format: csv, pagination is ignored and all records are returned in one file.


Step 1 — Get your site IDs

Before querying most endpoints, you'll need the UUID for each site you want to pull data for. Use the sites endpoint to get these:

GET /reports/external/sites

Example response:

{

"data": [

{

"id": "3affb5d9-0492-41e4-bcaa-da8eeece4b42",

"name": "WatchHouse Fifth Avenue",

"companyId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",

"companyName": "WatchHouse",

"currency": "USD"

}

]

}

The id field from each result is your siteId for other requests. Admin users will see all sites in their company; other roles will see the sites they're assigned to.


Endpoint reference

Profitability

POST /reports/external/profitability

Returns sold item profitability data, one row per item per day. Includes sales, ingredient costs, and profit.

Example request:

{

"siteId": "9e2210d2-8b0e-4e34-91bc-84af64735670",

"startDate": "2026-03-01",

"endDate": "2026-03-31"

}

Key fields to know:

  • menuItemName, menuItemCategory, menuItemClass — these will be null if the POS item hasn't been mapped to an Edify recipe

  • recipeIngredientsCost — unit cost; also null if unmapped

  • profit — net sales minus total ingredient cost; null if unmapped

  • totalSales — includes modifiers


Waste

POST /reports/external/waste

Returns waste events logged for both products and recipes.

Key fields:

  • wasteType — either product or recipe

  • comments — the reason selected when waste was logged (e.g. Damaged, No longer fresh, Beyond expiry date)

  • quantity and uomName — how much was wasted and in what unit


COGS

POST /reports/external/cogs

Returns a COGS summary for the period, mirroring the Single Site COGS page in Edify. Includes overall figures plus a breakdown by product class.

Key fields:

  • fromDate / toDate — the opening and closing stocktake dates used for the period (not necessarily your exact startDate/endDate)

  • actualUsage — actual COGS value

  • actualUsagePercent — COGS as a proportion of sales (4 decimal places; null if sales = 0)

  • theoreticalUsage — what COGS should have been based on sales

  • breakdown — array of per-product-class rows with their own actuals, purchases, transfers, and margins


COGS Variance

POST /reports/external/variance

Returns a per-item breakdown of actual vs theoretical COGS, mirroring the COGS Variance table in Edify.

Key fields:

  • actualUsage — opening stock + purchases + transfers − waste − closing stock

  • theoreticalUsage — expected usage based on sales

  • varianceQuantity — difference between actual and theoretical, in units

  • varianceCost — cost value of that variance

  • stockChange — inventory movement as a percentage between stocktakes


Deliveries

POST /reports/external/deliveries

Returns delivery orders with full product line items, including any credit note details. Date range is capped at 366 days.

Key delivery fields:

  • orderNumber — Edify PO number (null for ad-hoc deliveries)

  • supplierReference — the supplier's own invoice number

  • deliveryDate — actual delivery date (null if not yet delivered)

  • isManualOrder — true if the order was created outside the ordering workflow

Key line item fields:

  • initialQuantity / initialPrice — what was originally ordered before any amendments

  • creditQuantity / creditPrice — credit note values if a credit was raised

  • creditNoteStatus — the current status of the credit note workflow

  • creditRequestNotes — the reason given for the credit request


Suppliers

GET /reports/external/suppliers

Returns your suppliers with contact details, ordering configuration, integrations, and the sites they're linked to.

Supports pagination via query parameters: ?page=1&pageSize=20

Key fields:

  • status — active, inactive, or deleted

  • orderCutOffTimes — per-day cut-off and delivery windows; days with null times have no delivery

  • isCpu — whether this is a Central Production Unit supplier

  • integrations — connected integrations (e.g. Bidfood, Brakes, Xero)

  • sites — sites linked to this supplier, with site-specific account numbers


Supplier Products

GET /reports/external/suppliers/:supplierId/products

Returns products for a given supplier. Add a siteId query parameter to also get site-specific pricing, live stock levels, and blocked status.

Example request:

GET /reports/external/suppliers/f1e2d3c4-b5a6-7890/products?siteId=01cc8b96-77f0-4177-b44c-99d8a2f82a0c

Key fields:

  • packType, packQuantity — how the product is packaged and how many units per pack

  • packCost — cost per pack

  • allowSplitPack — whether individual units can be ordered

  • singleUnitType / singleItemVolumeOrWeight / unitOfMeasure — the base unit this product is measured in

  • allergens — contains and traces allergen lists

  • masterProduct — the master product this is linked to, if any

  • excludeFromCogs / useActualForTheoreticalCogs — COGS calculation settings

Site-specific fields (only present when siteId is provided):

  • sitePriceOverride — site-specific price, or null if using the default

  • isBlockedAtSite — whether the product is blocked at that site

  • liveStockLevel — current stock level at the site


Recipes

POST /reports/external/recipes

Returns all recipes for a site — ingredients, costs, packaging, timing, and production settings. Unlike other POST endpoints, this doesn't take date parameters.

Key recipe fields:

  • isSubRecipe — whether this recipe is used as an ingredient in other recipes

  • countInStockTake — whether it appears in stocktake counts

  • allergens — allergens present in the recipe

  • yield — how much one batch produces

Key ingredient fields:

  • type — the source of the ingredient: supplierProduct, productVariant, masterProduct, subRecipe, or generic

  • yieldLoss — percentage wasted during prep (e.g. 0.05 = 5%)

  • netQuantity — effective quantity after yield loss

  • isKeyIngredient — whether this is flagged as a key ingredient

Cost fields:

  • ingredientsCost — total ingredient cost per yield unit

  • packagingCost — broken down by service channel (dineIn, takeAway, delivery)

When using format: csv, each row represents a single ingredient or packaging line — recipe-level fields are repeated on each row.


Transfers

POST /reports/external/transfers

Returns inter-site stock transfers where the specified site was either the sender or receiver. Date range is capped at 366 days.

Transfer line items can be either supplier products or recipes:

  • Products: use productId, quantity, and unitOfMeasure

  • Recipes: use recipeId, recipeYieldTypeAmount, and recipeYieldType (e.g. 5 loaves)

initialQuantity / initialRecipeYieldTypeAmount reflect what was originally requested before any amendments.

Key status values: pending, sent, accepted, declined, cancelled


Tips

Finding your siteId: Always start with GET /reports/external/sites to get the correct UUID for each location. Don't use the site name — IDs are what the API expects.

Date ranges: Use YYYY-MM-DD format. The deliveries and transfers endpoints have a hard cap of 366 days per request — paginate if you need more.

CSV format: Useful for bulk exports and loading into spreadsheets directly. When using CSV, pagination is ignored and you'll get all records in one go.

Null values: Some fields will be null in certain conditions (e.g. profitability fields when a POS item isn't mapped to a recipe). Your integration should handle null gracefully rather than expecting a value to always be present.

Permissions: What you can see depends on your role. Admin users see all sites and suppliers in their company; other roles see only what they've been assigned access to.


Need help?

If you're stuck on a specific endpoint or seeing unexpected results, get in touch with your Customer Success contact or email us at hello@edifysystems.io.

Did this answer your question?