Skip to main content

Create Order

POST /api/v1/orders

Create an order and send a WhatsApp confirmation message to the customer.

Request Body

{
"externalOrderId": "EO-12345",
"customerName": "Ahmed Mohamed",
"customerPhone": "201234567890",
"customerAddress": "15 Tahrir St, Cairo",
"subtotal": 150,
"shippingCost": 25,
"totalCost": 175,
"currency": "EGP",
"note": "Gift wrap",
"items": [
{
"productName": "iPhone Case",
"variantName": "Black / Large",
"quantity": 2,
"unitPrice": 75,
"totalPrice": 150
}
]
}

Body Parameters

FieldTypeRequiredDescription
externalOrderIdstringYesYour unique order identifier
customerNamestringYesCustomer's full name
customerPhonestringYesCustomer's phone number (with country code, no +)
customerAddressstringNoDelivery address
subtotalnumberYesSubtotal before shipping
shippingCostnumberYesShipping cost
totalCostnumberYesTotal order cost
currencystringYesCurrency code (e.g., EGP)
notestringNoAdditional notes
itemsarrayYesOrder items (see below)

Item Fields

FieldTypeRequiredDescription
productNamestringYesProduct name
variantNamestringNoVariant description
quantitynumberYesQuantity ordered
unitPricenumberYesPrice per unit
totalPricenumberYesTotal price for this item

Headers

HeaderRequiredDescription
X-API-KeyYesYour API key (starts with ek_)
Content-TypeYesapplication/json
Accept-LanguageNoen (default) or ar

Response

201 — Order created and WhatsApp confirmation sent

{
"id": "ord_abc123",
"externalOrderId": "EO-12345",
"customerName": "Ahmed Mohamed",
"customerPhone": "201234567890",
"customerAddress": "15 Tahrir St, Cairo",
"subtotal": 150,
"shippingCost": 25,
"totalCost": 175,
"currency": "EGP",
"status": "pending",
"customerAction": "approved",
"deliveryStatus": "sent",
"items": [
{
"id": "item_xyz789",
"productName": "iPhone Case",
"variantName": "Black / Large",
"quantity": 2,
"unitPrice": 75,
"totalPrice": 150
}
],
"createdAt": "2026-04-20T10:23:52.772Z",
"updatedAt": "2026-04-20T10:23:52.772Z"
}

400 — WhatsApp send rejected by Meta

Returned when Meta synchronously rejects the message send (e.g., recipient not in the test allowlist, template paused, template not approved, invalid credentials). The order is still persisted with status: failed, deliveryStatus: failed, and the same failureReason + errorCode you can later read via GET /orders/:id.

The HTTP status line carries 400 Bad Request; the response body contains:

{
"message": "Failed to send WhatsApp message: Recipient phone number not in allowed list",
"errorCode": 131030,
"failureReason": "Recipient phone number not in allowed list"
}
FieldTypeDescription
errorCodeinteger | nullNumeric error code from Meta. Use this for programmatic handling — it is stable and documented. See the common error codes table under order.failed. May be null if the failure occurred before reaching Meta (e.g. internal validation).
failureReasonstringHuman-readable error text from Meta. Display only — do not match on the text, Meta may change the wording or language.

:::tip Sync vs async failures This 400 response is returned only for synchronous Meta rejections — when Meta refuses the send attempt during the request. Failures that happen after Meta accepted the message (e.g., the recipient's device is offline and delivery times out hours later) are reported via the order.failed webhook, not this endpoint. :::

Try It

POSThttps://api.easyconfirm.net/api/v1/orders

Example

curl -X POST https://api.easyconfirm.net/api/v1/orders \
-H "Content-Type: application/json" \
-H "X-API-Key: ek_your_api_key_here" \
-d '{
"externalOrderId": "EO-12345",
"customerName": "Ahmed Mohamed",
"customerPhone": "201234567890",
"customerAddress": "15 Tahrir St, Cairo",
"subtotal": 150,
"shippingCost": 25,
"totalCost": 175,
"currency": "EGP",
"items": [
{
"productName": "iPhone Case",
"variantName": "Black / Large",
"quantity": 2,
"unitPrice": 75,
"totalPrice": 150
}
]
}'