Orders

Orders are also sometimes called sales or invoices.

The Orders endpoint will return orders in all statuses by default. This includes both in-progress orders on the POS (i.e. statuses SUBMITTED, ON_HOLD, PENDING, ACCEPTED, REJECTED), as well as completed sales (where status is COMPLETE).

If you are only interested in completed sales, then ensure you set the correct filter in the path, i.e. /orders/complete.json

Get orders

Use this endpoint to retrieve orders and sales history.

GET /v1/companies/5678/orders/complete Get all complete orders1
GET /v1/companies/5678/orders/complete ?created_gt=2019-03-01 Get all completed orders created after a given date2
GET /v1/companies/5678/orders/complete ?created_lt=2019-03-01 Get all completed orders created before a given date2
GET /v1/companies/5678/orders/complete ?created_gte=2019-03-01T14:00:00Z Get all completed orders created on or after a given datetime3
GET /v1/companies/5678/orders/complete ?created_lte=2019-03-01T14:00:00Z Get all completed orders created on or before a given datetime3
GET /v1/companies/5678/orders/complete ?created_lte=2019-03-01T14:00:00Z&created_gte=2019-02-25T13:00:00Z Get all completed orders between the given datetimes3
GET /v1/companies/5678/orders ?value_lt=100 Get all orders worth less than $1001
GET /v1/companies/5678/orders/pending/accounts Get all pending account sales
GET /v1/companies/5678/orders/discounted Get all discounted orders
GET /v1/companies/5678/orders/deleted Get all orders deleted from the POS
GET /v1/companies/5678/orders/linkedcustomer Get all orders where a customer is attached
GET /v1/companies/5678/customers/4289/orders Get all orders for a given customer
GET /v1/companies/5678/sites/823/orders Get all orders for a given site
GET /v1/companies/5678/registers/16/orders Get all orders for a given register
GET /v1/companies/5678/staff/732846/orders Get all orders created by a given staff member
GET /v1/companies/5678/sites/823/registers/16/staff/732846/customers/4289/orders/complete/discounted ?created_gte=2013-06-01&value_lt=100 Combination of above filters

All the variations of the orders endpoint above act as filters, which can be combined indiscriminately. For example, /v1/companies/5678/orders/sites/823/staff/732846 will filter by site and staff member.s

The id_str is the string representation of the id field, which is a 64-bit integer. You should use this instead of the id field, as some programming languages have difficulty in interpreting 64-bit integers.

  • For limiting by creation date and value, you can use created_ or value_ with suffixes of
    • lt (less than)
    • lte (less than or equal to)
    • gt (greater than)
    • gte (greater than or equal to)
  • combine multiple filters to specify ranges, e.g. /v1/companies/5678/orders ?value_gte=50&value_lt=100 for values $50–$99.99 (or whatever currency is in use by the site). The order_type attribute will not be visible if its value is empty or not specified.
  • 1. Filter by order status by including the order status in lower case. See the Update an order action for a complete list of order status codes
  • 2. Dates specified without times will have times inferred based on the given sign. For example, created_gt=2019-03-01 becomes 2019-03-01T23:59:59Z
  • 3. The datetime specified must be in ISO8601 format.

Get an order

GET /v1/companies/5678/orders/93824701 Get an order by ID
GET /v1/companies/5678/orders/saleid/tj4ds8n3 Get an order by Sale ID
  • saleid is the 8 character ID printed on receipt.
  • There is no precedence between order-level and line-level price variation. They simply multiply their respective subtotals. For example, to apply a 5% discount on a line, you would specify a price_variation value of 0.95 on that line. It will be equal to 1 if there's no adjustments.
  • The price_fixed_variation will have a value if there is a fixed currency based discount. For example, a value of -2.00 means a $2.00 discount. It will be a positive value if order has surcharge and will be 0 if no adjustments.
  • line_total_ex_tax in the order line is the final line price including all price variations from both line level and order level.
  • Because completed orders are immutable, they are returned without some of the transient information included in incomplete orders (callback_uri, lock etc).
  • The options attribute contains any option sets in this order. See the Update an order
  • The order_type attribute will not be visible if its value is empty or not specified.
  • Line item product information will contain a sku key when set on a product.
  • The group_id represents a unique group or orders, such as multiple orders seated at the same table. See https://support.kounta.com/hc/en-us/articles/360001716176-Group-Ordering. Note: this ID may not be globally unique, but should be unique per site in the last 48hrs.
  • The course_ordinal is the numerical order of a course, e.g. 1 for Entree, 2 for Mains
  • The course_status is the current status of a course where line is added. Possible values are no status, uncalled, pending or called

Tip/Service

  • A tip/service charge may be applied to an order on POS. This amount will be expected to be applied as part of full payment on the order.
  • tip_service_paid: the total amount already paid towards the tip/service.
  • Only one of the following fields may be present:
  • tip_service_percent: when tip/service is applied as a percentage. A 12.5% tip/service fee will look like "tip_service_percent": 12.5
  • tip_service_amount: when tip/service is applied as an amount. A $2.45 tip/service fee will look like "tip_service_amount": 2.45

Get PDF invoice

GET /v1/companies/5678/orders/947891/pdf Get a PDF invoice of an order
  • Orders must be in COMPLETE status, else an HTTP 400 error will be returned.
  • The response will be PDF data with application/pdf headers.

Create an order

POST /v1/companies/5678/orders Submit a new order
  • Orders cannot be created with status ACCEPTED. If status is omitted, SUBMITTED will be assumed. See the Update an order action for a list of valid order statuses.
  • If you include a callback_uri, Kounta by Lightspeed will POST the order to it whenever the order's status changes. To test the callback, change an order’s status (see Update an order).
  • Orders are posted to callback_uri as JSON.
  • Add line modifiers as an array of product IDs. You can include the same ID more than once. To negate a modifier (e.g. No Sugar), change the sign of the ID to negative. In the example above, product 3091 will be marked as a negator.
  • unit_price should be specified as an ex tax price.
  • When you omit a line’s unit_price, it will then use unit_price_inc_tax if available.
  • If both unit_price and unit_price_inc_tax are omitted, the order’s site’s price for the line’s product will be used instead.
  • Use price_variation for percentage based discounts and surcharges. The value works as a coefficient of the order's subtotal. For example, 0.9 means a 10% discount, and 1.15 means a 15% surcharge.
  • Use price_fixed_variation for fixed currency based discounts and surcharges. For example, -2.00 means a $2.00 discount, and 1.15 means a $1.15 surcharge.
  • price_variation and price_fixed_variation cannot both be specified on an order-level.
  • Include a price_limit to prevent POS operators from modifying an order beyond a given payable amount. Price limits can be useful if you've taken a pre-payment or pre-authorization on a company's behalf.
  • If you want to send an order to a specific register, include a register_id instead of a site_id.
  • By default, and order’s status is changed to COMPLETE when it’s paid. Set complete_when_paid to false if you want to use the COMPLETE status as a delivery notification. The POS operator will manually mark the order as completed when it’s delivered.
  • Orders created in a SUBMITTED status will trigger an alert sound on the POS to notify the merchant of a new order.
    If you want to disable this sound from playing you can set enable_alert_sound to false.
  • order_type can be specified as one of Dine in, Takeaway, Pickup, Delivery, Catering or Drive Thru.
  • prompt_for_reject_reason can be set to true if you wish to have the merchant prompted for a reason when they reject a SUBMITTED order. The reject_reason will be returned in the order webhook payload, like this: "reject_reason": [ "id": 1, "name": "Sold Out", "notes": "Sorry some products you chose are sold out" ] .
  • pass_thru_printing can be set to true if this is a pass-thru-printing order, allowing items to print directly to the kitchen.

Use lock to prevent the POS operators from modifying parts of the order you’ve created. Possible flags include:

  • NEW_LINES - They won't be able to add their own lines.
  • PAYMENTS - They won’t be able to add any payments.
  • APP_PAYMENT - They will only be able to add your add-on's payment.
  • DELETE - They won’t be able to delete your order.
  • ALL - All of the above. They won't be able to edit your order.

Create an order with product availability

  • If an order was created with the order status ON_HOLD, PENDING, or COMPLETE and the order has any line item with invalid product availability, the request will be rejected with HTTP 400 and the following response: "error_description": "Product (199547) is out of stock."

Idempotency Headers

The Create Order endpoint supports idempotency allowing you to safely retry requests without accidentally performing the same operation twice. This is useful when an API call is disrupted in transit and you do not receive a response. For example, if a request to create an order does not respond due to a network connection error, you can retry the request with the same idempotency key to guarantee that a duplicate order is not created.

To perform an idempotent request, provide an Idempotency-Key header to the request. See The Idempotency HTTP Header Field for more details.

The idempotency works by saving the resulting status code and response of the first request made for any given idempotency key, regardless of whether it succeeded or failed. Subsequent requests with the same key return the same result, including 500 errors.

An idempotency key is a unique value generated by the client which the server uses to recognize subsequent retries of the same request. How you create unique keys is up to you, but we suggest using V4 UUIDs, or another random string with enough entropy to avoid collisions. Idempotency keys can be up to 255 characters long, and must match the regex [a-zA-Z0-9-]{1,255}. Idempotency keys will expire from the system automatically after they're at least 24 hours old.

The following errors may be returned on idempotent requests:

  • 400 Invalid Idempotency-Key Header if the header value is invalid.
  • 409 Conflict Idempotency-Key Header if there is already another request with the same header value still under processing. Generally you should retry when it happens.
  • 422 Used Idempotency-Key Header if the client tries to reuse the same header value with different request payloads. Generally you should create a new header value after receiving this error.

All fields are optional, but you must include either register_id or site_id. You can, as an alternative, create a blank order and add lines and payments in subsequent requests:

POST /v1/companies/5678/orders Create a blank order

Create with Option Sets

If options are provided the order will be created with the provided option sets. Option sets can be nested by using the same options schema inside each of the option_sets items.

POST /v1/companies/5678/orders Submit a new order with option sets

The options data will be considered as a new line item, separate to the lines.

You cannot specify a quantity on the options, you would just have multiple entries for multiple options, or multiple products with options.

If the option set supports instructions an option may include an instructions attribute with one of the four fixed values: No, Extra, Only or On Side.

The unit_price for option set options can be overriden by providing a unit_price value. unit_price should be specified as an ex tax price. See product ID 88714 in the example below.

Same as unit_price, unit_price_inc_tax can also overrides the unit_price (only if unit_price is not available in the payload). See product ID 88715 in the example below.

Update an order

PUT /v1/companies/5678/orders/93824701 Update an order
  • Orders with COMPLETE status cannot be updated.

The status field should be one of:

  • SUBMITTED - The order has been submitted and is awaiting approval from the company.
  • ON_HOLD - The order has been held for future processing (i.e. it is a pre-order).
  • ACCEPTED - The order has been accepted by the company, and is ready to be fulfilled.
  • REJECTED - The order has been rejected by the company (e.g. the order was cancelled or refunded).
  • PENDING - The order has been fulfilled and is awaiting payment.
  • COMPLETE - The order has been fulfilled and paid.

Kounta by Lightspeed will automatically change an order’s status from PENDING to COMPLETE if it is paid and the complete_when_paid flag is true.

You can add, update, remove, and re-order lines and payments using the Lines and Payments endpoints.

Refund an order

POST /v1/companies/5678/orders Refund an order
  • A refund is essentially a new order, with negative line items and payments.
  • It is recommended to include the original_order_id_str referencing the order that was refunded.
  • The order must have a status of COMPLETED if original_order_id_str is provided.

Option sets

An order may contain option sets. These are available through the options attribute:

GET /v1/companies/5678/orders/93824701 Get an order by ID

Since a single option set can span multiple lines on an order the option sets will be presented in their original form attached to the order (rather than the individual lines).

The order in the example above contains one option set that is represented in the order lines 2 and 3. Each nested option set selection will contain a line_number that points to an order line (the number attribute on a line).

Lines (and their modifiers) that belong to an option set cannot be modified directly. You must update the original option set instead. The order lines that are part of an option set will contain the attribute part_of_option_set with a value of true.

If the option set supports instructions an option may include an instructions attribute with one of the four fixed values: No, Extra, Only or On Side.

Get an option set

GET /v1/companies/5678/orders/93824701/optionsets/1 Get an option set for an order
  • The option set number starts at 1 which represents the first option set on that order.
  • See option sets for a full explanation.

Add an option set

POST /v1/companies/5678/orders/93824701/optionsets Add an option set to an order

Delete an option set

DELETE /v1/companies/5678/orders/93824701/optionsets/1 Delete an option set

Pass Thru Printing

POST /v1/companies/5678/orders Submit a pass-thru order

Order will be sent to kitchen and printed automatically if pass_thru_printing is set to true. Make sure a proper pass-thru register is configured correctly and online.

If pass_thru_printing_register is specified but pass_thru_printing is not set to true then it will not be tagged as a pass-thru order.

If pass_thru_printing_register is specified and it is online then it will handle the printing.

If pass_thru_printing_register is specified but it is offline then default pass-thru register will handle it.

If pass_thru_printing_register is specified but it is offline and default pass-thru register is also offline then order will be rejected.

If pass_thru_printing_register is not specified and default pass-thru register is offline then order will be rejected.

The status field should be ON_HOLD or PENDING.

A pass-thru-printing order sent in PENDING status must include payments and be paid in full.

An order sent in ON_HOLD status will move to PENDING if full payment is also included.

The order will move to COMPLETE status automatically after printing if complete_when_paid is true and the order is fully paid.

POST /v1/companies/5678/orders Submit an ON_HOLD pass-thru order without payment

If there is no full payment included, the status of the pass-thru order in ON_HOLD will not change after being printed.

POST /v1/companies/5678/orders Submit an PENDING pass-thru order with full payment

If a full payment included and complete_when_paid is true, the pass-thru order in PENDING status will move to COMPLETE after printing.

The order will stay in PENDING if complete_when_paid is false.

List of Webhooks

Here is a list of the supported webhook topics.

orders/completed

When an order is marked as complete. You will receive the complete order.

You also may provide the following attribute filters:

  • customer

orders/customer

When a customer, on whom a reference_id has been set, is linked to or unlinked from an order, you will receive the complete order.

orders/deleted

When an order is deleted. You will receive the complete order.

orders/kitchen

When an action is taken on an order that would trigger kitchen print rules (e.g. put an order ON_HOLD). This is typically used for bump screen integrations. You will receive the complete order.

group_orders/completed

After finalizing the group order, you will receive the group order payload containing the group_id, company_id, site_id and a list of orders that belong to it.