This guide is for developers maintaining an external retail system that synchronises merchandise, food and beverage, or other non-ticket inventory with Ventrata.
This guide covers:
creating an item using one of two pricing models:
📒 NOTE
The examples use https://api.ventrata.com/octo as the OCTO base URL. Use the endpoint and API token supplied for your connection.
Obtain Connection API Key
Locate your API key in the Ventrata Dashboard.
Locate your API key in the Ventrata Dashboard.
Prerequisites:
Contact your Ventrata Customer Success Manager or the Connectivity team to create a connection in 'Backoffice' mode for you in the Ventrata Dashboard.
The connection must have:
read permission for catalogue and tax-rate requests
write permission for create, update and delete requests
In your Ventrata Dashboard, go to Connections > Connections.
Connections
Locate and select the relevant connection.
Connection
📗 TIP
The Mode column shows
dashboardfor this connection type.On the connection detail, press the eye icon to reveal your API key.
Copy the API key and send it in the
Authorization: Bearer <API_TOKEN>header.‼️ IMPORTANT
Your API key is a confidential credential that provides access to your Ventrata account. Never share it over chat or email, and do not put it in source control, support tickets, or application logs.
Required Headers
Send the required headers with every request.
Send the required headers with every request.
Header | Description |
| (required) authenticates the request |
| (required) enables the item management capability |
| 📒 NOTE When a purchase includes an external discount (
|
| (required) indicates a JSON payload |
| (optional) controls which fields are returned; supports nested selections, for example, |
Inventory Management Endpoints
Endpoints are relative to the base URL, for example: https://api.ventrata.com/octo.
Endpoints are relative to the base URL, for example: https://api.ventrata.com/octo.
Operation | Method | Endpoint |
List assignable tax rates |
|
|
Retrieve one assignable tax rate |
|
|
List or retrieve selected items |
|
|
Create an item |
|
|
Partially update an item |
|
|
Delete an item |
|
|
Create a purchase and optionally create or update its item just in time |
|
|
📒 NOTE
Catalogue reads use the existing OCTO Retail endpoint. There are no separate Dashboard list or get-item endpoints.
Discover Assignable Tax Rates
List the tax rates available to the connection before you create or update taxable items. Use the Octo-Fields header to choose which fields are returned.
List the tax rates available to the connection before you create or update taxable items. Use the Octo-Fields header to choose which fields are returned.
Field | Type | Description |
| UUID | UUID of the tax rate |
| string | canonical name of the tax rate |
| string | name of the tax rate |
| string | optional description |
| number (percentage) / integer (fixed rates)
|
|
| boolean |
|
| boolean |
|
| string | currency of a fixed tax rate, |
| string array | tags assigned to the tax rate |
Example request
Example request
This is a GET request to list all tax rates available to the connection.
curl --get 'https://api.ventrata.com/octo/ventrata/dashboard/tax_rates' \
--header 'Authorization: Bearer <API_TOKEN>' \
--header 'Octo-Capabilities: ventrata/dashboard' \
--header 'Octo-Fields: {id,internalName,title,subtitle,amount,percentage,rounded,currency,tags}'
Example response (percentage tax rate)
Example response (percentage tax rate)
{
"id": "<TAX_RATE_UUID>",
"internalName": "Standard VAT",
"title": "Standard VAT",
"subtitle": "Standard retail VAT",
"amount": 20.0,
"percentage": true,
"rounded": false,
"currency": null,
"tags": ["retail"]
}
Retrieve a Known Tax Rate
Retrieve a single tax rate by its UUID using the /ventrata/dashboard/tax_rates/{taxRateId} endpoint.
Retrieve a single tax rate by its UUID using the /ventrata/dashboard/tax_rates/{taxRateId} endpoint.
Example request
Example request
curl --get 'https://api.ventrata.com/octo/ventrata/dashboard/tax_rates/<TAX_RATE_UUID>' \
--header 'Authorization: Bearer <API_TOKEN>' \
--header 'Octo-Capabilities: ventrata/dashboard' \
--header 'Octo-Fields: {id,internalName,title,subtitle,amount,percentage,rounded,currency,tags}'
Read the Item Catalogue
List the items in the catalogue and store each item's Ventrata id as the durable mapping key in your external system. For the list of fields you can request with the Octo-Fields header, see Item Response Fields.
List the items in the catalogue and store each item's Ventrata id as the durable mapping key in your external system. For the list of fields you can request with the Octo-Fields header, see Item Response Fields.
Example request
Example request
This is a GET request to list items available to the connection.
curl --get 'https://api.ventrata.com/octo/items' \
--header 'Authorization: Bearer <API_TOKEN>' \
--header 'Octo-Capabilities: ventrata/dashboard' \
--header 'Octo-Fields: {id,internalName,reference,billingAccountCode,destination{id,title},active,customRetail,retail,customCost,cost,currency,coverImageUrl,taxIncluded,taxRates{id,internalName,amount,percentage,currency}}'
Pagination
The item list supports the page and perPage query parameters. When pagination applies, the response includes the Octo-Total-Pages header.
The item list supports the page and perPage query parameters. When pagination applies, the response includes the Octo-Total-Pages header.
Example request
Example request
curl --get 'https://api.ventrata.com/octo/items' \
--header 'Authorization: Bearer <API_TOKEN>' \
--header 'Octo-Capabilities: ventrata/dashboard' \
--data-urlencode 'page=2' \
--data-urlencode 'perPage=50'
Retrieve Known Items
To retrieve specific items by their Ventrata UUIDs, repeat the itemIds[] query parameter. This is an efficient way to reconcile items your system has already mapped.
To retrieve specific items by their Ventrata UUIDs, repeat the itemIds[] query parameter. This is an efficient way to reconcile items your system has already mapped.
Example request
Example request
curl --get 'https://api.ventrata.com/octo/items' \
--header 'Authorization: Bearer <API_TOKEN>' \
--header 'Octo-Capabilities: ventrata/dashboard' \
--data-urlencode 'itemIds[]=<ITEM_UUID_1>' \
--data-urlencode 'itemIds[]=<ITEM_UUID_2>'
Item Identifiers
Each item has several fields that identify or name it.
Each item has several fields that identify or name it.
Field | Use it for | Notes | Editable |
| the durable mapping key in your external system | generated by Ventrata | N |
| a human-readable external reference, for example, a barcode | maps to the 'SKU/Code' field in the Ventrata Dashboard; used for just-in-time matching and can be used as | Y |
| an accounting reference | maps to the 'Billing Account Code' field in the Ventrata Dashboard; independent of
returned in item and purchase responses | Y |
| the item's name | maps to the translated item name in the Ventrata Dashboard | Y |
| a fallback for | returns the same name as | Y |
📒 NOTE
Do not use reference as your system's only identity key as it is editable. Store the Ventrata id instead.
Create an Item
Create an item using one of two retail pricing models.
Create an item using one of two retail pricing models.
📒 NOTE
Cost is configured independently of the pricing mode; each model below shows both options. For all other item parameters, such as internalName, reference, billingAccountCode, destinationId, coverImageUrl, and taxRateIds, see Writable Item Parameters.
The response is the created item, filtered by Octo-Fields when supplied.
Fixed Price Managed in Ventrata
Use this model when Ventrata owns the item's selling price.
Use this model when Ventrata owns the item's selling price.
set
customRetailtofalse, or omit it becausefalseis the defaultsend
retailon the item in integer minor units, for example,2500for £25.00send
taxIncludedto state whether that price includes taxfor a fixed cost, set
customCosttofalseand sendcostin integer minor units
Example request
Example request
This is a POST request to create a fixed-price item at £25.00.
The currency is based on the default currency set in the Supplier Settings.
curl --request POST 'https://api.ventrata.com/octo/ventrata/dashboard/items' \
--header 'Authorization: Bearer <API_TOKEN>' \
--header 'Octo-Capabilities: ventrata/dashboard' \
--header 'Content-Type: application/json' \
--data '{
"internalName": "Tatton guidebook",
"reference": "GUIDEBOOK",
"billingAccountCode": "GUIDEBOOK-001",
"category": "Books",
"destinationId": "<DESTINATION_UUID>",
"customRetail": false,
"retail": 2500,
"customCost": false,
"cost": 1000,
"coverImageUrl": "https://images.example.com/tatton-guidebook.jpg",
"taxIncluded": true,
"taxRateIds": ["<TAX_RATE_UUID>"],
"active": true
}'
Price Managed by the External System
Use this model when the external system owns the selling price and any discount applied at the point of sale. The item does not store a price. Instead, the external system sends the price with each purchase.
Use this model when the external system owns the selling price and any discount applied at the point of sale. The item does not store a price. Instead, the external system sends the price with each purchase.
Step 1: Create the Item
set
customRetailtotruedo not send an item-level
retailvalueset
customCosttotrueif the external system also supplies the cost with each purchase; otherwise set it tofalseand send a fixedcostsend
taxIncludedto state whether the retail values sent with purchases include tax
📗 TIP
To have Ventrata enforce the prices the external system can send, define customRetailOptions or restrictions.minCustomRetail and restrictions.maxCustomRetail on the item.
Example request
Example request
This is a POST request to create an item with an externally managed price and cost.
curl --request POST 'https://api.ventrata.com/octo/ventrata/dashboard/items' \
--header 'Authorization: Bearer <API_TOKEN>' \
--header 'Octo-Capabilities: ventrata/dashboard' \
--header 'Content-Type: application/json' \
--data '{
"internalName": "Externally priced guidebook",
"reference": "GUIDEBOOK-CUSTOM",
"billingAccountCode": "GUIDEBOOK-CUSTOM-001",
"category": "Books",
"destinationId": "<DESTINATION_UUID>",
"customRetail": true,
"customCost": true,
"taxIncluded": true,
"taxRateIds": ["<TAX_RATE_UUID>"],
"active": true
}'
Step 2: Record a Purchase with Price, Cost, and Discount
Send the actual per-unit values with each purchase.
send
retail, the per-unit gross selling price before discountsend
costwhen the item hascustomCost: true; it is required for these items and not applied to fixed-cost itemssend the per-unit external discount as
offerDiscount.retail, and include theocto/offerscapability; omitofferDiscountwhen no external discount applies
Example request
Example request
This is a POST request to create a purchase with a £25.00 per-unit retail value, £10.00 per-unit cost, and a £5.00 per-unit external discount.
curl --request POST 'https://api.ventrata.com/octo/purchases' \
--header 'Authorization: Bearer <API_TOKEN>' \
--header 'Octo-Capabilities: ventrata/dashboard,octo/offers' \
--header 'Content-Type: application/json' \
--header 'Octo-Fields: {uuid,itemId,quantity,retail,cost}' \
--data '{
"itemId": "<ITEM_UUID>",
"quantity": 1,
"currency": "GBP",
"retail": 2500,
"cost": 1000,
"offerDiscount": {
"retail": 500
}
}'
Create an Item Just in Time with a Purchase
You do not need to create every item before sending purchases. A POST /purchases request with the ventrata/dashboard capability can include a nested item object containing the same writable parameters as POST /ventrata/dashboard/items.
You do not need to create every item before sending purchases. A POST /purchases request with the ventrata/dashboard capability can include a nested item object containing the same writable parameters as POST /ventrata/dashboard/items.
When a purchase includes an item object, Ventrata resolves the item as follows:
If the request includes
itemId, Ventrata uses that existing item.If there is no
itemId, Ventrata reuses an item available to the connection with the same non-emptyreference.If no item matches, Ventrata creates a new item from the
itemparameters.
‼️ IMPORTANT
The item is saved before the purchase. If the purchase then fails validation, the item create or update remains saved. Purchase preview requests containing a nested item also save that item create or update.
For the purchase parameters, including the item object, see Purchase Parameters.
Example request
Example request
This is a POST request that creates or reuses a custom-retail soft-drink item while recording a purchase with a £2.70 per-unit gross retail value and a £1.00 per-unit external discount.
curl --request POST 'https://api.ventrata.com/octo/purchases' \
--header 'Authorization: Bearer <API_TOKEN>' \
--header 'Octo-Capabilities: ventrata/dashboard,octo/offers' \
--header 'Content-Type: application/json' \
--header 'Octo-Fields: {uuid,itemId,quantity,retail,pricing{original,retail,offerDiscount{retail}}}' \
--data '{
"quantity": 1,
"currency": "GBP",
"retail": 270,
"offerDiscount": {
"retail": 100
},
"item": {
"internalName": "Soft drink",
"reference": "POS-SOFT-DRINK",
"billingAccountCode": "SOFT-DRINK-001",
"category": "Food and beverage",
"customRetail": true,
"taxIncluded": true,
"taxRateIds": ["<TAX_RATE_UUID>"],
"active": true
}
}'
In this example:
retail: 270is the per-unit gross value before discount.offerDiscount.retail: 100is the per-unit discount supplied by the external system.The resulting per-unit payable retail is £1.70.
The discount can come from a loyalty reward, a promotion, or another external pricing rule. Ventrata records the supplied split and does not recalculate it.
Because the nested item has customRetail: true, it has no item-level retail, and the actual price is sent on the purchase. If the nested item has customCost: true, also send the per-unit cost on the purchase.
The purchase response returns the item's Ventrata UUID in itemId, whether the item was matched or created. If you use Octo-Fields, include itemId. Store this UUID and send it as itemId in later purchases.
Partially Update an Item
Only the parameters included in a PATCH request are changed. Omitted parameters keep their current values. For the full list of parameters, see Writable Item Parameters.
Only the parameters included in a PATCH request are changed. Omitted parameters keep their current values. For the full list of parameters, see Writable Item Parameters.
📒 NOTE
Use either the Ventrata UUID or a non-empty
referenceas{itemId}. UUID is recommended.taxRateIdsreplaces the complete set of assigned tax rates. To add a rate, send the existing UUIDs together with the new one. Pass an empty array to clear all assignments.All supplied tax-rate IDs are validated before the item is updated. If any ID is unavailable to the connection, no part of the update is applied.
internalNameis canonical.titleis accepted as a fallback wheninternalNameis absent.destinationId: "DEFAULT"clears the item's destination.Supplying
coverImageUrlreplaces the cover image. Omit it when the image should remain unchanged.
The response is the updated item, filtered by Octo-Fields when supplied.
Example request 1
Example request 1
This is a PATCH request to update a fixed price to £27.50, set the unit cost to £11.00, replace the cover image, and replace the tax-rate assignments.
curl --request PATCH 'https://api.ventrata.com/octo/ventrata/dashboard/items/<ITEM_UUID>' \
--header 'Authorization: Bearer <API_TOKEN>' \
--header 'Octo-Capabilities: ventrata/dashboard' \
--header 'Content-Type: application/json' \
--header 'Octo-Fields: {id,internalName,reference,billingAccountCode,customRetail,retail,customCost,cost,currency,coverImageUrl,taxIncluded,taxRates{id,internalName,amount,percentage,currency}}' \
--data '{
"customRetail": false,
"retail": 2750,
"customCost": false,
"cost": 1100,
"coverImageUrl": "https://images.example.com/tatton-guidebook-new.jpg",
"taxRateIds": ["<TAX_RATE_UUID>"]
}'
Example request 2
Example request 2
This is a PATCH request to switch an item to externally managed pricing without supplying a fixed retail value.
curl --request PATCH 'https://api.ventrata.com/octo/ventrata/dashboard/items/<ITEM_UUID>' \
--header 'Authorization: Bearer <API_TOKEN>' \
--header 'Octo-Capabilities: ventrata/dashboard' \
--header 'Content-Type: application/json' \
--data '{
"customRetail": true
}'
Delete an Item
Delete a single item identified by its Ventrata UUID or its non-empty reference. UUID is recommended.
Delete a single item identified by its Ventrata UUID or its non-empty reference. UUID is recommended.
Example request
Example request
This is a DELETE request to delete a single item.
curl --request DELETE 'https://api.ventrata.com/octo/ventrata/dashboard/items/<ITEM_UUID>' \
--header 'Authorization: Bearer <API_TOKEN>' \
--header 'Octo-Capabilities: ventrata/dashboard'
A successful delete returns HTTP 200 with an empty body. The item no longer appears in catalogue reads. After a successful delete, remove the item's mapping from your external system or mark it as deleted.
Item Reference
Writable Item Parameters
Use these parameters when you create an item, update an item, or send a nested item in a purchase.
Use these parameters when you create an item, update an item, or send a nested item in a purchase.
Parameter | Type | Description |
| boolean |
|
| string | canonical name of the item;
maps to the translated item name in the Ventrata Dashboard |
| string | accepted as a fallback when |
| string | human-readable external reference, for example, a barcode;
maps to the 'SKU/Code' field in the Ventrata Dashboard |
| string or | accounting reference, independent of
on update, omit it to keep the existing value or send
maps to the 'Billing Account Code' field in the Ventrata Dashboard |
| string | optional description |
| string | retail category of the item |
| UUID or | UUID of the destination where the item is sold;
pass |
|
| 📒 NOTE If the connection is scoped to a single destination, a new item inherits that destination when An explicit |
| boolean |
|
| integer | fixed per-unit selling price in integer minor units, for example,
do not send when |
| boolean |
|
| integer | fixed per-unit cost in integer minor units, for example,
do not send when |
| string | publicly accessible HTTPS image URL or image data URI, such as |
|
| 📒 NOTE Ventrata ingests the cover image and returns its stored URL in |
| boolean |
|
| UUID array | UUIDs of the tax rates to assign; replaces the complete set of assigned tax rates when present; item responses return the assigned rates as full objects under |
| string array | item tags |
| integer array | (optional) allowed custom prices in minor units |
| integer | (optional) minimum custom price in minor units |
| integer | (optional) maximum custom price in minor units |
Purchase Parameters
Use these parameters in a POST /purchases request.
Use these parameters in a POST /purchases request.
Parameter | Type | Description |
| UUID | UUID of the purchased item; if supplied, Ventrata uses that item |
| object | any writable item parameters; used when |
| integer | number of items purchased |
| string | 3-letter code of the purchase currency, for example, |
| integer | per-unit gross selling price before discount, in integer minor units, for example,
send it for items with |
| integer | per-unit cost in integer minor units, for example,
required when the item has |
| integer | (optional) per-unit discount supplied by the external system, in integer minor units, for example,
requires the
omit |
Item Response Fields
Item responses support these fields through Octo-Fields.
Item responses support these fields through Octo-Fields.
📗 TIP
destination and taxRates are expanded objects. Select the nested properties needed for your integration.
Field | Type | Description |
| UUID | UUID of the item; use it as the durable mapping key |
| string | canonical name of the item;
maps to the translated item name in the Ventrata Dashboard |
| string | returns the same name as |
| string | the plural label of the item |
| string | optional description |
| string | human-readable external reference |
| string or | accounting reference;
|
| string | retail category of the item |
| string array | item tags |
| string | two-letter language code based on the 'Default Language' field configured in the Supplier Settings, for example, |
| string | time zone configured in the Supplier Settings, for example |
| UUID or |
|
| string | name of the destination |
| boolean |
|
| boolean |
|
| integer array | allowed custom prices in minor units |
| integer | minimum custom price in minor units |
| integer | maximum custom price in minor units |
| integer | fixed per-unit selling price in integer minor units;
not the charged price when |
| boolean |
|
| integer | fixed per-unit cost in integer minor units |
| string | currency of the item's monetary values; use it when presenting or converting |
| string | URL of the stored cover image |
| boolean |
|
| UUID | UUID of the assigned tax rate |
| string | canonical name of the tax rate |
| number (percentage) / integer (fixed rates)
|
|
| boolean |
|
| string |
|
Example item response
Example item response
{
"id": "<ITEM_UUID>",
"internalName": "Tatton guidebook",
"reference": "GUIDEBOOK",
"billingAccountCode": "GUIDEBOOK-001",
"destination": {
"id": "<DESTINATION_UUID>",
"title": "Tatton Park"
},
"active": true,
"customRetail": false,
"retail": 2750,
"customCost": false,
"cost": 1100,
"currency": "GBP",
"coverImageUrl": "https://res.cloudinary.com/ventrata/image/upload/tatton-guidebook.jpg",
"taxIncluded": true,
"taxRates": [
{
"id": "<TAX_RATE_UUID>",
"internalName": "Standard VAT",
"amount": 20.0,
"percentage": true,
"currency": null
}
]
}
General Integration Recommendations
List the Ventrata item catalogue and store each item's Ventrata
idas the durable mapping key.List tax rates and map their Ventrata IDs before sending item writes.
Choose fixed or custom retail and cost explicitly for every item. For custom-retail or custom-cost items, send the applicable
retail,cost, and optional discount on each purchase.Create missing Ventrata items in advance, or create them just in time with a purchase, and persist the returned item IDs.
Send partial updates containing only parameters that changed. Include
taxRateIdsonly when replacing tax assignments.Reconcile known mappings efficiently with
GET /items?itemIds[]=....Delete items that should be removed, then remove the local mapping or mark it as deleted after success.
Keep
retail,cost, and other monetary values as integer minor units, and use the responsecurrencywhen presenting or converting them.Invalid authentication, permissions, destinations, items, or tax rates return the standard OCTO error response. Treat these as configuration or validation failures rather than automatically retrying them as transient failures.



