Skip to content

External Order API

The External Order API accepts a fully-formed order from any external system — a delivery aggregator, a white-label app, a kiosk, a voice agent — and routes it into the running APRO POS at the target location. A single POST is enough; the order appears on the order-manager screen immediately.

  • Endpoint: POST https://my.apro.at/api/v1/external/order
  • Auth: API key in x-api-key
  • Content type: application/json

Routing the order to a location

The order must be addressable to one concrete location. Provide one of the following — the first that is non-null wins:

  1. LocationID — numeric ID
  2. LocationShortCode — short string identifier (e.g. vienna-main)
  3. SpotID — a specific table/room/pickup spot (location is derived)
  4. QRCode — a scanned APRO QR code (location and spot are derived)

If none is provided, the request is rejected.

Request body

FieldTypeRequiredDescription
guidstringIdempotency key. If the same guid arrives twice, the duplicate is silently dropped.
locationIdint?◻︎See routing above.
locationShortCodestring◻︎See routing above.
spotIdint?ID of the target spot (table, room, pickup/delivery).
spotNumberint?Spot number, when ID is unknown.
userInfoUserInfoWho placed the order. email is required.
deliveryInfoDeliveryInfoDelivery address. Required for home delivery.
takeawaybooltrue for takeaway, false for dine-in.
notestringFree-form note from the guest (allergens, special requests).
qrCodestringSee routing.
entriesEntry[]Ordered items.
preOrderTimelong?Pre-order slot, Unix time in milliseconds UTC.
shortCodestringPickup / delivery reference (e.g. zw1356).
tipdecimal?Tip amount.
isPaidbooltrue if the order has already been paid externally.
grandTotaldecimal?Total of all entries + tip. Used to validate against server-side pricing.

Entry

FieldTypeRequiredDescription
productNrstringProduct number in APRO.
namestringDisplay name — informational only; APRO trusts productNr.
preOrderTimelong?Per-item pre-order slot.
quantitydoubleQuantity ordered.
pricedouble?Override the system price for this line (discounts, campaigns).
notestringItem-level note (e.g. Ohne Zwiebeln).
addonsAddon[]Add-on selections.

Addon

FieldTypeRequiredDescription
productNrstringProduct number of the add-on.
namestringDisplay name.
quantitydoubleQuantity.
pricedouble?Override the system price.

UserInfo

FieldTypeRequiredDescription
firstNamestring
lastNamestring
emailstringContact email for receipts and status updates.
phonestring
localestringIETF locale, e.g. de-DE.
nicknamestringShort name shown at pickup.

DeliveryInfo

FieldTypeDescription
namestringRecipient label.
companyNamestring
citystring
zipstring
streetstring
countrystring
floorstring
stairwaystring
doorstring
notestringDelivery instructions.

Examples

Minimal order

POST /api/v1/external/order
{
"locationShortCode": "vienna-main",
"takeaway": true,
"userInfo": { "email": "guest@example.com" },
"entries": [{ "productNr": "123", "quantity": 1 }],
"grandTotal": 9.99
}

Download: external-order-minimal.json

Full order with delivery and add-ons

POST /api/v1/external/order
{
"guid": "123e4567-e89b-12d3-a456-426614174000",
"locationId": 101,
"spotId": 15,
"spotNumber": 10,
"shortCode": "zw1356",
"userInfo": {
"firstName": "Max",
"lastName": "Mustermann",
"email": "max.mustermann@example.com",
"phone": "+491234567890",
"locale": "de-DE",
"nickname": "Max"
},
"takeaway": false,
"note": "Bitte schnell liefern",
"qrCode": "QR1234567890",
"deliveryInfo": {
"name": "Max Mustermann",
"city": "Wien",
"zip": "1010",
"street": "Stephansplatz 1",
"country": "AT",
"floor": "3",
"stairway": "A",
"door": "12"
},
"entries": [
{
"productNr": "123",
"name": "Wiener Schnitzel",
"quantity": 2,
"price": 9.99,
"note": "Extra scharf",
"addons": [
{ "productNr": "501", "name": "Pommes", "quantity": 2, "price": 3.5 }
]
},
{ "productNr": "31231", "name": "Burger Classic", "quantity": 1, "note": "Ohne Zwiebeln" }
],
"preOrderTime": 1723574400000,
"tip": 1.2,
"isPaid": true,
"grandTotal": 28.18
}

Download: external-order-full.json

Idempotency

Always set guid to a stable, client-generated UUID. APRO uses it to deduplicate retries — if a response is lost in transit and you retry, the second POST is a no-op and returns success.

Pricing

APRO re-prices every line server-side from productNr. price on an entry or add-on only takes effect when explicitly passed; grandTotal is checked against the server total and an inconsistent payload is rejected. Use it both as a safety net and as a mechanism to pass through campaign-specific discounts.