> For the complete documentation index, see [llms.txt](https://wiki.wakilni.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://wiki.wakilni.com/integrations/api.md).

# API

the Wakilni offers an API to help create and manage orders from third-party applications.

Developers can use this API to integrate Wakilni into their custom applications.

Below are steps required, along with detailed documentation on the API.

### Testing environment

For `Testing` use the data below instead of the data in the [Production Environment](#production-environment) section&#x20;

`URL` -> <https://api-dev.wakilni.com>

### Setup

You need to register as a new client in [`https://dev.wakilni.com/sign-up`](https://dev.wakilni.com/sign-up) and complete the integration as followed in the documentation.

### Production environment

If everything went right, please find the `Production` data (use data below instead of the data in the [Testing Environment](#testing-environment) section)

`URL` -> <https://api.wakilni.com>

`JORDAN URL` -> <https://jordan-api.wakilni.com>

### **Integration with Wakilni steps:**

1. Each client will be able to generate an access token that is attached to your account to be used in the API.
   1. Login to customer back office
   2. Go to Settings
   3. Open tab “Api Tokens”
   4. Click “Link to your custom app”
   5. Enter your shop name/label.
   6. Click create
   7. A key/secret combination will be created for this client.
   8. Copy these credentials and pass them to the request of the auth api.
   9. A token will be generated, which you can pas as a bearer token in the other apis.                          &#x20;

### **Order flow**

* Bulk process is divided into 2 flows: pickup bulk and delivery bulk
* Pickup bulk: driver pickups the product from the vendor
* Delivery bulk: driver delivers the product to the recipient
* Shipping price: Wakilni has default delivery prices based on pickup/delivery locations. Also, each customer can have his own customized prices.
* Api process:
  * Start bulk: creates pickup bulk order (multiple bulks can be created)
  * Add delivery: creates delivery order related to pickup bulk (multiple deliveries can be created)
  * End bulk: orders become active and are sent to portal for shipping
  * Show order status: shows order status based on the flow update\
    Status/ Status Code:
    * PENDING = 1
    * CONFIRMED = 2
    * DECLINED = 6
    * CANCELED = 7
    * PROCESSING = 3
    * SUCCESS = 4
    * FAILED = 5
    * CLOSED\_FAILED = 8&#x20;
    * POSTPONED = 9
    * PENDING\_CANCELLATION = 10
    * SUCCESS, REJECTED = 4
      * When the order is delivered but the client rejected it

### **Authentication**

**API**: [https://api.wakilni.com/api/v2/third\_party/auth\_token](#testing-environment)

**Method**: GET

**Body**:

```
{
    "key": string,
    "secret": string
}
```

* `key`: App key
* `secret`: App secret

**Response**

```
{
    "message": "Auth token retrieved successfully",
    "token": "*****"
}
```

### **Start bulk**

**API**: [https://api.wakilni.com/api/v2/clients/start\_bulk](#testing-environment)

**Method**: POST

**Header**: **Authorization**: Bearer {token}

**Body**:

```
{
    "location_id": number,
    "longitude": number,
    "latitude": number,
    "floor": number,
    "area": string, 
}
```

* `location_id`: customer’s location id reference from your app
* `longitude`: customer’s location’s longitude
* `latitude`: customer’s location’s latitude
* `floor`: customer’s location’s floor
* `area`: it is preferable to send us the area name from the list provided from get area’s list

**Response**

```
{
    "message": "Bulk order opened",
    "bulk_id"
}
```

### **Add delivery**

**API**: [https://api.wakilni.com/api/](#testing-environment)[v2/](#testing-environment)[clients/add\_delivery/{bulk\_id}](#testing-environment)

**Method**: POST

**Header**: **Authorization**: Bearer {token}

**Body**:

```
{
    "get_order_details": boolean,
    "get_barcode": boolean,
    "waybill": number,
    "receiver_id": number,
    "receiver_first_name": string,
    "receiver_last_name": string,
    "receiver_phone_number": string,
    "receiver_gender": string,
    "receiver_email": string,
    "receiver_secondary_phone_number": string,
    "receiver_location_id *": number,
    "receiver_longitude": number,
    "receiver_latitude": number,
    "receiver_building": string,
    "receiver_floor": number,
    "receiver_directions": string,
    "receiver_area": string,
    "currency": number,
    "cash_collection_type_id": number,
    "collection_amount": double,
    "note: string,
    "car_needed": bool,
    "is_express": bool,  
    "packages": [
        {
            "quantity": number,
            "type_id": number,
            "name": string,
            "sku": string
        },..
    ]
}
```

* `get_order_details`: Set to true if you want to display order details after creating order
* `get_barcode`: Set to true if you want the barcode label returned
* `waybill`: To reference or identify your order
* `receiver_id`: The recipient’s unique reference id from your app or system
  * For example: your recipient's id in your system is 123, then `"receiver_id" : 123`
* `receiver_first_name`: Recipient’s first name
* `receiver_last_name`: Recipient’s last name
* `receiver_phone_number`: Recipient’s phone number
* `receiver_gender`: Recipient’s gender (1 -> male, 2 -> female)
* `receiver_email`: Recipient’s email
* `receiver_secondary_phone_number`: Recipient’s secondary phone number
* `receiver_location_id *`*:* The recipient’s location's unique reference id from your app or system
  * For example, your recipients shipping address location id is 123, then\
    `"receiver_location_id" : 123`
* `receiver_longitude`: Customer’s location’s longitude
* `receiver_latitude`: Customer’s location’s latitude
* `receiver_building`: Customer’s location’s building
* `receiver_floor`: Customer’s location’s floor
* `receiver_directions`: Customer’s location’s directions
* `receiver_area`: It is preferable to send us the area name from the list provided from get area’s list
* `currency`: 1 -> USD, 2 -> LBP
* `cash_collection_type_id`: (paid: 54, on delivery: 52)
* `type_id`: (paper: 57, regular box: 58, small box: 59, large box: 60, very large box: 61)
* `is_express`: When `true`, creates an **Express** order and prices accordingly. Omitting it (or `false`) defaults to a standard **Bulk** order.&#x20;

**Response:**&#x20;

```
{
    "message": "Delivery order added",
    "delivery_id",
    "tracking_url",
    "tracking_id",
    "packages": [
        { "barcode_package_number": string },
        ..
    ],
    "barcode_label",
    "order_details"
}
```

* `packages`: Array of barcode objects generated for this order's packages. Each object has a `barcode_package_number`. The array is empty if no barcode records exist yet, and is always present (never `null`). Barcodes are auto-generated when packages are created.

**Note**: for use of barcode label to display barcode image, add the blob value to the image src as follows:

```
<img src="data:image/png;base64,{{barcode_label)}}" alt="barcode"/>
```

### **End bulk**

**API**: [https://api.wakilni.com/api/](#testing-environment)[v2/](#testing-environment)[clients/end\_bulk/{bulk\_id}](#testing-environment)

**Method**: POST

**Header**: **Authorization**: Bearer {token}

**Response:**&#x20;

```
{
    "message": "Closed Bulk order",
    "bulk_id"
}
```

### **Update order**

**API**: [https://api.wakilni.com/api/v2/clients/orders/{id}](https://api.wakilni.com/api/v2/clients/orders/%7Bid%7D)

**Method**: PUT

**Header**: **Authorization**: Bearer {token}

**Description**: Updates a pending delivery order. Uses PATCH semantics — only fields present in the body whose value differs from the stored value are changed; any omitted field is left unchanged.

**Note**: Only orders with status **Pending (1)** can be updated. Updating a non-pending order returns a `422`.

**Body** (all fields optional — send only the fields you want to change):

```
{
    "waybill": string,
    "car_needed": boolean,
    "try_on": boolean,
    "exchange": boolean,
    "is_express": boolean,
    "currency": number,
    "cash_collection_type_id": number,
    "collection_amount": number,
    "note": string,
    "require_signature": boolean,
    "require_picture": boolean,
    "self_pickup": boolean,
    "self_pickup_details": { "office_id": number },
    "new_receiver_location": boolean,
    "receiver_first_name": string,
    "receiver_last_name": string,
    "receiver_phone_number": string,
    "receiver_secondary_phone_number": string,
    "receiver_gender": number,
    "receiver_email": string,
    "receiver_building": string,
    "receiver_floor": number,
    "receiver_directions": string,
    "receiver_longitude": number,
    "receiver_latitude": number,
    "receiver_area": string,
    "packages": [
        { "quantity": number, "type_id": number, "name": string, "sku": string },
        ..
    ]
}
```

Field reference:

* `waybill` (max 100): Your internal reference / waybill number.
* `car_needed`: Whether a car (van) is needed for delivery.
* `try_on`: Whether the receiver can try on the item before accepting.
* `exchange`: Whether the order involves an exchange.
* `is_express`: Toggle express. `true` on a standard bulk order switches it to **Express Single** and reprices; `false` on an express order reverts it to **Bulk** and reprices.
* `currency`: Collection currency ID — `1 = USD`, `2 = LBP`.&#x20;
* `cash_collection_type_id`: `54 = Paid`, `52 = On Delivery`. Switching to Paid (54) automatically resets `collection_amount` to 0.
* `collection_amount` (≥ 0): Amount to collect from the receiver. If the collection type is Paid, the effective amount is always 0 regardless of what is sent.
* `note` (max 5000): Order note / instructions. Also stored as a public comment on the order.
* `require_signature`: Whether a signature must be collected on delivery.
* `require_picture`: Whether a picture must be taken on delivery.
* `self_pickup`: Whether the receiver will pick up from a Wakilni office. Setting `true` requires `self_pickup_details.office_id`. Setting `false` removes the self-pickup record and reprices.
* `self_pickup_details.office_id`: Required when `self_pickup = true`. The ID of the Wakilni pickup office.
* `new_receiver_location`: Controls whether location changes apply to all orders sharing the same location, or to this order only. `false` (default) updates the existing location record in place — all ongoing orders sharing it see the change. `true` clones the location into a new record assigned only to this order; the original is untouched. Only applies when location fields are changed (`receiver_building`, `receiver_floor`, `receiver_directions`, `receiver_longitude`, `receiver_latitude`, `receiver_area`). Recipient fields (name, phone, etc.) are always updated in place regardless of this flag.
* `receiver_first_name` / `receiver_last_name`: Receiver's name.
* `receiver_phone_number` / `receiver_secondary_phone_number`: Receiver's phone numbers.
* `receiver_gender`: `1 = Male`, `2 = Female`.
* `receiver_email`: Receiver's email.
* `receiver_building` / `receiver_floor` / `receiver_directions`: Receiver's location details.
* `receiver_longitude` / `receiver_latitude`: Receiver's location coordinates.
* `receiver_area`: Receiver's area name (e.g. "Hazmieh").&#x20;
* `packages`: **Replace-all** — if present, all existing packages are deleted and replaced with exactly the list sent. To keep existing packages you must re-send them. Each element requires `quantity`; other sub-fields are optional.
  * `packages.*.quantity` (≥ 1): Required when `packages` is present.
  * `packages.*.type_id`: `57 = Paper`, `58 = Regular Box`, `59 = Small Box`, `60 = Large Box`, `61 = Very Large Box`. Defaults to 58 if omitted.
  * `packages.*.name` (max 255): Package description / item name.
  * `packages.*.sku` (max 255): Package SKU.

**Price recalculation**: The delivery price is automatically recalculated and applied to the order's `price` field when `is_express` changes.

**Response**:

```
{
    "message": "Order updated successfully",
    "id": number,
    "tracking_url": string,
    "tracking_id": string,
    "packages": [
        { "barcode_package_number": string },
        ..
    ]
}
```

* `packages`: Current barcode objects for the order's packages after the update.

**Error responses**:

* `404` — Order not found or does not belong to this customer → "Order not found."
* `422` — Order is not in Pending status → "Cannot update a non-pending order."
* `422` — `self_pickup = true` sent without `office_id` → "The office id is required when self pickup is true."
* `422` — `is_express = true` but `ClientCanExpress` feature flag disabled → "You cannot update this order to express, you can contact the operator."
* `422` — Validation failure (e.g. invalid currency ID) → field-level validation messages.

**Example — update collection details & receiver area**

Request:

```
PUT https://api.wakilni.com/api/v2/clients/orders/98765
Authorization: Bearer eyJ...

{
    "currency": 2,
    "cash_collection_type_id": 52,
    "collection_amount": 250000,
    "receiver_area": "Hamra",
    "note": "Call before delivery"
}
```

Response:

```
{
    "message": "Order updated successfully",
    "id": 98765,
    "tracking_url": "https://track.wakilni.com/WK123456",
    "tracking_id": "WK123456",
    "packages": [
        { "barcode_package_number": "WKB2401010001" },
        { "barcode_package_number": "WKB2401010002" }
    ]
}
```

**Example — replace packages**

Request:

```
PUT https://api.wakilni.com/api/v2/clients/orders/98765
Authorization: Bearer eyJ...

{
    "packages": [
        { "quantity": 2, "type_id": 58, "name": "Shoes", "sku": "SH-001" },
        { "quantity": 1, "type_id": 59, "name": "Hat", "sku": "HT-002" }
    ]
}
```

Response:

```
{
    "message": "Order updated successfully",
    "id": 98765,
    "tracking_url": "https://track.wakilni.com/WK123456",
    "tracking_id": "WK123456",
    "packages": [
        { "barcode_package_number": "WKB2401010003" },
        { "barcode_package_number": "WKB2401010004" },
        { "barcode_package_number": "WKB2401010005" }
    ]
}
```

### **Show order status**

**API**: [https://api.wakilni.com/api/](#testing-environment)[v2/](#testing-environment)[clients/orders/{id}](#testing-environment)

**Method**: POST

**Header**: **Authorization**: Bearer {token}

**Response:**

```
{
    "status"
    "status_code"
    "completed_on"
}
```

### **Show order status from tracking id**

**API**: [https://api.wakilni.com/api/](#testing-environment)[v2/](#testing-environment)[clients/tracking/orders/{tracking\_id}](#testing-environment)

**Method**: POST

**Header**: **Authorization**: Bearer {token}

**Response:**

```
{
    "status"
    "status_code"
    "completed_on"
}
```

### **Cancel order**

**API**: [https://api.wakilni.com/api](#testing-environment)[/v2/clients/orders/{id}/cancel](https://api.wakilni.com/api/v2/clients/orders/%7Bid%7D/cancel%60)

**Method**: PUT

**Header**: **Authorization**: Bearer {token}

**Body**:

```
{
    "reason": string,
}
```

* `reason`: Reason for canceling the order

**Response:**&#x20;

```
{
    "message": string,
    "delivery_id": number
}
```

**Note**: You are able to cancel an order only if the status is pending

### **Get areas**

**API**: [https://api.wakilni.com/api/v2/areas](#testing-environment)

**Method**: GET

**Header: Authorization:** Bearer {token}

**Pagination:** [https://api.wakilni.com/api/v2/areas?with\_pagination=true\&page=2](#testing-environment)

**Filter:** [https://api.wakilni.com/api/](#testing-environment)[v2/](#testing-environment)[areas?search=name:beirut\&searchJoin=and\&with\_filter=true](#testing-environment)

**Pagination and Filter:** [https://api.wakilni.com/api/](#testing-environment)[v2/](#testing-environment)[areas?search=name:beirut\&searchJoin=and\&with\_filter=true\&with\_pagination=true\&page =2](#testing-environment)

### Get order status

**API**: <https://api.wakilni.com/api/v2/clients/orders/status?tracking_id={tracking_id}&order_id={order_id}>

**Note:** You may use either the tracking\_id or the order\_id based on your preference&#x20;

**Method**: GET

**Header: Authorization:** Bearer {token}

**Response:**

```
{
    "success": true,
    "data": {
        "tracking_id": string,
        "comments": array of strings,
        "logs": [
            {
                "status": string,
                "status_code": number,
                "created_at": string
            },
        ]
    }
}
```

**Example response:**

```
{
    "success": true,
    "data": {
        "tracking_id": "WK2312120840222729128YIbYK",
        "comments": [
            "Call before delivery",
            "No answer",
            "Not available",
            "Order rejected"
        ],
        "logs": [
            {
                "status": "Success",
                "status_code": 4,
                "created_at": "2023-12-12 11:22:24"
            },
            {
                "status": "Success, Rejected",
                "status_code": 4,
                "created_at": "2023-12-12 11:22:24"
            },
            {
                "status": "Processing",
                "status_code": 3,
                "created_at": "2023-12-12 10:58:49"
            },
            {
                "status": "Closed Failed",
                "status_code": 8,
                "created_at": "2023-12-12 10:50:39"
            },
            {
                "status": "Processing",
                "status_code": 3,
                "created_at": "2023-12-12 10:47:37"
            },
            {
                "status": "Canceled",
                "status_code": 7,
                "created_at": "2023-12-12 10:40:37"
            },
            {
                "status": "Confirmed",
                "status_code": 2,
                "created_at": "2023-12-12 10:40:22"
            },
            {
                "status": "Pending",
                "status_code": 1,
                "created_at": "2023-12-12 10:40:22"
            }
        ]
    }
}
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://wiki.wakilni.com/integrations/api.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
