Skip to content

Grocy Integration

Björn Strausmann edited this page May 10, 2026 · 1 revision

Grocy Integration

Print product, storage, and chore labels from Grocy — both interactively and automatically when Grocy triggers a print.

Status: design specification. Implementation tracked in issue #16.

How it works

Grocy supports both pull and push:

  • Pull: open the hub UI, scan a product barcode in the Grocy tab, label is printed
  • Push: Grocy sends a label-print webhook to the hub when you click a print action in Grocy → label prints automatically
PULL MODE                                            PUSH MODE
─────────                                            ─────────
You / phone        Hub          Grocy                Grocy             Hub                  Printer
─────────────      ───          ─────                ─────             ───                  ───────
1. Hub UI ────────►
2. Switch to Grocy tab
3. Scan barcode ──► /api/lookup/grocy/<barcode>
                       ─────► GET /api/objects/products
                              ?query=barcode
                       ◄───── product
                   ◄── LabelData
4. Click Print ───► /api/print/<printer>
                                                     1. User clicks a print action in Grocy
                                                     2. Grocy → POST hub webhook  ──►  /api/webhook/grocy
                                                                                       ──► render layout + queue + print
                                                                                       ──► 200 OK

Enabling label printing in Grocy

Grocy ships with label printing disabled by default. You have to enable the feature flag in your data/config.php:

Setting('FEATURE_FLAG_LABEL_PRINTING', true);

After restart, the Print label action appears on supported entities (products, stock entries, batteries, etc.) and on the External services settings page.

If the print action isn't visible in your Grocy, check the feature flag. The hub's webhook endpoint won't be called until Grocy itself believes label printing is on.

What gets on the label

Per ADR 0012, every label is rendered through a layout — a saved recipe. Choose a default per (integration, tape_mm), override per print job if needed.

Available Grocy fields you can put on a layout:

Field path Example value Source
title "Tomatoes (canned)" product name
primary_id "4006381333931" product barcode (or product ID if no barcode)
qr_payload https://<your-host>/product/<id> hub-built URL
secondary[0] best-before date from stock entry
secondary[1] location name from stock
extras.unit unit of measure product unit
extras.amount stock amount from stock
extras.due_date best-before date parsed

Seed layouts shipped:

  • grocy-product-12mm (default for 12mm) — QR + name + barcode
  • grocy-product-24mm (default for 24mm) — QR + name + barcode + best-before
  • grocy-location-12mm — QR + location name (for storage labels)
  • grocy-location-24mm — QR + location name + description

Create your own via POST /api/layouts — see the API reference at /redoc on a running hub.

Setup — pull mode

1. Create a Grocy API key

In Grocy:

  1. Manage API keys (/api/manageapikeys)
  2. Click Add → name it label-printer-hub
  3. Copy the key

2. Configure the hub

In .env:

GROCY_URL=https://grocy.example.com
GROCY_API_KEY=<your-key>

Restart backend.

3. Verify

Hub UI → switch to Grocy tab → scan a product barcode → see preview in 1-2 s.

Setup — push mode (webhook)

This adds automatic printing triggered from Grocy.

1. Set the webhook API key

The hub uses WEBHOOK_API_KEY (already set in your .env if you followed Getting Started). Make sure it's a strong random value:

openssl rand -hex 32

2. Configure Grocy

In Grocy → SettingsExternal servicesLabel printer (only visible when FEATURE_FLAG_LABEL_PRINTING=true):

Field Value
Label printer webhook URL https://<your-host>/api/webhook/grocy
Label printer params { "X-API-Key": "<your-WEBHOOK_API_KEY>" }
Run server (leave empty)

Save.

3. Verify push mode

Open any product in Grocy → click Print label. The hub UI should show a new job in the printer's queue within 1-2 s, then print and announce completion via SSE / browser notification.

Selecting which layout the webhook uses

By default the hub picks the integration's default layout for the tape size in DEFAULT_TAPE_PT_SERIES / DEFAULT_TAPE_QL_SERIES. To override per-print, the webhook payload may include a layout_id field:

{
  "product_id": 42,
  "layout_id": "grocy-product-with-best-before-24mm"
}

Whether you can add this field from Grocy depends on Grocy's webhook payload customisation — at the time of writing Grocy sends a fixed payload. The hub-side default-layout flow handles this for you.

Limitations

  • Grocy must have FEATURE_FLAG_LABEL_PRINTING=true (Grocy default is off)
  • Bulk-print of all products — out of scope for MVP
  • Grocy doesn't expose tape size in the webhook — the hub uses your default tape size from .env

Troubleshooting

Symptom Likely cause Fix
Print label action missing in Grocy Feature flag not set Add Setting('FEATURE_FLAG_LABEL_PRINTING', true); to Grocy data/config.php and restart Grocy
401 on webhook API key mismatch Verify X-API-Key in Grocy matches WEBHOOK_API_KEY in hub .env
Webhook 200 but nothing printed Job queued but worker stuck Check printer status page; ensure printer reachable
Hub never receives the webhook Grocy can't reach the hub URL From the Grocy host: curl https://<your-host>/healthz
Wrong layout chosen Default doesn't match the product type Set a different layout as default for (grocy, <tape_mm>) via the hub UI / API
Webhook URL has SSO wall Pangolin/Authelia is blocking it The webhook subroute (/api/webhook/) must bypass auth — see compose.traefik.yml / compose.pangolin.yml for the configured exception

See also