Migrating from v0.9 to date-based API

Migrating Sales from v0.9 to the date-based API

This guide helps you migrate sale requests from the legacy v0.9 /api/register_sales endpoint to the date-based /api/{version}/sales endpoint.

The new endpoint introduces a cleaner, more explicit payload structure. Most fields have been renamed, reorganised, or moved into nested objects to improve clarity and consistency across the API.

Endpoint changes

ActionLegacy (v0.9)Date-based ({version})
Create a salePOST /api/register_salesPOST /api/{version}/sales
Update a salePOST /api/register_sales (with id in body)PUT /api/{version}/sales/{id}
Get a saleGET /api/register_sales/{id}GET /api/{version}/sales/{id}

Note: In the legacy API, updates and creates shared the same POST endpoint. In the date-based API, creates and updates are separated into POST and PUT.

Top-level field changes

Legacy fieldNew fieldNotes
register_idsource.register_idMoved under source.
user_idsource.author_idRenamed and moved under source.
sale_datedateRenamed. Must now be RFC3339 format (2016-05-05T23:35:34Z).
statusRemoved. Use state and attributes instead. See states and attributes.
register_sale_attributesattributesRenamed.
register_sale_productsline_itemsRenamed.
register_sale_paymentspaymentsRenamed.
invoice_sequence_metadata.invoice.sequenceMoved under _metadata.invoice.
resolve_invoice_number_metadata.invoice.resolve_numberRenamed and moved under _metadata.invoice.
source (string)source.typeMoved under source object.
source_idsource.idMoved under source object.

| adjustments | pricing.adjustments | Moved under pricing. Sub-fields restructured: target_type/target_method/targetstarget.type/target.method/target.ids, source_idsource.id, value_type/valueamount.type/amount.value. |

Line item field changes

Legacy fieldNew fieldNotes
product_idproduct.idMoved under product object.
pricepricing.priceMoved under pricing object.
costpricing.costMoved under pricing.
discountpricing.discountMoved under pricing.
loyalty_valuepricing.loyalty_amountRenamed and moved under pricing.
taxtax.amountMoved under tax object.
tax_idtax.idMoved under tax.
register_idsource.register_idMoved under source.
sequence_metadata.sequenceMoved under _metadata.
price_set_metadata.is_price_overrideRenamed, moved under _metadata, and type changed from integer (0/1) to boolean.
salesperson_idsource.author_idRenamed and moved under source.
fulfillment_type_metadata.fulfillment_methodRenamed and moved under _metadata.
adjustmentspricing.adjustmentsMoved under pricing. Same sub-field restructuring as sale-level adjustments.
promotions[].promotion_idpromotions[].idRenamed from promotion_id to id.

Payment field changes

Legacy fieldNew fieldNotes
retailer_payment_type_idtype.config_idRenamed and moved under type.
payment_datedateRenamed. Must be RFC3339 format.
register_idsource.register_idMoved under source.
payment_type_idtype.system_idMoved under type object.
source (string)source.typeMoved under source object.
source_idsource.idMoved under source object.

Payload comparison

Legacy (v0.9) payload

{
    "register_id": "b1e198a9-f019-11e3-a0f5-b8ca3a64f8f4",
    "user_id": "b1ed6158-f019-11e3-a0f5-b8ca3a64f8f4",
    "customer_id": "06e35f89-3783-11e6-ec7e-13193f7bd2ed",
    "sale_date": "2016-05-05 23:35:34",
    "status": "CLOSED",
    "state": "closed",
    "short_code": "mlzs94",
    "invoice_number": "MR-1484-NZ",
    "source": "pos_system",
    "source_id": "ext-sale-001",
    "resolve_invoice_number": true,
    "invoice_sequence": 1484,
    "register_sale_attributes": [],
    "adjustments": [{
        "type": "DISCOUNT",
        "name": "Loyalty discount",
        "target_type": "SALE",
        "target_method": "PROPORTIONED",
        "value_type": "FIXED",
        "value": "5.00",
        "source_id": "promo-uuid-1"
    }],
    "register_sale_products": [{
        "product_id": "b1d87b58-f019-11e3-a0f5-b8ca3a64f8f4",
        "register_id": "b1e198a9-f019-11e3-a0f5-b8ca3a64f8f4",
        "quantity": 1,
        "price": 22,
        "cost": 20,
        "discount": 0,
        "loyalty_value": 0,
        "tax": 3.3,
        "tax_id": "b1d192bc-f019-11e3-a0f5-b8ca3a64f8f4",
        "sequence": 1,
        "price_set": 1,
        "salesperson_id": "f5a7c0d0-6789-01ab-cdef-444444444444",
        "fulfillment_type": "DISPATCH",
        "status": "CONFIRMED",
        "promotions": [{
            "promotion_id": "promo-uuid-1",
            "name": "Summer Sale",
            "amount": 5.00
        }]
    }],
    "register_sale_payments": [{
        "retailer_payment_type_id": "b1e1d70e-f019-11e3-a0f5-b8ca3a64f8f4",
        "payment_type_id": "167",
        "register_id": "b1e198a9-f019-11e3-a0f5-b8ca3a64f8f4",
        "payment_date": "2016-05-05 23:35:34",
        "amount": 25.3,
        "source": "lightspeed_payments",
        "source_id": "ext-txn-456"
    }]
}

New date-based payload

{
    "source": {
        "register_id": "b1e198a9-f019-11e3-a0f5-b8ca3a64f8f4",
        "author_id": "b1ed6158-f019-11e3-a0f5-b8ca3a64f8f4",
        "type": "pos_system",
        "id": "ext-sale-001"
    },
    "date": "2016-05-05T23:35:34Z",
    "customer_id": "06e35f89-3783-11e6-ec7e-13193f7bd2ed",
    "state": "closed",
    "short_code": "mlzs94",
    "invoice_number": "MR-1484-NZ",
    "attributes": [],
    "_metadata": {
        "invoice": {
            "resolve_number": true,
            "sequence": 1484
        }
    },
    "pricing": {
        "adjustments": [{
            "type": "DISCOUNT",
            "name": "Loyalty discount",
            "target": {
                "type": "SALE",
                "method": "PROPORTIONED"
            },
            "source": {
                "id": "promo-uuid-1"
            },
            "amount": {
                "type": "FIXED",
                "value": "5.00"
            }
        }]
    },
    "line_items": [{
        "product": {
            "id": "b1d87b58-f019-11e3-a0f5-b8ca3a64f8f4"
        },
        "quantity": 1,
        "pricing": {
            "price": "22",
            "cost": "20",
            "discount": "0",
            "loyalty_amount": "0"
        },
        "tax": {
            "id": "b1d192bc-f019-11e3-a0f5-b8ca3a64f8f4",
            "amount": "3.3"
        },
        "source": {
            "register_id": "b1e198a9-f019-11e3-a0f5-b8ca3a64f8f4",
            "author_id": "f5a7c0d0-6789-01ab-cdef-444444444444"
        },
        "_metadata": {
            "sequence": 1,
            "is_price_override": true,
            "fulfillment_method": "DISPATCH"
        },
        "status": "CONFIRMED",
        "promotions": [{
            "id": "promo-uuid-1",
            "name": "Summer Sale",
            "amount": "5.00"
        }]
    }],
    "payments": [{
        "type": {
            "config_id": "b1e1d70e-f019-11e3-a0f5-b8ca3a64f8f4",
            "system_id": "167"
        },
        "source": {
            "register_id": "b1e198a9-f019-11e3-a0f5-b8ca3a64f8f4",
            "type": "lightspeed_payments",
            "id": "ext-txn-456"
        },
        "date": "2016-05-05T23:35:34Z",
        "amount": "25.3"
    }]
}

Key behavioural differences

  • No more status: The legacy status field (SAVED, CLOSED, ONACCOUNT, LAYBY, etc.) is removed. Use state (parked, pending, closed, voided) together with attributes (onaccount, layby, delivery, pickup, service) to represent the same information.
  • Create vs update split: POST /api/{version}/sales is now for creation only. Updates must use PUT /api/{version}/sales/{id}.
  • Response shape: POST returns only the id of the created sale. Use GET /api/{version}/sales/{id} to retrieve the full sale object.

Next steps

Once you're familiar with the new structure, see Sales 101 for full details on the payload, including line item and payment semantics, fulfillment details, and metadata.