Product graph
Categories, Tags & Images
Categories
Categories organize products within a menu and can be nested one level deep (category > sub-category). Unlike products and steps, categories are addressed by their numeric categoryId.
GET/menus/{menuId}/categoriesList Categories
Retrieve all categories of a menu, with their sub-categories, products and product count. Only one of the has_no_children, no_subcategory and can_be_parent filters is applied per request (in that order of precedence).
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| menuId | integer | Yes | The unique identifier of the menu. |
| search | string | No | Filter categories by name (query parameter). |
| limit | integer | No | Pagination limit (query parameter). |
| offset | integer | No | Pagination offset (query parameter). |
| order | string | No | Sort order (query parameter). |
| has_no_children | string | No | Set to 1 to only return categories without sub-categories (query parameter). |
| no_subcategory | string | No | Set to 1 to only return top-level categories (query parameter). |
| can_be_parent | string | No | Set to 1 to only return categories that can receive sub-categories (query parameter). |
Response
{
"status": 200,
"code": "categories_succeed",
"data": [
{
"categoryId": 30085,
"menuId": 106477,
"name": "Burgers",
"position": 1,
"parentCategoryId": null,
"productCount": 12,
"products": [],
"subCategory": []
}
]
}Response Properties
Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.
| Property | Type | Example | Description |
|---|---|---|---|
| status | integer | 200 | HTTP status code returned by the API. |
| code | string | "categories_succeed" | Machine-readable application code for the result. |
| data | array | […] | Endpoint-specific response payload. |
| data[] | object | {…} | Endpoint-specific response payload. |
| data[].categoryId | integer | 30085 | Identifier of the category. |
| data[].menuId | integer | 106477 | Identifier of the menu. |
| data[].name | string | "Burgers" | The name value. |
| data[].position | integer | 1 | The position value. |
| data[].parentCategoryId | null | null | Identifier of the associated parent category. |
| data[].productCount | integer | 12 | The product count value. |
| data[].products | array | [] | List of products entries. |
| data[].subCategory | array | [] | List of sub category entries. |
GET/menus/{menuId}/categories/{categoryId}Get Category Details
Retrieve a single category with its products and sub-categories.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| menuId | integer | Yes | The unique identifier of the menu. |
| categoryId | integer | Yes | The unique identifier of the category. |
Response
{
"status": 200,
"data": {
"categoryId": 30085,
"menuId": 106477,
"name": "Burgers",
"position": 1,
"parentCategoryId": null,
"products": [
{
"productId": 464462,
"name": "Cheeseburger",
"price": 1200
}
],
"subCategory": []
}
}Response Properties
Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.
| Property | Type | Example | Description |
|---|---|---|---|
| status | integer | 200 | HTTP status code returned by the API. |
| data | object | {…} | Endpoint-specific response payload. |
| data.categoryId | integer | 30085 | Identifier of the category. |
| data.menuId | integer | 106477 | Identifier of the menu. |
| data.name | string | "Burgers" | The name value. |
| data.position | integer | 1 | The position value. |
| data.parentCategoryId | null | null | Identifier of the associated parent category. |
| data.products | array | […] | List of products entries. |
| data.products[] | object | {…} | Object containing products fields. |
| data.products[].productId | integer | 464462 | Identifier of the product. |
| data.products[].name | string | "Cheeseburger" | The name value. |
| data.products[].price | integer | 1200 | The price value. |
| data.subCategory | array | [] | List of sub category entries. |
POST/menus/{menuId}/categoriesCreate Category
Create a category in a menu. Only "name" is required. If "position" is omitted, the category is appended at the end (max position + 1). Use "parentCategoryId" to create a sub-category.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| menuId | integer | Yes | The unique identifier of the menu. |
Request Body
{
"name": "Desserts",
"description": "Sweet treats",
"position": 2,
"parentCategoryId": null,
"imageId": 1001
}Request Body Properties
Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.
| Property | Type | Example | Description |
|---|---|---|---|
| name | string | "Desserts" | The name value. |
| description | string | "Sweet treats" | The description value. |
| position | integer | 2 | The position value. |
| parentCategoryId | null | null | Identifier of the associated parent category. |
| imageId | integer | 1001 | Identifier of the associated image. |
Response
{
"status": 200,
"code": "category_creation_success",
"message": "The category has been created with success.",
"data": {
"categoryId": 30090,
"menuId": 106477,
"name": "Desserts",
"position": 2,
"parentCategoryId": null,
"imageId": 1001
}
}Response Properties
Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.
| Property | Type | Example | Description |
|---|---|---|---|
| status | integer | 200 | HTTP status code returned by the API. |
| code | string | "category_creation_success" | Machine-readable application code for the result. |
| message | string | "The category has been created with success." | Human-readable result message. Do not use this value for program logic. |
| data | object | {…} | Endpoint-specific response payload. |
| data.categoryId | integer | 30090 | Identifier of the category. |
| data.menuId | integer | 106477 | Identifier of the menu. |
| data.name | string | "Desserts" | The name value. |
| data.position | integer | 2 | The position value. |
| data.parentCategoryId | null | null | Identifier of the associated parent category. |
| data.imageId | integer | 1001 | Identifier of the associated image. |
Full Replacement
The products array of the update below is required and replaces the complete product list of the category: an empty array empties the category. To add products without listing the existing ones, use POST /menus/{menuId}/categories/{categoryId}/products instead.
PUT/menus/{menuId}/categories/{categoryId}Update Category
Update a category attributes AND replace the full list of its products. The "products" array is required and defines the exact products (with their position) contained in the category after the call - an empty array empties the category. This endpoint is also used to reorder products within a category. To add products without listing the existing ones, use POST /menus/{menuId}/categories/{categoryId}/products instead.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| menuId | integer | Yes | The unique identifier of the menu. |
| categoryId | integer | Yes | The unique identifier of the category. |
Request Body
{
"name": "Desserts & Pastries",
"description": "Sweet treats",
"position": 2,
"parentCategoryId": null,
"imageId": 1001,
"products": [
{
"productId": 464490,
"category_product": {
"position": 1
}
},
{
"productId": 464491,
"category_product": {
"position": 2
}
}
]
}Request Body Properties
Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.
| Property | Type | Example | Description |
|---|---|---|---|
| name | string | "Desserts & Pastries" | The name value. |
| description | string | "Sweet treats" | The description value. |
| position | integer | 2 | The position value. |
| parentCategoryId | null | null | Identifier of the associated parent category. |
| imageId | integer | 1001 | Identifier of the associated image. |
| products | array | […] | List of products entries. |
| products[] | object | {…} | Object containing products fields. |
| products[].productId | integer | 464490 | Identifier of the product. |
| products[].category_product | object | {…} | Object containing category product fields. |
| products[].category_product.position | integer | 1 | The position value. |
Response
{
"status": 200,
"code": "category_has_been_updated",
"message": "The category has been successfully updated",
"data": {
"categoryId": 30090,
"menuId": 106477,
"name": "Desserts & Pastries",
"products": [
{
"productId": 464490
},
{
"productId": 464491
}
],
"subCategory": []
}
}Response Properties
Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.
| Property | Type | Example | Description |
|---|---|---|---|
| status | integer | 200 | HTTP status code returned by the API. |
| code | string | "category_has_been_updated" | Machine-readable application code for the result. |
| message | string | "The category has been successfully updated" | Human-readable result message. Do not use this value for program logic. |
| data | object | {…} | Endpoint-specific response payload. |
| data.categoryId | integer | 30090 | Identifier of the category. |
| data.menuId | integer | 106477 | Identifier of the menu. |
| data.name | string | "Desserts & Pastries" | The name value. |
| data.products | array | […] | List of products entries. |
| data.products[] | object | {…} | Object containing products fields. |
| data.products[].productId | integer | 464490 | Identifier of the product. |
| data.subCategory | array | [] | List of sub category entries. |
POST/menus/{menuId}/categories/{categoryId}/productsAdd Products to Category
Add existing products of the menu to a category without affecting the products already linked to it.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| menuId | integer | Yes | The unique identifier of the menu. |
| categoryId | integer | Yes | The unique identifier of the category. |
Request Body
{
"productIds": [
464490,
464491
]
}Request Body Properties
Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.
| Property | Type | Example | Description |
|---|---|---|---|
| productIds | array | […] | List of product ids entries. |
| productIds[] | integer | 464490 | The product ids value. |
Response
{
"status": 200,
"code": "category_products_have_been_added",
"message": "Products have been successfully added to the category"
}Response Properties
Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.
| Property | Type | Example | Description |
|---|---|---|---|
| status | integer | 200 | HTTP status code returned by the API. |
| code | string | "category_products_have_been_added" | Machine-readable application code for the result. |
| message | string | "Products have been successfully added to the category" | Human-readable result message. Do not use this value for program logic. |
PUT/menus/{menuId}/categories/layoutReorder Category Tree
Reorganize the whole category tree in a single call by setting the position and parent of each category.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| menuId | integer | Yes | The unique identifier of the menu. |
Request Body
{
"layout": [
{
"categoryId": 30085,
"position": 1,
"parentCategoryId": null
},
{
"categoryId": 30090,
"position": 2,
"parentCategoryId": null
},
{
"categoryId": 30091,
"position": 1,
"parentCategoryId": 30090
}
]
}Request Body Properties
Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.
| Property | Type | Example | Description |
|---|---|---|---|
| layout | array | […] | List of layout entries. |
| layout[] | object | {…} | Object containing layout fields. |
| layout[].categoryId | integer | 30085 | Identifier of the category. |
| layout[].position | integer | 1 | The position value. |
| layout[].parentCategoryId | null | null | Identifier of the associated parent category. |
Response
{
"status": 200,
"code": "category_layout_updated"
}Response Properties
Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.
| Property | Type | Example | Description |
|---|---|---|---|
| status | integer | 200 | HTTP status code returned by the API. |
| code | string | "category_layout_updated" | Machine-readable application code for the result. |
DELETE/menus/{menuId}/categories/{categoryId}Delete Category
Remove a category from the menu.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| menuId | integer | Yes | The unique identifier of the menu. |
| categoryId | integer | Yes | The unique identifier of the category to delete. |
Response
{
"status": 200,
"code": "category_has_been_deleted"
}Response Properties
Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.
| Property | Type | Example | Description |
|---|---|---|---|
| status | integer | 200 | HTTP status code returned by the API. |
| code | string | "category_has_been_deleted" | Machine-readable application code for the result. |
CategoryAttributes
interface CategoryAttributes {
categoryId: number;
menuId: number;
name: string;
description: string | null;
position: number;
parentCategoryId: number | null; // For nested sub-categories
imageId: number | null;
webAvailability: boolean;
kioskAvailability: boolean;
}Tags
Tags allow for grouping products across categories, often used for reporting or printing rules.
GET/menus/{menuId}/tagsGet Tags
Retrieve tags for a specific menu.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| menuId | integer | Yes | The unique identifier of the menu. |
Response
{
"status": 201,
"code": "tags_succeed",
"message": "Tags have been successfully retrieved.",
"data": [
{
"tagId": 101,
"name": "Vegan",
"color": "#00ff00",
"brandId": 3325,
"posLocalId": null,
"is_enabled": true,
"created_at": "2026-07-11T10:00:00.000Z",
"updated_at": "2026-07-11T10:00:00.000Z"
}
]
}Response Properties
Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.
| Property | Type | Example | Description |
|---|---|---|---|
| status | integer | 201 | HTTP status code returned by the API. |
| code | string | "tags_succeed" | Machine-readable application code for the result. |
| message | string | "Tags have been successfully retrieved." | Human-readable result message. Do not use this value for program logic. |
| data | array | […] | Endpoint-specific response payload. |
| data[] | object | {…} | Endpoint-specific response payload. |
| data[].tagId | integer | 101 | Identifier of the associated tag. |
| data[].name | string | "Vegan" | The name value. |
| data[].color | string | "#00ff00" | The color value. |
| data[].brandId | integer | 3325 | Identifier of the brand. |
| data[].posLocalId | null | null | Identifier of the associated pos local. |
| data[].is_enabled | boolean | true | Whether enabled is enabled or applies. |
| data[].created_at | string | "2026-07-11T10:00:00.000Z" | Timestamp when this resource was created. |
| data[].updated_at | string | "2026-07-11T10:00:00.000Z" | Timestamp when this resource was last updated. |
POST/menus/{menuId}/tagsCreate Tag
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| menuId | integer | Yes | The unique identifier of the menu. |
Request Body
{
"name": "Gluten Free",
"color": "#ffff00",
"is_enabled": true
}Request Body Properties
Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.
| Property | Type | Example | Description |
|---|---|---|---|
| name | string | "Gluten Free" | The name value. |
| color | string | "#ffff00" | The color value. |
| is_enabled | boolean | true | Whether enabled is enabled or applies. |
Response
{
"status": 201,
"code": "tag_create_succeed",
"message": "Tag has been successfully created.",
"data": {
"tagId": 103,
"name": "Gluten Free",
"color": "#ffff00",
"brandId": 3325,
"posLocalId": null,
"is_enabled": true,
"created_at": "2026-07-11T10:00:00.000Z",
"updated_at": "2026-07-11T10:00:00.000Z"
}
}Response Properties
Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.
| Property | Type | Example | Description |
|---|---|---|---|
| status | integer | 201 | HTTP status code returned by the API. |
| code | string | "tag_create_succeed" | Machine-readable application code for the result. |
| message | string | "Tag has been successfully created." | Human-readable result message. Do not use this value for program logic. |
| data | object | {…} | Endpoint-specific response payload. |
| data.tagId | integer | 103 | Identifier of the associated tag. |
| data.name | string | "Gluten Free" | The name value. |
| data.color | string | "#ffff00" | The color value. |
| data.brandId | integer | 3325 | Identifier of the brand. |
| data.posLocalId | null | null | Identifier of the associated pos local. |
| data.is_enabled | boolean | true | Whether enabled is enabled or applies. |
| data.created_at | string | "2026-07-11T10:00:00.000Z" | Timestamp when this resource was created. |
| data.updated_at | string | "2026-07-11T10:00:00.000Z" | Timestamp when this resource was last updated. |
GET/menus/{menuId}/tags/{tagId}Get Tag Details
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| menuId | integer | Yes | Menu ID |
| tagId | integer | Yes | Tag ID |
Response
{
"status": 201,
"code": "tags_succeed",
"message": "Tags have been successfully retrieved.",
"data": {
"tagId": 101,
"name": "Vegan",
"color": "#00ff00",
"brandId": 3325,
"posLocalId": null,
"is_enabled": true,
"created_at": "2026-07-11T10:00:00.000Z",
"updated_at": "2026-07-11T10:00:00.000Z"
}
}Response Properties
Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.
| Property | Type | Example | Description |
|---|---|---|---|
| status | integer | 201 | HTTP status code returned by the API. |
| code | string | "tags_succeed" | Machine-readable application code for the result. |
| message | string | "Tags have been successfully retrieved." | Human-readable result message. Do not use this value for program logic. |
| data | object | {…} | Endpoint-specific response payload. |
| data.tagId | integer | 101 | Identifier of the associated tag. |
| data.name | string | "Vegan" | The name value. |
| data.color | string | "#00ff00" | The color value. |
| data.brandId | integer | 3325 | Identifier of the brand. |
| data.posLocalId | null | null | Identifier of the associated pos local. |
| data.is_enabled | boolean | true | Whether enabled is enabled or applies. |
| data.created_at | string | "2026-07-11T10:00:00.000Z" | Timestamp when this resource was created. |
| data.updated_at | string | "2026-07-11T10:00:00.000Z" | Timestamp when this resource was last updated. |
PUT/menus/{menuId}/tags/{tagId}Update Tag
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| menuId | integer | Yes | The unique identifier of the menu. |
| tagId | integer | Yes | The unique identifier of the tag. |
Request Body
{
"name": "Extra Spicy",
"color": "#8b0000"
}Request Body Properties
Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.
| Property | Type | Example | Description |
|---|---|---|---|
| name | string | "Extra Spicy" | The name value. |
| color | string | "#8b0000" | The color value. |
Response
{
"status": 200,
"code": "tag_update_succeed",
"message": "Tag has been successfully updated.",
"data": {
"tagId": 102,
"name": "Extra Spicy",
"color": "#8b0000",
"brandId": 3325,
"posLocalId": null,
"is_enabled": true,
"created_at": "2026-07-11T10:00:00.000Z",
"updated_at": "2026-07-11T10:01:00.000Z"
}
}Response Properties
Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.
| Property | Type | Example | Description |
|---|---|---|---|
| status | integer | 200 | HTTP status code returned by the API. |
| code | string | "tag_update_succeed" | Machine-readable application code for the result. |
| message | string | "Tag has been successfully updated." | Human-readable result message. Do not use this value for program logic. |
| data | object | {…} | Endpoint-specific response payload. |
| data.tagId | integer | 102 | Identifier of the associated tag. |
| data.name | string | "Extra Spicy" | The name value. |
| data.color | string | "#8b0000" | The color value. |
| data.brandId | integer | 3325 | Identifier of the brand. |
| data.posLocalId | null | null | Identifier of the associated pos local. |
| data.is_enabled | boolean | true | Whether enabled is enabled or applies. |
| data.created_at | string | "2026-07-11T10:00:00.000Z" | Timestamp when this resource was created. |
| data.updated_at | string | "2026-07-11T10:01:00.000Z" | Timestamp when this resource was last updated. |
DELETE/menus/{menuId}/tags/{tagId}Delete Tag
Soft-deletes the tag by disabling it. Products that already reference the tag are not deleted.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| menuId | integer | Yes | The unique identifier of the menu. |
| tagId | integer | Yes | The unique identifier of the tag. |
Response
{
"status": 200,
"code": "tag_delete_succeed",
"message": "Tag has been successfully deleted."
}Response Properties
Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.
| Property | Type | Example | Description |
|---|---|---|---|
| status | integer | 200 | HTTP status code returned by the API. |
| code | string | "tag_delete_succeed" | Machine-readable application code for the result. |
| message | string | "Tag has been successfully deleted." | Human-readable result message. Do not use this value for program logic. |
TagAttributes
interface TagAttributes {
tagId: number;
name: string;
color: string;
brandId?: number;
posLocalId?: number;
is_enabled: boolean;
created_at?: string;
updated_at?: string;
}Images
The Image Library allows you to manage assets for menus and products. Images can be scoped to a Brand (available to all restaurants) or a Restaurant (specific location).
Retrieve Images
GET/library/brand/{brandId}Get Brand Images
Retrieve all images available for the brand. Internal filesystem paths are omitted, and legacy filenames outside the public allowlist are canonicalized before being returned.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| brandId | integer | Yes | Brand ID |
| limit | integer | No | Pagination limit |
| offset | integer | No | Pagination offset |
Response
{
"status": 200,
"code": "images_succeed",
"message": "Image has been successfully retrieved.",
"data": [
{
"imageId": 1001,
"filename": "burger.jpg",
"originalFilename": "burger.jpg",
"fullUrl": "https://static.innovorder.fr/images/burger.jpg",
"size": 245120,
"mimeType": "image/jpeg",
"restaurantId": null,
"brandId": 3325,
"focalX": 50,
"focalY": 50,
"zoom": 100
}
]
}Response Properties
Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.
| Property | Type | Example | Description |
|---|---|---|---|
| status | integer | 200 | HTTP status code returned by the API. |
| code | string | "images_succeed" | Machine-readable application code for the result. |
| message | string | "Image has been successfully retrieved." | Human-readable result message. Do not use this value for program logic. |
| data | array | […] | Endpoint-specific response payload. |
| data[] | object | {…} | Endpoint-specific response payload. |
| data[].imageId | integer | 1001 | Identifier of the associated image. |
| data[].filename | string | "burger.jpg" | The filename value. |
| data[].originalFilename | string | "burger.jpg" | The original filename value. |
| data[].fullUrl | string | "https://static.innovorder.fr/images/burger.jpg" | The full url value. |
| data[].size | integer | 245120 | The size value. |
| data[].mimeType | string | "image/jpeg" | The mime type value. |
| data[].restaurantId | null | null | Identifier of the restaurant. |
| data[].brandId | integer | 3325 | Identifier of the brand. |
| data[].focalX | integer | 50 | The focal x value. |
| data[].focalY | integer | 50 | The focal y value. |
| data[].zoom | integer | 100 | The zoom value. |
GET/library/restaurant/{restaurantId}Get Restaurant Images
Retrieve images specific to a restaurant. Internal filesystem paths are omitted, and legacy filenames outside the public allowlist are canonicalized before being returned.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| restaurantId | integer | Yes | Restaurant ID |
Response
{
"status": 200,
"code": "images_succeed",
"message": "Image has been successfully retrieved.",
"data": [
{
"imageId": 2001,
"filename": "pizza.jpg",
"originalFilename": "pizza.jpg",
"fullUrl": "https://static.innovorder.fr/images/pizza.jpg",
"size": 245120,
"mimeType": "image/jpeg",
"restaurantId": 6801,
"brandId": 3325,
"focalX": 50,
"focalY": 50,
"zoom": 100
}
]
}Response Properties
Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.
| Property | Type | Example | Description |
|---|---|---|---|
| status | integer | 200 | HTTP status code returned by the API. |
| code | string | "images_succeed" | Machine-readable application code for the result. |
| message | string | "Image has been successfully retrieved." | Human-readable result message. Do not use this value for program logic. |
| data | array | […] | Endpoint-specific response payload. |
| data[] | object | {…} | Endpoint-specific response payload. |
| data[].imageId | integer | 2001 | Identifier of the associated image. |
| data[].filename | string | "pizza.jpg" | The filename value. |
| data[].originalFilename | string | "pizza.jpg" | The original filename value. |
| data[].fullUrl | string | "https://static.innovorder.fr/images/pizza.jpg" | The full url value. |
| data[].size | integer | 245120 | The size value. |
| data[].mimeType | string | "image/jpeg" | The mime type value. |
| data[].restaurantId | integer | 6801 | Identifier of the restaurant. |
| data[].brandId | integer | 3325 | Identifier of the brand. |
| data[].focalX | integer | 50 | The focal x value. |
| data[].focalY | integer | 50 | The focal y value. |
| data[].zoom | integer | 100 | The zoom value. |
GET/library/pos_devices/{posDeviceId}Get POS Device Image
Retrieves the image assigned to one POS device. Internal filesystem paths are omitted, and legacy filenames outside the public allowlist are canonicalized before being returned. The device must exist and have an image; otherwise the API returns a not-found error.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| posDeviceId | integer | Yes | POS device whose image is retrieved. |
Response
{
"status": 200,
"code": "images_succeed",
"message": "Image has been successfully retrieved",
"data": {
"imageId": 3001,
"filename": "pos-background.jpg",
"originalFilename": "pos-background.jpg",
"fullUrl": "https://static.innovorder.fr/images/pos-background.jpg",
"size": 245120,
"mimeType": "image/jpeg",
"restaurantId": null,
"brandId": 3325,
"posDeviceId": 8063,
"focalX": 50,
"focalY": 50,
"zoom": 100,
"created_at": "2026-07-11T09:00:00.000Z",
"updated_at": "2026-07-11T09:00:00.000Z",
"deleted_at": null
}
}Response Properties
Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.
| Property | Type | Example | Description |
|---|---|---|---|
| status | integer | 200 | HTTP status code returned by the API. |
| code | string | "images_succeed" | Machine-readable application code for the result. |
| message | string | "Image has been successfully retrieved" | Human-readable result message. Do not use this value for program logic. |
| data | object | {…} | Endpoint-specific response payload. |
| data.imageId | integer | 3001 | Identifier of the associated image. |
| data.filename | string | "pos-background.jpg" | The filename value. |
| data.originalFilename | string | "pos-background.jpg" | The original filename value. |
| data.fullUrl | string | "https://static.innovorder.fr/images/pos-background.jpg" | The full url value. |
| data.size | integer | 245120 | The size value. |
| data.mimeType | string | "image/jpeg" | The mime type value. |
| data.restaurantId | null | null | Identifier of the restaurant. |
| data.brandId | integer | 3325 | Identifier of the brand. |
| data.posDeviceId | integer | 8063 | Identifier of the associated pos device. |
| data.focalX | integer | 50 | The focal x value. |
| data.focalY | integer | 50 | The focal y value. |
| data.zoom | integer | 100 | The zoom value. |
| data.created_at | string | "2026-07-11T09:00:00.000Z" | Timestamp when this resource was created. |
| data.updated_at | string | "2026-07-11T09:00:00.000Z" | Timestamp when this resource was last updated. |
| data.deleted_at | null | null | Timestamp when this resource was deleted, or null when it is active. |
Upload Images
Creating an image is a multi-step process or handled via multipart/form-data.
POST/library/brand/{brandId}Upload Brand Image
Upload a new image file. Supports `?resize=true` query param. The original filename is trimmed, NFKC-normalized, limited to 255 characters, and canonicalized to Unicode letters and numbers, spaces, underscores, dots, and hyphens. Unsupported punctuation is replaced with underscores; a missing or empty name returns 400 invalid_parameters.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| brandId | integer | Yes | The unique identifier of the brand. |
| resize | string | No | Set to "true" to resize the image on upload. |
Request Body
Multipart Form Data: file=[binary]Request Body Properties
Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.
| Property | Type | Example | Description |
|---|---|---|---|
| file | binary | [binary] | Binary file uploaded in this multipart field. |
Response
{
"status": 201,
"code": "upload_image_succeed",
"message": "Image has been successfully added to the image bank.",
"data": {
"imageId": 1001,
"filename": "burger.jpg",
"originalFilename": "burger.jpg",
"fullUrl": "https://static.innovorder.fr/images/burger.jpg",
"size": 245120,
"mimeType": "image/jpeg",
"restaurantId": null,
"brandId": 3325,
"focalX": 50,
"focalY": 50,
"zoom": 100
}
}Response Properties
Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.
| Property | Type | Example | Description |
|---|---|---|---|
| status | integer | 201 | HTTP status code returned by the API. |
| code | string | "upload_image_succeed" | Machine-readable application code for the result. |
| message | string | "Image has been successfully added to the image bank." | Human-readable result message. Do not use this value for program logic. |
| data | object | {…} | Endpoint-specific response payload. |
| data.imageId | integer | 1001 | Identifier of the associated image. |
| data.filename | string | "burger.jpg" | The filename value. |
| data.originalFilename | string | "burger.jpg" | The original filename value. |
| data.fullUrl | string | "https://static.innovorder.fr/images/burger.jpg" | The full url value. |
| data.size | integer | 245120 | The size value. |
| data.mimeType | string | "image/jpeg" | The mime type value. |
| data.restaurantId | null | null | Identifier of the restaurant. |
| data.brandId | integer | 3325 | Identifier of the brand. |
| data.focalX | integer | 50 | The focal x value. |
| data.focalY | integer | 50 | The focal y value. |
| data.zoom | integer | 100 | The zoom value. |
POST/library/restaurant/{restaurantId}Upload Restaurant Image
Upload a media file (image or MP4 video) to a restaurant image library. Send the file as multipart/form-data in a field named "file" (required). The original filename is trimmed, NFKC-normalized, limited to 255 characters, and canonicalized to Unicode letters and numbers, spaces, underscores, dots, and hyphens. Unsupported punctuation is replaced with underscores; a missing or empty name returns 400 invalid_parameters. Accepted images: png, jpg, jpeg, gif, bmp - up to 30 MB (errors: file_extension_not_allowed, file_too_large). Accepted video: video/mp4 - up to 100 MB. Returns HTTP 201 with code "upload_image_succeed" for images or "upload_video_succeed" for videos.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| restaurantId | integer | Yes | Restaurant ID. |
| resize | string | No | Set to "true" to resize the image on upload, images only (query parameter). |
Request Body
Multipart Form Data: file=[binary]Request Body Properties
Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.
| Property | Type | Example | Description |
|---|---|---|---|
| file | binary | [binary] | Binary file uploaded in this multipart field. |
Response
{
"status": 201,
"code": "upload_image_succeed",
"message": "Image has been successfully added to the image bank.",
"data": {
"imageId": 2001,
"filename": "pizza.jpg",
"originalFilename": "pizza.jpg",
"fullUrl": "https://static.innovorder.fr/images/...",
"mimeType": "image/jpeg",
"size": 245120,
"focalX": 50,
"focalY": 50,
"brandId": 3325,
"restaurantId": 6801
}
}Response Properties
Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.
| Property | Type | Example | Description |
|---|---|---|---|
| status | integer | 201 | HTTP status code returned by the API. |
| code | string | "upload_image_succeed" | Machine-readable application code for the result. |
| message | string | "Image has been successfully added to the image bank." | Human-readable result message. Do not use this value for program logic. |
| data | object | {…} | Endpoint-specific response payload. |
| data.imageId | integer | 2001 | Identifier of the associated image. |
| data.filename | string | "pizza.jpg" | The filename value. |
| data.originalFilename | string | "pizza.jpg" | The original filename value. |
| data.fullUrl | string | "https://static.innovorder.fr/images/..." | The full url value. |
| data.mimeType | string | "image/jpeg" | The mime type value. |
| data.size | integer | 245120 | The size value. |
| data.focalX | integer | 50 | The focal x value. |
| data.focalY | integer | 50 | The focal y value. |
| data.brandId | integer | 3325 | Identifier of the brand. |
| data.restaurantId | integer | 6801 | Identifier of the restaurant. |
POST/library/pos_devices/{posDeviceId}Upload POS Device Image
Uploads or replaces the image assigned to a POS device. Send one image in the multipart field file. The original filename is trimmed, NFKC-normalized, limited to 255 characters, and canonicalized to Unicode letters and numbers, spaces, underscores, dots, and hyphens. Unsupported punctuation is replaced with underscores; a missing or empty name returns 400 invalid_parameters. The endpoint returns the normal success envelope without a data field.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| posDeviceId | integer | Yes | POS device that receives the image. |
Request Body
file=[binary]Request Body Properties
Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.
| Property | Type | Required | Example | Description |
|---|---|---|---|---|
| file | binary | Yes | [binary] | Image file to upload for the POS device. |
Response
{
"status": 200,
"code": "images_succeed",
"message": "Image has been successfully retrieved"
}Response Properties
Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.
| Property | Type | Example | Description |
|---|---|---|---|
| status | integer | 200 | HTTP status code returned by the API. |
| code | string | "images_succeed" | Machine-readable application code for the result. |
| message | string | "Image has been successfully retrieved" | Human-readable result message. Do not use this value for program logic. |
POST/library/restaurants/{restaurantId}/pos_devices/dual_screenUpload Dual-Screen Image to POS Devices
Uploads one image to a selected set of POS devices in the restaurant. The original filename is trimmed, NFKC-normalized, limited to 255 characters, and canonicalized to Unicode letters and numbers, spaces, underscores, dots, and hyphens; unsupported punctuation is replaced with underscores. The response is a chunked text/plain stream: progress lines are followed by the final JSON object. The request accepts a maximum 10-minute server timeout.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| restaurantId | integer | Yes | Restaurant that owns every selected POS device. |
Request Body
file=[binary]
posDeviceIds=[1,2,3]Request Body Properties
Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.
| Property | Type | Required | Example | Description |
|---|---|---|---|---|
| file | binary | Yes | [binary] | Image file uploaded once and applied to each selected POS device. |
| posDeviceIds | string | Yes | [1,2,3] | JSON-encoded array of integer POS device IDs, for example [8063,8064]. |
Response
HTTP 200 text/plain; charset=utf-8 with chunked progress lines. The final chunk is JSON: {"success":true} when every requested device succeeded, or {"success":false,"error":"..."} when the upload handler catches an error. A requested device outside the restaurant is reported in the stream and makes success false.Response Properties
Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.
| Property | Type | Required | Example | Description |
|---|---|---|---|---|
| HTTP 200 text/plain; charset | string | Not specified | utf-8 with chunked progress lines. The final chunk is JSON: {"success":true} when every requested device succeeded, or {"success":false,"error":"..."} when the upload handler catches an error. A requested device outside the restaurant is reported in the stream and makes success false. | The http 200 text/plain; charset value. |
| success | boolean | Yes | Not provided | Final JSON field: true only when every requested device received the image. |
| error | string | No | Not provided | Final JSON field supplied when the upload handler catches an error. |
Restaurant Upload Behavior
- The media is stored at the brand level of the restaurant (
brandIdis filled), withrestaurantIdset on the record to scope it to the restaurant. - Uploaded images are automatically tagged
"<restaurant name> Library"- the tag is created at brand level if it does not exist yet. Videos are not tagged. - This endpoint returns HTTP 201, not 200.
Manage Images
PUT/library/brand/{imageId}Update Image Metadata
Update attributes like filename or focal point.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| imageId | integer | Yes | The unique identifier of the brand-level image. |
Request Body
{
"filename": "burger_hd.jpg",
"focalX": 40,
"focalY": 60,
"zoom": 100,
"fullUrl": "https://static.innovorder.fr/images/burger_hd.jpg",
"size": 250000,
"mimeType": "image/jpeg"
}Request Body Properties
Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.
| Property | Type | Required | Example | Description |
|---|---|---|---|---|
| filename | string | Yes | "burger_hd.jpg" | New display filename (1-255 characters). Unicode letters and numbers, spaces, underscores, dots, and hyphens only; the value is trimmed and NFKC-normalized. |
| focalX | integer | No | 40 | Horizontal focal-point percentage. |
| focalY | integer | No | 60 | Vertical focal-point percentage. |
| zoom | integer | No | 100 | Zoom level used when rendering the image. |
| fullUrl | string | No | "https://static.innovorder.fr/images/burger_hd.jpg" | Replacement public URL, when explicitly managed by the caller. |
| size | integer | No | 250000 | Replacement file size in bytes, when explicitly managed by the caller. |
| mimeType | string | No | "image/jpeg" | Replacement MIME type, when explicitly managed by the caller. |
Response
{
"status": 201,
"code": "image_update_succeed",
"message": "Image has been successfully updated.",
"data": {
"imageId": 1001,
"filename": "burger_hd.jpg",
"originalFilename": "burger.jpg",
"fullUrl": "https://static.innovorder.fr/images/burger_hd.jpg",
"size": 250000,
"mimeType": "image/jpeg",
"restaurantId": null,
"brandId": 3325,
"focalX": 40,
"focalY": 60,
"zoom": 100
}
}Response Properties
Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.
| Property | Type | Example | Description |
|---|---|---|---|
| status | integer | 201 | HTTP status code returned by the API. |
| code | string | "image_update_succeed" | Machine-readable application code for the result. |
| message | string | "Image has been successfully updated." | Human-readable result message. Do not use this value for program logic. |
| data | object | {…} | Endpoint-specific response payload. |
| data.imageId | integer | 1001 | Identifier of the associated image. |
| data.filename | string | "burger_hd.jpg" | The filename value. |
| data.originalFilename | string | "burger.jpg" | The original filename value. |
| data.fullUrl | string | "https://static.innovorder.fr/images/burger_hd.jpg" | The full url value. |
| data.size | integer | 250000 | The size value. |
| data.mimeType | string | "image/jpeg" | The mime type value. |
| data.restaurantId | null | null | Identifier of the restaurant. |
| data.brandId | integer | 3325 | Identifier of the brand. |
| data.focalX | integer | 40 | The focal x value. |
| data.focalY | integer | 60 | The focal y value. |
| data.zoom | integer | 100 | The zoom value. |
DELETE/library/brand/{imageId}Delete Image
Permanently remove an image from the library.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| imageId | integer | Yes | The unique identifier of the brand-level image. |
Response
{
"status": 201,
"code": "image_delete_succeed",
"message": "The image has been successfully deleted."
}Response Properties
Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.
| Property | Type | Example | Description |
|---|---|---|---|
| status | integer | 201 | HTTP status code returned by the API. |
| code | string | "image_delete_succeed" | Machine-readable application code for the result. |
| message | string | "The image has been successfully deleted." | Human-readable result message. Do not use this value for program logic. |
PUT/library/restaurant/{imageId}Update Restaurant Image Metadata
Update the metadata of a restaurant library image: rename it or adjust its focal point and zoom. This endpoint does NOT replace the binary file - it accepts a JSON body only. The image must belong to a restaurant (restaurantId set), otherwise 400 invalid_parameters: brand-level images cannot be updated through this route. "filename" is required (400 missing_parameters otherwise); "focalX", "focalY" and "zoom" are optional integers.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| imageId | integer | Yes | The unique identifier of the image. |
Request Body
{
"filename": "pizza_hd.jpg",
"focalX": 40,
"focalY": 60,
"zoom": 100
}Request Body Properties
Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.
| Property | Type | Example | Description |
|---|---|---|---|
| filename | string | "pizza_hd.jpg" | The filename value. |
| focalX | integer | 40 | The focal x value. |
| focalY | integer | 60 | The focal y value. |
| zoom | integer | 100 | The zoom value. |
Response
{
"status": 201,
"code": "image_update_succeed",
"message": "Image has been successfully updated",
"data": {
"imageId": 2001,
"filename": "pizza_hd.jpg",
"fullUrl": "https://static.innovorder.fr/images/...",
"focalX": 40,
"focalY": 60,
"brandId": 3325,
"restaurantId": 6801
}
}Response Properties
Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.
| Property | Type | Example | Description |
|---|---|---|---|
| status | integer | 201 | HTTP status code returned by the API. |
| code | string | "image_update_succeed" | Machine-readable application code for the result. |
| message | string | "Image has been successfully updated" | Human-readable result message. Do not use this value for program logic. |
| data | object | {…} | Endpoint-specific response payload. |
| data.imageId | integer | 2001 | Identifier of the associated image. |
| data.filename | string | "pizza_hd.jpg" | The filename value. |
| data.fullUrl | string | "https://static.innovorder.fr/images/..." | The full url value. |
| data.focalX | integer | 40 | The focal x value. |
| data.focalY | integer | 60 | The focal y value. |
| data.brandId | integer | 3325 | Identifier of the brand. |
| data.restaurantId | integer | 6801 | Identifier of the restaurant. |
DELETE/library/restaurant/{imageId}Delete Restaurant Image
Delete an image from a restaurant library. This is a soft delete: the image disappears from listings but the underlying file is not removed from storage. The image must belong to a restaurant (restaurantId set), otherwise 400 invalid_parameters.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| imageId | integer | Yes | The unique identifier of the image to delete. |
Response
{
"status": 201,
"code": "image_delete_succeed",
"message": "the image has been successfully deleted"
}Response Properties
Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.
| Property | Type | Example | Description |
|---|---|---|---|
| status | integer | 201 | HTTP status code returned by the API. |
| code | string | "image_delete_succeed" | Machine-readable application code for the result. |
| message | string | "the image has been successfully deleted" | Human-readable result message. Do not use this value for program logic. |
Restaurant Library Gotchas
- The update and delete routes return HTTP 201 (historical behavior) - including the DELETE.
- If the
imageIddoes not exist, the API returns a 500 server error instead of a clean 404. Verify the ID first withGET /library/restaurant/{restaurantId}. - Deletion is a soft delete: the public file URL keeps being served, and existing references (products or categories pointing to the image) are not cleaned up.
ImageAttributes
interface ImageAttributes {
imageId: number;
filename: string | null;
originalFilename: string | null;
fullUrl: string;
size: number;
mimeType: string;
focalX: number;
focalY: number;
restaurantId: number | null;
brandId: number;
}