Creates a purchase. The purchase status comes from the Default status for new purchases setting in the system settings, and the status determines whether materials and products are added to stock immediately (see Changing the Purchase Status).
v1/purchases/add.php
Parameters
| Field | Type | Required | Description |
|---|---|---|---|
| supplier_id | int | supplier_id or supplier_name | ID of an existing supplier |
| supplier_name | string | supplier_id or supplier_name | Supplier name. If there is none, a supplier is created from the supplier_ prefixed fields |
| materials | array | materials or products | Material lines |
| products | array | materials or products | Product lines |
| date_placed | string | No | Purchase order date. Default today |
| date_received | string | No | Received date |
| materials_storage_id | int | No | Materials storage location. Default from settings |
| products_storage_id | int | No | Products storage location. Default from settings |
| delivery_price | float | No | Delivery cost. Default 0 |
| discount | float | No | Discount. Default 0 |
| notes | string | No | Notes |
Purchase lines
The purchase's lines are passed as two arrays: materials for materials and products for products. At least one line in one of the arrays is required.
| Field | Type | Required | Description |
|---|---|---|---|
| id | int | id or sku | Material or product ID |
| sku | string | id or sku | SKU. A product is also matched by its alternative SKUs |
| amount | float | Yes | Quantity |
| total | float | Yes | Line total (not the price per unit) |
Unlike sales, an unknown item is not skipped: the request is rejected with an error and the purchase is not created.
Supplier
A supplier is specified in one of two ways:
- supplier_id: the ID of an existing supplier, e.g. from v1/suppliers/add;
- supplier_name: the supplier's name. If there is no supplier with that name, Controlata creates one together with the purchase from the fields below.
| Field | Type | Description |
|---|---|---|
| supplier_name | string | Name |
| supplier_email | string | |
| supplier_phone | string | Phone |
| supplier_address | string | Address |
| supplier_agreement | string | Agreement |
| supplier_manager_name | string | Manager |
| supplier_manager_post | string | Manager's position |
| supplier_notes | string | Supplier notes |
If both are passed, supplier_id is used and supplier_* are ignored. If a supplier with that name already exists, the purchase is linked to it and supplier_* are not updated.
Example request
{
"supplier_id": 45,
"date_placed": "2026-10-06",
"materials_storage_id": 3998,
"materials": [
{
"sku": "M010",
"amount": 0.2,
"total": 26000
},
{
"id": 2052,
"amount": 10,
"total": 4000
}
],
"delivery_price": 1500,
"notes": "Invoice No. 118"
}
Example response
{
"success": true,
"purchase_id": 29645,
"status": 1
}
status holds the code of the status the purchase was created in.
Errors
| Error | Reason |
|---|---|
| No supplier_name or supplier_id in input | No supplier was passed |
| Supplier not found or access denied | The supplier_id supplier was not found or is deleted |
| Supplier name must not be empty | Empty supplier_name |
| Supplier name must be a string | supplier_name is not a string |
| Storage ID not found | Storage location not found or deleted |
| Materials is not an array | materials is not an array (same for products) |
| No products or materials in input | No line was passed |
| Line 0 of materials must be an object | The line is not an object (instead of 0, the line number) |
| SKU or id not set for material 0 | The line has neither id nor sku |
| Material with SKU "M010" not found | The item was not found or is deleted |
| Amount must be greater than 0 for material with SKU "M010" | Quantity is missing, not a number or not above 0 after rounding |
| Total must be 0 or greater for material with SKU "M010" | The line total is missing, not a number or below 0 |
| Date is not a valid date in format YYYY-MM-DD | Invalid order or received date |
| Invalid delivery_price value. Must be a number, 0 or greater | Delivery cost is not a number or below 0 |
| Invalid discount value. Must be a number, 0 or greater | Discount is not a number or below 0 |
In line error texts, material becomes product for product lines, and instead of SKU "M010" there is id 2052 if the line was passed by id.