Skip to content

Customers

Every order is delivered to a customer who has at least one address. Customers are scoped to your merchant account — phone numbers and emails are de-duplicated within your account only.

Create a customer

POST /integration/merchant/customer

Request body:

json
{
  "name": "Sara Ahmad",
  "phoneNumber": "+96550001234",
  "email": "[email protected]",
  "addresses": [
    {
      "label": "Home",
      "addressType": "home",
      "governorateId": "<governorate-id>",
      "neighborhoodId": "<neighborhood-id>",
      "blockId": "4",
      "streetId": "12",
      "houseNumber": "8",
      "buildingName": "Al-Salam Tower",
      "floorNumber": "3",
      "apartmentNumber": "11"
    }
  ]
}
FieldRequiredNotes
nameYesCustomer full name.
phoneNumberYesValidated and normalized. Must be unique within your merchant account.
emailNoValidated if provided. Unique within your merchant account.
addressesNoUp to 5. The first address becomes the default. label is the only schema-required address field; governorateId and neighborhoodId are required for pricing.

Response: 201 Created

json
{
  "success": true,
  "data": {
    "customer": {
      "_id": "665f...",
      "name": "Sara Ahmad",
      "phoneNumber": "96550001234",
      "addresses": [ { "_id": "665f...", "label": "Home", "isDefault": true, /* ... */ } ]
    }
  }
}

Store customer._id and the relevant addresses[]._id — you need both to create an order.

Find or create a customer

POST /integration/merchant/customer/upsert

The most convenient endpoint for e-commerce flows: pass a phone number and get back the existing customer, or create a new one — all in a single call.

Request body:

json
{ "phoneNumber": "+96550001234", "name": "Sara Ahmad" }
FieldRequiredNotes
phoneNumberYesSearched within your merchant account.
nameIf creatingRequired when no match is found and a new customer must be created.
emailNoStored on creation only if the customer doesn't exist yet.

Response:

json
{
  "success": true,
  "data": {
    "customer": { "_id": "665f...", "name": "Sara Ahmad", /* ... */ },
    "created": false
  }
}

created: true means a new customer was created; created: false means an existing one was returned. The customer shape is identical in both cases.

Address fields

FieldRequiredDescription
labelSchema requiredA name for the address, e.g. "Home", "Office".
governorateIdRequired for pricingFrom the area tree. Orders cannot be priced without it.
neighborhoodIdRequired for pricingFrom the area tree. Orders cannot be priced without it.
addressTypeOptionalhome (default) | apartment | office.
blockIdOptional — strongly preferredImproves pricing accuracy and routing.
streetIdOptionalStreet within the block.
parcelIdOptionalParcel identifier.
houseNumberOptionalHouse or villa number.
buildingNameOptionalName of the building or tower.
floorNumberOptionalFloor within a building.
apartmentNumberOptionalApartment unit number.
officeNumberOptionalOffice unit number.
paciNumberOptionalKuwait Civil ID (PACI) parcel number.
line1OptionalFree-text fallback address line.
coordinatesOptional{ "lat": <number>, "lng": <number> }.

Required for pricing

At minimum, each address needs governorateId and neighborhoodId — the delivery fee is resolved from them. Provide blockId as well whenever you can. If a customer gives you their Kuwait Civil ID (PACI number), resolve the full hierarchy in one call via GET /governorate-area/civil-id.

List customers

GET /integration/merchant/customer

Returns your merchant's customers with pagination. Supports ?page, ?limit, and ?search query parameters. The list is always returned under data.list with data.pagination.

Get a customer

GET /integration/merchant/customer/:customerId

Returns a single customer (must belong to your merchant), including all addresses.

Update a customer

PUT /integration/merchant/customer/:customerId

Updates the customer's name, phoneNumber, or email. Only send the fields you want to change.

Request body:

json
{ "name": "Sara A. Al-Rashidi", "email": "[email protected]" }

Response: 200 OK — updated customer object.

Add an address

POST /integration/merchant/customer/:customerId/address

Adds an address to an existing customer (max 5 total). The first address added to a customer with no addresses becomes the default.

Request body:

json
{
  "label": "Office",
  "governorateId": "<governorate-id>",
  "neighborhoodId": "<neighborhood-id>",
  "blockId": "7",
  "streetId": "3",
  "buildingName": "Trade Center",
  "officeNumber": "402"
}

label, governorateId, and neighborhoodId are required; the rest are optional (see Address fields).

Response: 201 Created

json
{
  "success": true,
  "data": {
    "address": { "_id": "665f...", "label": "Office", "isDefault": false /* ... */ },
    "addresses": [ /* all of the customer's addresses */ ]
  }
}

Update an address

PUT /integration/merchant/customer/:customerId/address/:addressId

Updates fields on an existing address. Send the same fields accepted at creation. Wasal verifies the customer belongs to your merchant before applying the change.

Set the default address

PUT /integration/merchant/customer/:customerId/address/:addressId/default

Marks the given address as the customer's default. When an order omits customerAddressId, the default address is used.

Delete an address

DELETE /integration/merchant/customer/:customerId/address/:addressId

Removes an address from the customer. The customer must have at least one remaining address before you can create new orders for them.

Delete a customer

DELETE /integration/merchant/customer/:customerId

Removes the customer from your merchant account. The customer record is soft-deleted and no longer accessible through your merchant key.

Customers with existing orders cannot be deleted. If the customer has one or more orders under your merchant account, the request returns 409 CUSTOMER_HAS_ORDERS. Cancel or resolve the outstanding orders before deleting the customer.

Response: 200 OK

json
{ "success": true, "message": "Customer removed from merchant successfully" }

Errors

HTTPcodeMeaning
400VALIDATION_FAILEDOne or more fields invalid — see errors.
400MAX_ADDRESSES_EXCEEDEDCustomer already has 5 addresses.
404CUSTOMER_NOT_FOUNDCustomer does not exist or is not linked to your merchant.
409CUSTOMER_PHONE_DUPLICATEA customer with this phone already exists for your merchant.
409CUSTOMER_EMAIL_DUPLICATEA customer with this email already exists for your merchant.
409CUSTOMER_HAS_ORDERSCustomer has existing orders and cannot be deleted.

See the full Error Reference.

Wasal Delivery Platform · Integration API v1.0.0