RazGazRazGaz
ENעברית

Integration guide for cashier systems

RazGazOrder Ingest API

The complete contract for pushing delivery orders from a cashier system into RazGaz. One call — there is nothing else to implement.

Version 1.0 · 2026-08-18POSTapi.raz-gaz.com/ingestOrder
Contents

1Overview

The cashier system sends RazGaz one HTTP request per delivery order. RazGaz prices the delivery, broadcasts it to nearby carriers, and manages the carrier from assignment through hand-over to the customer.

Base URLhttps://api.raz-gaz.com
CallAdd Order — POST /ingestOrder
TransportHTTPS only. POST, Content-Type: application/json, UTF-8
AuthenticationPer-cashier API key
IdempotencyBy your own order id

There is no status back-channel on this integration. RazGaz does not call the cashier system back, and there is no endpoint to poll for the state of a delivery or for carrier details. If the cashier system needs delivery status, say so before integrating — it is a separate contract, not a parameter of this one.


2What RazGaz issues you

Two things, both from RazGaz, before the first order:

What it isScope
API keyA secret string, format rg_live_ followed by 48 hexadecimal charactersOne key per cashier installation, whatever number of restaurants it sends for
Restaurant codeThe code that identifies one restaurant branch in your requests, sent as externalIdOne code per branch. It is your own identifier for the branch — RazGaz records it against the branch, so you do not have to adopt ours

The API key is shown once, at creation, and is not recoverable afterwards. Store it as a secret. Any key can be revoked by RazGaz at any time, after which every request presenting it is rejected with 401.


3Authentication

Present the key on every request, either way:

MethodWhere
Header (preferred)x-api-key: <key>
Query parameter?apiKey=<key>

If both are present, the header is used. A request with no key, an unknown key or a revoked key is answered 401 and nothing is recorded — no order is created, and RazGaz raises no internal alert. A 401 in production means the integration is silently delivering nothing, so treat it as a hard failure and escalate rather than retry indefinitely.


4Call: Add Order

POST /ingestOrder

4.1Request — required fields

Every field below must be present, and the four coordinate values must be JSON numbers, not strings. A request failing any of these is rejected with 400 and no order is created.

FieldTypeDescription
orderIdstringYour identifier for this order. Becomes the order's identity on the RazGaz side and is the idempotency key — see §6. Must be unique across every order this cashier installation sends, and stable across retries of the same order
externalIdstringThe restaurant code RazGaz issued you (§2), identifying which branch the order is collected from
pickupLocationobjectWhere the carrier collects. { "latitude": number, "longitude": number }
deliveryLocationobjectWhere the carrier delivers. { "latitude": number, "longitude": number }

Coordinates are mandatory and are never derived. This endpoint does not geocode: it does not convert a text address into coordinates, and it does not substitute the branch's stored position for a missing pickupLocation. A cashier system that cannot produce coordinates for both ends cannot use this integration.

4.2Request — optional fields

FieldTypeDescription
estimatedReadyMinutesintegerMinutes from now until the food is ready. Whole minutes, greater than 0 and no more than 240. Send it whenever the cashier knows it — see §7
deliveryAddressstringThe delivery address as one human-readable line. Not used for routing — the coordinates are — but it is what the carrier reads, so send the doorway detail here: floor, apartment, entrance
pickupAddressstringThe branch address as one human-readable line
customerNamestringThe customer's name, as the carrier should ask for them
customerPhonestringA dialable number for the customer. The carrier calls it on arrival
notesstringFree text shown to the carrier. Delivery instructions, gate codes, "leave at door"
itemsarrayThe order's line items. Each entry must be { "name": string, "qty": number }; RazGaz stores the array as sent and every screen reads exactly those two keys, so an entry naming its quantity anything other than qty displays as blank. May be omitted entirely — carriers do not need line items to deliver
orderAmountnumberWhat the customer pays for the order, in ILS
paymentMethodstring"cash" when the carrier must collect payment from the customer. Any other value, and the absence of the field, are recorded as "card" — meaning the carrier collects nothing
placedAtnumber | stringWhen the customer placed the order: epoch milliseconds, or an ISO-8601 timestamp. Omitted or unparseable, the time of the request is used

4.3Reserved fields — do not send

The endpoint accepts several further fields that belong to RazGaz's own operations. Sending them from a cashier system is not supported: they change what the carrier is paid and how the delivery is dispatched, and RazGaz does not validate them against the delivery.

estimatedPayout, broadcastRadius, platformOrderRef, regionId, restaurantId.

scheduledFor is likewise not part of this integration: it is stored on the first POST and has no effect, so an order sent with a future time is dispatched immediately, and a different time on a later POST of the same order is not stored. An order for later must not be sent until it is due.

restaurantName is accepted as a fallback for identifying the branch when externalId matches nothing, and it must then match RazGaz's own spelling of the name character for character. Do not rely on it: send externalId.

4.4Response

HTTPMeaning
201The order was created
200An order with this orderId already existed and was updated — see §6

Both answer with the same body:

FieldTypeDescription
successbooleantrue
orderIdstringThe orderId you sent, echoed
createdbooleantrue on 201, false on 200

Treat any 2xx as accepted. created: false is a normal, successful answer, not a duplicate error.

4.5Errors

HTTPBodyCauseWhat to do
400{ "error": "<reason>" }A required field of §4.1 is missing; a coordinate is not a number; estimatedReadyMinutes is not a positive number, or is greater than 240Fix the payload. Retrying it unchanged cannot succeed. RazGaz is alerted internally on every 400
401{ "error": "Invalid API key" }No key, unknown key, or revoked keyStop and escalate. No internal alert is raised, so RazGaz will not notice for you
405{ "error": "<reason>" }The request was not a POSTFix the method
500{ "error": "<reason>" }A fault on the RazGaz sideRetry. RazGaz is alerted internally on every 500

A network timeout with no response is indistinguishable from a 500 and should be handled the same way: retry. Retrying is always safe — see §6.


5Identifying the restaurant

Send externalId on every order. RazGaz holds your code for each branch against that branch, keyed to your API key, so:

  • your codes need no relation to RazGaz's own identifiers or naming;
  • two cashier systems may use different codes for the same branch without interfering;
  • a branch you have not been issued a code for is not integrated yet. An order carrying an unknown code is still accepted with 201 — it simply arrives attached to no restaurant, and RazGaz raises no alert. This is the failure mode to watch for on the first order from each new branch: the request looks entirely successful.

If your API key is ever rotated, the branch codes must be re-registered against the new key before it is used. Coordinate a rotation with RazGaz; do not switch keys unilaterally.


6Idempotency and retries

The orderId you send is the order's identity on the RazGaz side. A second request carrying an orderId already known is an update, never a second delivery.

An update rewrites the order details you own — both addresses and both coordinate pairs, customer name and phone, line items, amount, payment method, notes, prep time, placed-at time — and leaves the delivery itself alone: assignment to a carrier, the state of the delivery, and every timestamp of its progress are never touched by an incoming request. A prep time the kitchen has already answered for itself is also preserved.

Consequences for the cashier system:

  • Retrying is always safe, at any interval, for as long as needed. No retry can create a second delivery or disturb one in progress.
  • A correction is sent the same way: re-send the whole order with the same orderId and the corrected values. Partial payloads are not supported — a field left out of the retry is written as empty, not left as it was.
  • A correction is applied to the order whatever state it is in, but a delivery already under way is being driven by a person. Phone RazGaz as well, rather than assuming the carrier has seen the change.

Cancellation is not part of this integration. To cancel an order already sent, contact RazGaz.


7Prep time

estimatedReadyMinutes tells RazGaz when the food will be ready, and it is the single most useful optional field: it is what lets RazGaz time the carrier's arrival to the kitchen rather than send them to stand at a counter.

When it is absent, RazGaz falls back to what it knows about the branch:

  • a branch with an average prep time recorded uses that average;
  • a branch with no average dispatches with no ready time at all;
  • a branch configured to give a time per order holds the delivery, undispatched, until a person in that kitchen answers. Nothing releases it automatically.

That last case is why a cashier system that knows its own kitchen should always send the field: it removes a manual step that otherwise delays every order.


8Before going live

  1. RazGaz has issued the API key and one restaurant code per branch.
  2. Every branch's coordinates are correct in the cashier system, and every order carries them as numbers.
  3. One real order per branch has been sent and confirmed — with RazGaz — to have arrived attached to the right restaurant. §5 explains why the HTTP response alone does not confirm this.
  4. estimatedReadyMinutes is being sent if the cashier system can produce it.
  5. Retries on 500 and on timeout are implemented; 400 and 401 are not retried blindly but surfaced to whoever can act on them.