Delivery Sales with Customer Addresses

Delivery Sales with Customer Addresses

This tutorial explains how to create delivery sales with customer billing and shipping addresses using the public REST APIs.

See also: Sales 101, Fulfillments, States and attributes.

Understanding Sale Addresses

Billing vs Shipping Addresses

For each new delivery sale, both addresses must be created for the customer first:

  • Billing address: The address associated with the payment method. This is where invoices are sent and where the payment card is registered. Stored in register_sale_payments.
  • Shipping address: The address where goods will be delivered. Stored in fulfillment_details.

Workflow Overview

Creating a delivery sale with customer addresses requires four steps:

  1. Create a customer (v2.0 API) — Skip if using an existing customer
  2. Create a billing address for the customer (v2.0 API)
  3. Create a shipping address for the customer (v2.0 API)
  4. Create the delivery sale with address references (v0.9 API)

Step 1: Create Customer (Optional)

If you're creating a sale for a new customer, first create the customer record. Skip this step if you already have the customer's ID.

POST https://<<domain_prefix>>.retail.lightspeed.app/api/2.0/customers

{
  "first_name": "Jane",
  "last_name": "Doe",
  "email": "[email protected]",
  "phone": "+1 555 123 4567",
  "company_name": "Acme Corp"
}

Response (201 Created):

{
  "data": {
    "id": "b8ca3a65-0183-11e4-fbb5-4f73f02a9d1c",
    "customer_code": "Jane-N4ZJ",
    "name": "Jane Doe",
    "first_name": "Jane",
    "last_name": "Doe",
    "email": "[email protected]",
    "phone": "+1 555 123 4567",
    "company_name": "Acme Corp",
    "year_to_date": 0,
    "balance": 0,
    "loyalty_balance": 0,
    "do_not_email": false,
    "enable_loyalty": true,
    "created_at": "2026-01-20T09:00:00Z",
    "updated_at": "2026-01-20T09:00:00Z",
    "version": 3505346597
  }
}

Save the id from the response. You'll use this customer_id when creating addresses and the sale.

Step 2: Create Billing Address

Create a billing address for the customer. The response includes an id_token that you'll need for the sale.

POST https://<<domain_prefix>>.retail.lightspeed.app/api/2.0/customers/{customer_id}/addresses

{
  "address_line_1": "100 Main Street",
  "address_line_2": "Suite 200",
  "city": "New York",
  "postcode": "10001",
  "state": "New York",
  "state_code": "NY",
  "country_code": "US",
  "type": "BILLING"
}

Response (201 Created):

{
  "data": {
    "id": 123456789,
    "id_token": "hmac_billing_token_abc123",
    "customer_id": "b8ca3a65-0183-11e4-fbb5-4f73f02a9d1c",
    "address_line_1": "100 Main Street",
    "address_line_2": "Suite 200",
    "city": "New York",
    "postcode": "10001",
    "state": "New York",
    "state_code": "NY",
    "country_code": "US",
    "country_name": "United States",
    "type": "BILLING",
    "created_at": "2026-01-20T10:00:00Z",
    "updated_at": "2026-01-20T10:00:00Z"
  }
}

Save the id and id_token from the response. You'll need both values when creating the sale.

Step 3: Create Shipping Address

Create a shipping address using the same endpoint with type: "SHIPPING".

POST https://<<domain_prefix>>.retail.lightspeed.app/api/2.0/customers/{customer_id}/addresses

{
  "address_line_1": "456 Oak Avenue",
  "city": "Los Angeles",
  "postcode": "90001",
  "state": "California",
  "state_code": "CA",
  "country_code": "US",
  "type": "SHIPPING"
}

Response (201 Created):

{
  "data": {
    "id": 987654321,
    "id_token": "hmac_shipping_token_xyz789",
    "customer_id": "b8ca3a65-0183-11e4-fbb5-4f73f02a9d1c",
    "address_line_1": "456 Oak Avenue",
    "city": "Los Angeles",
    "postcode": "90001",
    "state": "California",
    "state_code": "CA",
    "country_code": "US",
    "country_name": "United States",
    "type": "SHIPPING",
    "created_at": "2026-01-20T10:05:00Z",
    "updated_at": "2026-01-20T10:05:00Z"
  }
}

Save the id and id_token from the response. You'll need both values when creating the sale.

Step 4: Create Delivery Sale with Addresses

Create a delivery sale that references both addresses using the IDs and tokens from the previous steps.

POST https://<<domain_prefix>>.retail.lightspeed.app/api/register_sales

{
  "register_id": "b1e198a9-f019-11e3-a0f5-b8ca3a64f8f4",
  "customer_id": "b8ca3a65-0183-11e4-fbb5-4f73f02a9d1c",
  "user_id": "b1ed6158-f019-11e3-a0f5-b8ca3a64f8f4",
  "state": "pending",
  "register_sale_attributes": ["delivery"],
  "register_sale_products": [
    {
      "product_id": "b1d87b58-f019-11e3-a0f5-b8ca3a64f8f4",
      "quantity": 1,
      "price": 100,
      "tax": 15,
      "tax_id": "b1d192bc-f019-11e3-a0f5-b8ca3a64f8f4",
      "fulfillment_type": "DISPATCH"
    }
  ],
  "register_sale_payments": [
    {
      "retailer_payment_type_id": "b1e1d70e-f019-11e3-a0f5-b8ca3a64f8f4",
      "amount": 115,
      "billing_address_id": "123456789",
      "billing_address_token": "hmac_billing_token_abc123"
    }
  ],
  "fulfillment_details": [
    {
      "type": "DISPATCH",
      "shipping_address_id": "987654321",
      "shipping_address_token": "hmac_shipping_token_xyz789"
    }
  ]
}
FieldLocationDescription
billing_address_idregister_sale_paymentsThe id from the billing address response (as a string)
billing_address_tokenregister_sale_paymentsThe id_token from the billing address response
shipping_address_idfulfillment_detailsThe id from the shipping address response (as a string)
shipping_address_tokenfulfillment_detailsThe id_token from the shipping address response

Important Notes

  • The id_token is only returned when creating an address. It is not returned on subsequent GET requests.
  • The token is validated server-side to prevent address ID tampering.
  • The address must belong to the same customer specified in the sale.
  • Address IDs must be passed as strings in the sale request payload.

Retrieving Customer Addresses (Optional)

If you need to retrieve existing addresses for a customer (for example, to display them in a UI or verify address details), you can use the following endpoints.

List All Addresses

Retrieve all addresses associated with a customer.

GET https://<<domain_prefix>>.retail.lightspeed.app/api/2.0/customers/{customer_id}/addresses

Response (200 OK):

{
  "data": [
    {
      "id": 123456789,
      "customer_id": "b8ca3a65-0183-11e4-fbb5-4f73f02a9d1c",
      "address_line_1": "100 Main Street",
      "address_line_2": "Suite 200",
      "city": "New York",
      "postcode": "10001",
      "state": "New York",
      "state_code": "NY",
      "country_code": "US",
      "country_name": "United States",
      "type": "BILLING",
      "created_at": "2026-01-20T10:00:00Z",
      "updated_at": "2026-01-20T10:00:00Z"
    },
    {
      "id": 987654321,
      "customer_id": "b8ca3a65-0183-11e4-fbb5-4f73f02a9d1c",
      "address_line_1": "456 Oak Avenue",
      "city": "Los Angeles",
      "postcode": "90001",
      "state": "California",
      "state_code": "CA",
      "country_code": "US",
      "country_name": "United States",
      "type": "SHIPPING",
      "created_at": "2026-01-20T10:05:00Z",
      "updated_at": "2026-01-20T10:05:00Z"
    }
  ]
}

Get a Single Address

Retrieve a specific address by its ID.

GET https://<<domain_prefix>>.retail.lightspeed.app/api/2.0/customers/{customer_id}/addresses/{address_id}

Response (200 OK):

{
  "data": {
    "id": 123456789,
    "customer_id": "b8ca3a65-0183-11e4-fbb5-4f73f02a9d1c",
    "address_line_1": "100 Main Street",
    "address_line_2": "Suite 200",
    "city": "New York",
    "postcode": "10001",
    "state": "New York",
    "state_code": "NY",
    "country_code": "US",
    "country_name": "United States",
    "type": "BILLING",
    "created_at": "2026-01-20T10:00:00Z",
    "updated_at": "2026-01-20T10:00:00Z"
  }
}

Complete Example with cURL

This section provides a complete working example using cURL commands. Replace <<domain_prefix>> with your store's domain prefix and <<access_token>> with your personal access token.

Prerequisites: Gather Required IDs

Before creating a sale, you need to collect the required IDs from your store.

Get a Register ID:

curl -s -H "Authorization: Bearer <<access_token>>" \
  "https://<<domain_prefix>>.retail.lightspeed.app/api/2.0/registers" | jq '.data[0]'

Response:

{
  "id": "0698ab21-5fc8-11f0-f6d9-88a9c20f3f9c",
  "name": "Front Counter"
}

Get a User ID:

curl -s -H "Authorization: Bearer <<access_token>>" \
  "https://<<domain_prefix>>.retail.lightspeed.app/api/2.0/users" | jq '.data[0]'

Response:

{
  "id": "020b2c2a-4661-11f0-e200-88a31fbafec6",
  "display_name": "John Smith"
}

Get a Product ID:

curl -s -H "Authorization: Bearer <<access_token>>" \
  "https://<<domain_prefix>>.retail.lightspeed.app/api/2.0/products?page_size=5" | jq '.data[] | {id, name}'

Response:

{
  "id": "083d58eb-0d39-4fa2-9df8-4c3c73abf008",
  "name": "iPhone 16"
}
{
  "id": "ffe9c2be-f45d-461d-b6a7-ba7d61a001dd",
  "name": "Samsung Galaxy S24"
}

Get a Tax ID:

curl -s -H "Authorization: Bearer <<access_token>>" \
  "https://<<domain_prefix>>.retail.lightspeed.app/api/taxes" | jq '.taxes[0]'

Response:

{
  "id": "0698ab21-5f09-11f0-f6d9-88a3200cbd80",
  "name": "No Tax",
  "rate": 0,
  "default": false,
  "active": true,
  "rates": [
    {
      "id": "200d91fb-88a3-11f0-96d9-0698ab215f09",
      "rate": 0,
      "name": "No Tax"
    }
  ]
}

Get a Payment Type ID:

curl -s -H "Authorization: Bearer <<access_token>>" \
  "https://<<domain_prefix>>.retail.lightspeed.app/api/payment_types" | jq '.payment_types[0]'

Response:

{
  "id": "7692490c-97f6-4528-8260-60a65a606891",
  "name": "Cash",
  "type_id": 1,
  "disabled": false,
  "deleted_at": null,
  "internal": false
}

Step 1: Create Customer

curl -X POST \
  -H "Authorization: Bearer <<access_token>>" \
  -H "Content-Type: application/json" \
  "https://<<domain_prefix>>.retail.lightspeed.app/api/2.0/customers" \
  -d '{
    "first_name": "Jane",
    "last_name": "Doe",
    "email": "[email protected]",
    "phone": "+1 555 123 4567"
  }'

Response:

{
  "data": {
    "id": "0698ab21-5fc8-11f0-f6d9-fdc9572dd1c5",
    "customer_code": "Jane-YPK5",
    "name": "Jane Doe",
    "first_name": "Jane",
    "last_name": "Doe",
    "email": "[email protected]",
    "phone": "+1 555 123 4567",
    "year_to_date": 0,
    "balance": 0,
    "loyalty_balance": 0,
    "do_not_email": false,
    "enable_loyalty": true,
    "created_at": "2026-01-30T10:49:24+00:00",
    "updated_at": "2026-01-30T10:49:24+00:00"
  }
}

Step 2: Create Billing Address

curl -X POST \
  -H "Authorization: Bearer <<access_token>>" \
  -H "Content-Type: application/json" \
  "https://<<domain_prefix>>.retail.lightspeed.app/api/2.0/customers/0698ab21-5fc8-11f0-f6d9-fdc9572dd1c5/addresses" \
  -d '{
    "address_line_1": "200 Broadway",
    "city": "New York",
    "postcode": "10001",
    "state": "New York",
    "state_code": "NY",
    "country_code": "US",
    "type": "BILLING"
  }'

Response:

{
  "data": {
    "id": 2017188673192951808,
    "id_token": "XCLB5Bzuh7_8g3t53XrdosRrUoiZ9cRFRAK1oUQ5MXY",
    "customer_id": "0698ab21-5fc8-11f0-f6d9-fdc9572dd1c5",
    "address_line_1": "200 Broadway",
    "address_line_2": "",
    "city": "New York",
    "postcode": "10001",
    "state": "New York",
    "state_code": "NY",
    "country_code": "US",
    "country_name": "United States",
    "type": "BILLING",
    "created_at": "2026-01-30T10:50:17Z",
    "updated_at": "2026-01-30T10:50:17Z"
  }
}

Save the id and id_token for the sale request.

Step 3: Create Shipping Address

curl -X POST \
  -H "Authorization: Bearer <<access_token>>" \
  -H "Content-Type: application/json" \
  "https://<<domain_prefix>>.retail.lightspeed.app/api/2.0/customers/0698ab21-5fc8-11f0-f6d9-fdc9572dd1c5/addresses" \
  -d '{
    "address_line_1": "789 Sunset Blvd",
    "city": "Los Angeles",
    "postcode": "90028",
    "state": "California",
    "state_code": "CA",
    "country_code": "US",
    "type": "SHIPPING"
  }'

Response:

{
  "data": {
    "id": 2017188697067581440,
    "id_token": "aPAfSNxKcd2PVbt0PSTNhoRf7gjsOns18bVTV-LTSE4",
    "customer_id": "0698ab21-5fc8-11f0-f6d9-fdc9572dd1c5",
    "address_line_1": "789 Sunset Blvd",
    "address_line_2": "",
    "city": "Los Angeles",
    "postcode": "90028",
    "state": "California",
    "state_code": "CA",
    "country_code": "US",
    "country_name": "United States",
    "type": "SHIPPING",
    "created_at": "2026-01-30T10:50:23Z",
    "updated_at": "2026-01-30T10:50:23Z"
  }
}

Save the id and id_token for the sale request.

Step 4: Create Delivery Sale

Using all the IDs collected, create the delivery sale:

curl -X POST \
  -H "Authorization: Bearer <<access_token>>" \
  -H "Content-Type: application/json" \
  "https://<<domain_prefix>>.retail.lightspeed.app/api/register_sales" \
  -d '{
    "register_id": "0698ab21-5fc8-11f0-f6d9-88a9c20f3f9c",
    "customer_id": "0698ab21-5fc8-11f0-f6d9-fdc9572dd1c5",
    "user_id": "020b2c2a-4661-11f0-e200-88a31fbafec6",
    "state": "pending",
    "register_sale_attributes": ["delivery"],
    "register_sale_products": [
      {
        "product_id": "083d58eb-0d39-4fa2-9df8-4c3c73abf008",
        "quantity": 1,
        "price": 100,
        "tax": 0,
        "tax_id": "0698ab21-5f09-11f0-f6d9-88a3200cbd80",
        "fulfillment_type": "DISPATCH"
      }
    ],
    "register_sale_payments": [
      {
        "retailer_payment_type_id": "7692490c-97f6-4528-8260-60a65a606891",
        "amount": 100,
        "billing_address_id": "2017188673192951808",
        "billing_address_token": "XCLB5Bzuh7_8g3t53XrdosRrUoiZ9cRFRAK1oUQ5MXY"
      }
    ],
    "fulfillment_details": [
      {
        "type": "DISPATCH",
        "shipping_address_id": "2017188697067581440",
        "shipping_address_token": "aPAfSNxKcd2PVbt0PSTNhoRf7gjsOns18bVTV-LTSE4"
      }
    ]
  }'

Response:

{
  "register_sale": {
    "id": "c73c3df7-ab69-4a34-a636-f399f7c789fc",
    "customer_id": "0698ab21-5fc8-11f0-f6d9-fdc9572dd1c5",
    "customer_name": "Jane Doe",
    "invoice_number": "16",
    "state": "pending",
    "status": "AWAITING_DISPATCH",
    "register_sale_attributes": ["delivery"],
    "total_price": 100,
    "total_tax": 0,
    "created_at": "2026-01-30 10:51:19",
    "register_sale_products": [
      {
        "id": "801f14c3-1129-4b0b-aa49-ea06ae1fbf9f",
        "product_id": "083d58eb-0d39-4fa2-9df8-4c3c73abf008",
        "name": "iPhone 16 / Pro / 128GB",
        "quantity": 1,
        "price": 100,
        "status": "CONFIRMED",
        "fulfillment_type": "DISPATCH"
      }
    ],
    "register_sale_payments": [
      {
        "id": "0698ab21-5fc8-11f0-f6d9-fdc99bd3eb0b",
        "amount": 100,
        "name": "Cash",
        "billing_address_id": "2017188673192951808"
      }
    ]
  }
}

The sale is now created with status AWAITING_DISPATCH, indicating it's ready for fulfillment.

Verify Customer Addresses

After creating addresses, you can verify them using the GET endpoints:

List all addresses:

curl -s -H "Authorization: Bearer <<access_token>>" \
  "https://<<domain_prefix>>.retail.lightspeed.app/api/2.0/customers/0698ab21-5fc8-11f0-f6d9-fdc9572dd1c5/addresses"

Response:

{
  "data": [
    {
      "id": 2017188697067581440,
      "customer_id": "0698ab21-5fc8-11f0-f6d9-fdc9572dd1c5",
      "address_line_1": "789 Sunset Blvd",
      "city": "Los Angeles",
      "postcode": "90028",
      "state": "California",
      "state_code": "CA",
      "country_code": "US",
      "country_name": "United States",
      "type": "SHIPPING",
      "created_at": "2026-01-30T10:50:23Z",
      "updated_at": "2026-01-30T10:50:23Z"
    },
    {
      "id": 2017188673192951808,
      "customer_id": "0698ab21-5fc8-11f0-f6d9-fdc9572dd1c5",
      "address_line_1": "200 Broadway",
      "city": "New York",
      "postcode": "10001",
      "state": "New York",
      "state_code": "NY",
      "country_code": "US",
      "country_name": "United States",
      "type": "BILLING",
      "created_at": "2026-01-30T10:50:17Z",
      "updated_at": "2026-01-30T10:50:17Z"
    }
  ]
}

Note that id_token is not included in GET responses—it is only returned when creating an address.

Fulfill the Sale

After processing the delivery, mark the sale as shipped using the fulfillment endpoint. For comprehensive fulfillment documentation including partial fulfillments, picking, and packing, see the Fulfillments guide.

Fulfill the sale (mark as SHIPPED):

curl -X POST \
  -H "Authorization: Bearer <<access_token>>" \
  -H "Content-Type: application/json" \
  "https://<<domain_prefix>>.retail.lightspeed.app/api/2.0/sales/c73c3df7-ab69-4a34-a636-f399f7c789fc/fulfill" \
  -d '{
    "fulfillment_type": "SHIPPED"
  }'

Response:

{
  "data": {
    "id": "2017192376529309696",
    "sale_id": "c73c3df7-ab69-4a34-a636-f399f7c789fc",
    "outlet_id": "0698ab21-5fc8-11f0-f6d9-88a9c2064dff",
    "user_id": "020b2c2a-4661-11f0-e200-88a31fbafec6",
    "status": "SHIPPED",
    "created_at": "2026-01-30T11:05:14Z",
    "line_items": [
      {
        "id": "2017192376537698304",
        "product_id": "083d58eb-0d39-4fa2-9df8-4c3c73abf008",
        "quantity": "1"
      }
    ]
  }
}

The fulfillment_type can be either SHIPPED (for delivery) or PICKED_UP (for customer pickup).

Verify fulfillments:

curl -s -H "Authorization: Bearer <<access_token>>" \
  "https://<<domain_prefix>>.retail.lightspeed.app/api/2.0/sales/c73c3df7-ab69-4a34-a636-f399f7c789fc/fulfillments"

Response:

{
  "data": [
    {
      "id": "2017192376529309696",
      "sale_id": "c73c3df7-ab69-4a34-a636-f399f7c789fc",
      "outlet_id": "0698ab21-5fc8-11f0-f6d9-88a9c2064dff",
      "user_id": "020b2c2a-4661-11f0-e200-88a31fbafec6",
      "status": "SHIPPED",
      "created_at": "2026-01-30T11:05:14Z",
      "line_items": [
        {
          "id": "2017192376537698304",
          "product_id": "083d58eb-0d39-4fa2-9df8-4c3c73abf008",
          "quantity": "1"
        }
      ],
      "shipping_address_id": "2017188697067581440"
    }
  ]
}

Note that the shipping_address_id appears in the fulfillment response, linking the fulfillment to the shipping address.

Sale status after fulfillment:

After fulfillment, the sale status changes. Verify by fetching the sale:

curl -s -H "Authorization: Bearer <<access_token>>" \
  "https://<<domain_prefix>>.retail.lightspeed.app/api/register_sales/c73c3df7-ab69-4a34-a636-f399f7c789fc"

Response (key fields):

{
  "register_sales": [
    {
      "id": "c73c3df7-ab69-4a34-a636-f399f7c789fc",
      "status": "DISPATCHED_CLOSED",
      "state": "closed",
      "register_sale_attributes": ["delivery"],
      "customer_name": "Jane Doe",
      "total_price": 100,
      "register_sale_payments": [
        {
          "amount": 100,
          "name": "Cash",
          "billing_address_id": "2017188673192951808"
        }
      ]
    }
  ]
}

The sale has transitioned from:

  • status: AWAITING_DISPATCHDISPATCHED_CLOSED
  • state: pendingclosed