Purchase orders
Orders pharmacies placed with you: confirm, reject, and declare what you're delivering.
Endpoints
List orders
https://api.dawatrack.com/partner-api/v1/purchase-orders/
Orders pharmacies on DawaTrack placed with your supplier account, newest first.
orders:read
Limit 5,000 per day
Your credential must belong to an API account linked to a supplier account; otherwise 403. Needs orders:read.
Filter with status: SENT (waiting for you), CONFIRMED, PARTIALLY_RECEIVED, RECEIVED or CANCELLED. The order.* webhooks tell you when a new order arrives.
Query parameters
-
orderingstring OptionalWhich field to use when ordering the results.
-
pageinteger OptionalA page number within the paginated result set.
-
page_sizeinteger OptionalNumber of results to return per page.
-
searchstring OptionalA search term.
-
statusenum OptionalPossible values:CANCELLEDCONFIRMEDPARTIALLY_RECEIVEDRECEIVEDSENT
Example request
curl -X GET https://api.dawatrack.com/partner-api/v1/purchase-orders/ \
-H "Authorization: Bearer $DAWATRACK_TOKEN"
import requests
token = "..." # from POST /oauth/token/
response = requests.get(
"https://api.dawatrack.com/partner-api/v1/purchase-orders/",
headers={"Authorization": f"Bearer {token}"},
)
response.raise_for_status()
print(response.json())
const token = "..."; // from POST /oauth/token/
const response = await fetch("https://api.dawatrack.com/partner-api/v1/purchase-orders/", {
method: "GET",
headers: {
Authorization: `Bearer ${token}`,
},
});
console.log(await response.json());
Response fields
A page of results. These are the fields of each item in results. See Pagination.
-
order_idinteger -
po_numberstring -
pharmacy_namestringThe facility's name.
-
statusstring -
order_datedate -
expected_deliverydate or null -
total_amountstring -
confirmed_delivery_datedate or null -
carrier_namestring -
tracking_referencestring -
notesstring -
linesarray of objects-
line_idinteger -
medicine_namestringThe product's name.
-
quantity_orderedinteger -
unit_pricestring -
quantity_confirmedinteger -
batch_numberstringThe batch or lot number.
-
expiry_datedate or nullThe batch's expiry date.
-
notestring
-
Example response
{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"order_id": 1,
"po_number": "po_number",
"pharmacy_name": "Pharmacy A",
"status": "OPEN",
"order_date": "2026-10-10",
"expected_delivery": "2026-10-10",
"total_amount": "total_amount",
"confirmed_delivery_date": "2026-10-10",
"carrier_name": "carrier_name",
"tracking_reference": "tracking_reference",
"notes": "notes",
"lines": [
{}
]
}
]
}
Status codes
200 | OK |
401 | No valid access token |
403 | Your credential lacks the scope, partner type or environment this needs |
429 | Rate limit exceeded |
Get an order
https://api.dawatrack.com/partner-api/v1/purchase-orders/{id}/
One order with its lines; each line has a line_id you declare delivery against.
orders:read
Limit 5,000 per day
An order placed with another supplier is 404.
Path parameters
-
idinteger Required
Example request
curl -X GET https://api.dawatrack.com/partner-api/v1/purchase-orders/42/ \
-H "Authorization: Bearer $DAWATRACK_TOKEN"
import requests
token = "..." # from POST /oauth/token/
response = requests.get(
"https://api.dawatrack.com/partner-api/v1/purchase-orders/42/",
headers={"Authorization": f"Bearer {token}"},
)
response.raise_for_status()
print(response.json())
const token = "..."; // from POST /oauth/token/
const response = await fetch("https://api.dawatrack.com/partner-api/v1/purchase-orders/42/", {
method: "GET",
headers: {
Authorization: `Bearer ${token}`,
},
});
console.log(await response.json());
Response fields
-
order_idinteger -
po_numberstring -
pharmacy_namestringThe facility's name.
-
statusstring -
order_datedate -
expected_deliverydate or null -
total_amountstring -
confirmed_delivery_datedate or null -
carrier_namestring -
tracking_referencestring -
notesstring -
linesarray of objects-
line_idinteger -
medicine_namestringThe product's name.
-
quantity_orderedinteger -
unit_pricestring -
quantity_confirmedinteger -
batch_numberstringThe batch or lot number.
-
expiry_datedate or nullThe batch's expiry date.
-
notestring
-
Example response
{
"order_id": 1,
"po_number": "po_number",
"pharmacy_name": "Pharmacy A",
"status": "OPEN",
"order_date": "2026-10-10",
"expected_delivery": "2026-10-10",
"total_amount": "total_amount",
"confirmed_delivery_date": "2026-10-10",
"carrier_name": "carrier_name",
"tracking_reference": "tracking_reference",
"notes": "notes",
"lines": [
{
"line_id": 1,
"medicine_name": "Amoxicillin 500 mg capsules",
"quantity_ordered": 1,
"unit_price": "unit_price",
"quantity_confirmed": 1,
"batch_number": "BTH-2026-041",
"expiry_date": "2026-10-10",
"note": "Contract CP-2026-11"
}
]
}
Status codes
200 | OK |
401 | No valid access token |
403 | Your credential lacks the scope, partner type or environment this needs |
429 | Rate limit exceeded |
Confirm an order
https://api.dawatrack.com/partner-api/v1/purchase-orders/{id}/confirm/
Accept an order that is waiting for you (SENT).
orders:write
Production credentials only
Limit 5,000 per day
The pharmacy sees it confirmed. An order that isn't waiting is 400. Needs orders:write; production credentials only.
Path parameters
-
idinteger Required
Example request
curl -X POST https://api.dawatrack.com/partner-api/v1/purchase-orders/42/confirm/ \
-H "Authorization: Bearer $DAWATRACK_TOKEN" \
-H "Idempotency-Key: $(uuidgen)"
import uuid
import requests
token = "..." # from POST /oauth/token/
response = requests.post(
"https://api.dawatrack.com/partner-api/v1/purchase-orders/42/confirm/",
headers={"Authorization": f"Bearer {token}", "Idempotency-Key": str(uuid.uuid4())},
)
response.raise_for_status()
print(response.json())
const token = "..."; // from POST /oauth/token/
const response = await fetch("https://api.dawatrack.com/partner-api/v1/purchase-orders/42/confirm/", {
method: "POST",
headers: {
Authorization: `Bearer ${token}`,
"Idempotency-Key": crypto.randomUUID(),
},
});
console.log(await response.json());
Response fields
-
order_idinteger -
po_numberstring -
pharmacy_namestringThe facility's name.
-
statusstring -
order_datedate -
expected_deliverydate or null -
total_amountstring -
confirmed_delivery_datedate or null -
carrier_namestring -
tracking_referencestring -
notesstring -
linesarray of objects-
line_idinteger -
medicine_namestringThe product's name.
-
quantity_orderedinteger -
unit_pricestring -
quantity_confirmedinteger -
batch_numberstringThe batch or lot number.
-
expiry_datedate or nullThe batch's expiry date.
-
notestring
-
Example response
{
"order_id": 1,
"po_number": "po_number",
"pharmacy_name": "Pharmacy A",
"status": "OPEN",
"order_date": "2026-10-10",
"expected_delivery": "2026-10-10",
"total_amount": "total_amount",
"confirmed_delivery_date": "2026-10-10",
"carrier_name": "carrier_name",
"tracking_reference": "tracking_reference",
"notes": "notes",
"lines": [
{
"line_id": 1,
"medicine_name": "Amoxicillin 500 mg capsules",
"quantity_ordered": 1,
"unit_price": "unit_price",
"quantity_confirmed": 1,
"batch_number": "BTH-2026-041",
"expiry_date": "2026-10-10",
"note": "Contract CP-2026-11"
}
]
}
Status codes
200 | OK |
400 | The request is invalid, for example a malformed GTIN or a missing field |
401 | No valid access token |
403 | Your credential lacks the scope, partner type or environment this needs |
409 | Conflict: a request with this Idempotency-Key is in progress, or the record already exists |
429 | Rate limit exceeded |
Reject an order
https://api.dawatrack.com/partner-api/v1/purchase-orders/{id}/reject/
Turn down an order that is waiting for you; the pharmacy sees it cancelled, with your reason.
orders:write
Production credentials only
Limit 5,000 per day
Path parameters
-
idinteger Required
Request body
JSON. Send Content-Type: application/json.
-
reasonstring Optional
Example request
curl -X POST https://api.dawatrack.com/partner-api/v1/purchase-orders/42/reject/ \
-H "Authorization: Bearer $DAWATRACK_TOKEN" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"reason": "Out of stock until next month"
}'
import uuid
import requests
token = "..." # from POST /oauth/token/
response = requests.post(
"https://api.dawatrack.com/partner-api/v1/purchase-orders/42/reject/",
headers={"Authorization": f"Bearer {token}", "Idempotency-Key": str(uuid.uuid4())},
json={
"reason": "Out of stock until next month"
},
)
response.raise_for_status()
print(response.json())
const token = "..."; // from POST /oauth/token/
const response = await fetch("https://api.dawatrack.com/partner-api/v1/purchase-orders/42/reject/", {
method: "POST",
headers: {
Authorization: `Bearer ${token}`,
"Idempotency-Key": crypto.randomUUID(),
"Content-Type": "application/json",
},
body: JSON.stringify({
"reason": "Out of stock until next month"
}),
});
console.log(await response.json());
Response fields
-
order_idinteger -
po_numberstring -
pharmacy_namestringThe facility's name.
-
statusstring -
order_datedate -
expected_deliverydate or null -
total_amountstring -
confirmed_delivery_datedate or null -
carrier_namestring -
tracking_referencestring -
notesstring -
linesarray of objects-
line_idinteger -
medicine_namestringThe product's name.
-
quantity_orderedinteger -
unit_pricestring -
quantity_confirmedinteger -
batch_numberstringThe batch or lot number.
-
expiry_datedate or nullThe batch's expiry date.
-
notestring
-
Example response
{
"order_id": 1,
"po_number": "po_number",
"pharmacy_name": "Pharmacy A",
"status": "OPEN",
"order_date": "2026-10-10",
"expected_delivery": "2026-10-10",
"total_amount": "total_amount",
"confirmed_delivery_date": "2026-10-10",
"carrier_name": "carrier_name",
"tracking_reference": "tracking_reference",
"notes": "notes",
"lines": [
{
"line_id": 1,
"medicine_name": "Amoxicillin 500 mg capsules",
"quantity_ordered": 1,
"unit_price": "unit_price",
"quantity_confirmed": 1,
"batch_number": "BTH-2026-041",
"expiry_date": "2026-10-10",
"note": "Contract CP-2026-11"
}
]
}
Status codes
200 | OK |
400 | The request is invalid, for example a malformed GTIN or a missing field |
401 | No valid access token |
403 | Your credential lacks the scope, partner type or environment this needs |
409 | Conflict: a request with this Idempotency-Key is in progress, or the record already exists |
429 | Rate limit exceeded |
Declare delivery
https://api.dawatrack.com/partner-api/v1/purchase-orders/{id}/delivery/
Say what you're sending: per line the units, batch and expiry, and the delivery date, carrier and tracking.
orders:write
Production credentials only
Limit 5,000 per day
Each line with a batch_number and a quantity becomes a SHIP event in the traceability ledger; when the pharmacy receives that line, its receipt links to it. Declaring again with a different batch or quantity writes a correcting event.
Quantities are capped at what was ordered. Lines you don't list keep what you declared before; a line_id not on the order is 400.
A product you make whose PPB registration is on hold can't be declared (400): set its quantity to 0 to deliver the rest.
Declaring on an order that was waiting confirms it. Same rules as the supplier portal.
Path parameters
-
idinteger Required
Request body
JSON. Send Content-Type: application/json.
-
linesarray of objects RequiredLines not listed keep what was declared before.
-
line_idinteger Required -
quantityinteger RequiredUnits sent; capped at what was ordered.
-
batch_numberstring OptionalThe batch or lot number.
-
expiry_datedate or null OptionalThe batch's expiry date.
-
notestring Optional
-
-
delivery_datedate or null Optional -
carrier_namestring Optional -
tracking_referencestring Optional -
notesstring Optional
Example request
curl -X POST https://api.dawatrack.com/partner-api/v1/purchase-orders/42/delivery/ \
-H "Authorization: Bearer $DAWATRACK_TOKEN" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"lines": [
{
"line_id": 123,
"quantity": 20,
"batch_number": "BTH-2026-041",
"expiry_date": "2028-01-31"
}
],
"delivery_date": "2026-11-02",
"carrier_name": "G4S",
"tracking_reference": "TRK-99123"
}'
import uuid
import requests
token = "..." # from POST /oauth/token/
response = requests.post(
"https://api.dawatrack.com/partner-api/v1/purchase-orders/42/delivery/",
headers={"Authorization": f"Bearer {token}", "Idempotency-Key": str(uuid.uuid4())},
json={
"lines": [
{
"line_id": 123,
"quantity": 20,
"batch_number": "BTH-2026-041",
"expiry_date": "2028-01-31"
}
],
"delivery_date": "2026-11-02",
"carrier_name": "G4S",
"tracking_reference": "TRK-99123"
},
)
response.raise_for_status()
print(response.json())
const token = "..."; // from POST /oauth/token/
const response = await fetch("https://api.dawatrack.com/partner-api/v1/purchase-orders/42/delivery/", {
method: "POST",
headers: {
Authorization: `Bearer ${token}`,
"Idempotency-Key": crypto.randomUUID(),
"Content-Type": "application/json",
},
body: JSON.stringify({
"lines": [
{
"line_id": 123,
"quantity": 20,
"batch_number": "BTH-2026-041",
"expiry_date": "2028-01-31"
}
],
"delivery_date": "2026-11-02",
"carrier_name": "G4S",
"tracking_reference": "TRK-99123"
}),
});
console.log(await response.json());
Response fields
-
order_idinteger -
po_numberstring -
pharmacy_namestringThe facility's name.
-
statusstring -
order_datedate -
expected_deliverydate or null -
total_amountstring -
confirmed_delivery_datedate or null -
carrier_namestring -
tracking_referencestring -
notesstring -
linesarray of objects-
line_idinteger -
medicine_namestringThe product's name.
-
quantity_orderedinteger -
unit_pricestring -
quantity_confirmedinteger -
batch_numberstringThe batch or lot number.
-
expiry_datedate or nullThe batch's expiry date.
-
notestring
-
Example response
{
"order_id": 1,
"po_number": "po_number",
"pharmacy_name": "Pharmacy A",
"status": "OPEN",
"order_date": "2026-10-10",
"expected_delivery": "2026-10-10",
"total_amount": "total_amount",
"confirmed_delivery_date": "2026-10-10",
"carrier_name": "carrier_name",
"tracking_reference": "tracking_reference",
"notes": "notes",
"lines": [
{
"line_id": 1,
"medicine_name": "Amoxicillin 500 mg capsules",
"quantity_ordered": 1,
"unit_price": "unit_price",
"quantity_confirmed": 1,
"batch_number": "BTH-2026-041",
"expiry_date": "2026-10-10",
"note": "Contract CP-2026-11"
}
]
}
Status codes
200 | OK |
400 | The request is invalid, for example a malformed GTIN or a missing field |
401 | No valid access token |
403 | Your credential lacks the scope, partner type or environment this needs |
409 | Conflict: a request with this Idempotency-Key is in progress, or the record already exists |
429 | Rate limit exceeded |
Partner API v1. The API reference is generated from the API's own code.