Cafe (Digital Menus)
The Cafe API powers digital menus: a cafe has groups and categories, and categories contain menu items. These endpoints are available on all plans.
Scopes: reads require cafe.read, creating a cafe requires cafe.create, deleting a
cafe requires cafe.delete, and all other writes (profile, theme, groups,
categories, items) require cafe.update.
:::note Multipart uploads
Endpoints that accept images — cafe profile (logo/cover), group images, category
images, and item images — expect multipart/form-data rather than JSON. The JSON
examples below are for the non-image endpoints.
:::
Cafes
| Method & path | Scope | Description |
|---|---|---|
GET /cafes | cafe.read | List cafes. |
GET /cafes/:id | cafe.read | Get one cafe. |
POST /cafes | cafe.create | Create a cafe. |
PUT /cafes/:id | cafe.update | Update a cafe. |
PUT /cafes/:id/profile | cafe.update | Update profile (multipart: logo, cover). |
PUT /cafes/:id/theme | cafe.update | Update theme/colors. |
DELETE /cafes/:id | cafe.delete | Delete a cafe. |
Create a cafe
| Field | Type | Required | Notes |
|---|---|---|---|
name | string | yes | Max 255 chars. |
description | string | no | Max 2000 chars. |
type | string | no |
curl -X POST https://api.prolinksqr.com/cafes \
-H "Authorization: Basic key-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{ "name": "Downtown Cafe", "description": "Specialty coffee & brunch" }'
Update theme
| Field | Type | Required | Notes |
|---|---|---|---|
themeImage | string | yes | A supported theme key (e.g. modern, coffee, brunch). |
primaryColor, secondaryColor | string | no | |
showDietarySection | boolean | no |
Groups
| Method & path | Scope | Description |
|---|---|---|
GET /cafes/:id/groups | cafe.read | List groups. |
GET /cafes/:id/groups/:groupId | cafe.read | Get one group. |
POST /cafes/:id/groups | cafe.update | Create a group (multipart: optional image). |
PUT /cafes/:id/groups/:groupId | cafe.update | Update a group (multipart: optional image). |
DELETE /cafes/:id/groups/:groupId | cafe.delete | Delete a group. |
PATCH /cafes/:id/groups/reorder | cafe.update | Reorder groups. |
Create a group
| Field | Type | Required | Notes |
|---|---|---|---|
name | string | yes | Max 255 chars. |
visible | boolean | no | Defaults to true. |
order | integer | no |
Reorder groups
{ "orders": [{ "id": "<groupId>", "order": 0 }, { "id": "<groupId>", "order": 1 }] }
Categories
| Method & path | Scope | Description |
|---|---|---|
GET /cafes/:id/categories | cafe.read | List categories. |
GET /cafes/:id/categories/:categoryId | cafe.read | Get one category. |
POST /cafes/:id/categories | cafe.update | Create a category. |
PUT /cafes/:id/categories/:categoryId | cafe.update | Update a category. |
PUT /cafes/:id/categories/:categoryId/image | cafe.update | Set category image (multipart: image). |
DELETE /cafes/:id/categories/:categoryId | cafe.update | Delete a category. |
PATCH /cafes/:id/categories/reorder | cafe.update | Reorder categories. |
Create a category
| Field | Type | Required | Notes |
|---|---|---|---|
name | string | yes | Max 255 chars. |
description | string | no | Max 1000 chars. |
group_id | string (UUID) | no | Assign to a group. |
type | string | no | |
order | integer | no | |
visible | boolean | no | Defaults to true. |
curl -X POST https://api.prolinksqr.com/cafes/<cafeId>/categories \
-H "Authorization: Basic key-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{ "name": "Hot Drinks", "visible": true }'
Menu items
| Method & path | Scope | Description |
|---|---|---|
GET /cafes/:id/items | cafe.read | List items. |
GET /cafes/:id/items/:itemId | cafe.read | Get one item. |
POST /cafes/:id/items | cafe.update | Create an item (multipart: optional image). |
POST /cafes/:id/items/bulk-insert | cafe.update | Bulk insert items (JSON). |
PUT /cafes/:id/items/:itemId | cafe.update | Update an item (multipart: optional image). |
DELETE /cafes/:id/items/:itemId | cafe.update | Delete an item. |
POST /cafes/:id/items/:itemId/hide | cafe.update | Hide an item. |
POST /cafes/:id/items/:itemId/show | cafe.update | Show an item. |
PATCH /cafes/:id/items/reorder | cafe.update | Reorder items. |
Create an item
Sent as multipart/form-data (so an image file can be attached). Fields:
| Field | Type | Required | Notes |
|---|---|---|---|
category_id | string (UUID) | yes | The category this item belongs to. |
name | string | yes | Max 255 chars. |
price | number | yes | ≥ 0. |
currency | string | no | ISO code (e.g. USD, EUR). Defaults to USD. |
description | string | no | Max 2000 chars. |
visible, is_featured, is_new, is_recommended | boolean | no | |
spice_level | string | no | One of none, mild, medium, hot, extra_hot. |
ingredients, tags, allergens | string | no | |
image | file | no | Image upload. |
curl -X POST https://api.prolinksqr.com/cafes/<cafeId>/items \
-H "Authorization: Basic key-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-F "category_id=<categoryId>" \
-F "name=Cappuccino" \
-F "price=4.50" \
-F "currency=USD" \
-F "image=@cappuccino.jpg"
Bulk insert items
JSON body with an items array (1–5000 items):
| Field | Type | Required | Notes |
|---|---|---|---|
name | string | yes | |
price | number | yes | ≥ 0. |
currency | string | yes | ISO code. |
category | string | yes | Category name (lowercased). |
group | string | no | Group name. |
description | string | no | |
ingredients | array | no | Array of strings. |
curl -X POST https://api.prolinksqr.com/cafes/<cafeId>/items/bulk-insert \
-H "Authorization: Basic key-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"items": [
{ "name": "Espresso", "price": 3.0, "currency": "USD", "category": "hot drinks" },
{ "name": "Latte", "price": 4.5, "currency": "USD", "category": "hot drinks" }
]
}'