Check health before sending
curl 'https://app.ezw.solutions/api/v1/health?wakeup=false&channel_type=web' \
-H 'Authorization: Bearer {lineApiToken}'
Send text
Direct phone recipient
curl -X POST 'https://app.ezw.solutions/api/v1/messages/text' \
-H 'Authorization: Bearer {lineApiToken}' \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: order-123-ready' \
-d '{
"to": "+972501234567",
"body": "Your order is ready.",
"ctaUrlButton": {
"displayText": "Open order",
"url": "https://store.example.com/orders/123"
}
}'
Existing conversation
curl -X POST 'https://app.ezw.solutions/api/v1/messages/text' \
-H 'Authorization: Bearer {lineApiToken}' \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: webhook-reply-123' \
-d '{
"conversationId": "{conversationId}",
"body": "Thanks, I am checking this now."
}'
WhatsApp group JID
curl -X POST 'https://app.ezw.solutions/api/v1/messages/text' \
-H 'Authorization: Bearer {lineApiToken}' \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: group-update-123' \
-d '{
"groupId": "120363012345678901@g.us",
"body": "Group update"
}'
Configure a line webhook
curl -X POST 'https://app.ezw.solutions/api/v1/webhooks' \
-H 'Authorization: Bearer {lineApiToken}' \
-H 'Content-Type: application/json' \
-d '{
"targetUrl": "https://agency.example.com/ezw/webhook",
"events": ["messages.post", "statuses.post", "chats.post"],
"payloadFormat": "whapi",
"enabled": true,
"persistent": true
}'
Send as a workspace user
Text reply
curl -X POST 'https://app.ezw.solutions/api/lines/{lineId}/send' \
-H 'Authorization: Bearer {idToken}' \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: workspace-reply-123' \
-d '{
"conversationId": "{conversationId}",
"bodyText": "Thanks, I am checking this now."
}'
Direct phone send
curl -X POST 'https://app.ezw.solutions/api/lines/{lineId}/send' \
-H 'Authorization: Bearer {idToken}' \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: workspace-direct-123' \
-d '{
"recipientPhoneNumber": "+972501234567",
"bodyText": "Hello from the workspace."
}'
One uploaded image
curl -X POST 'https://app.ezw.solutions/api/lines/{lineId}/send' \
-H 'Authorization: Bearer {idToken}' \
-H 'Idempotency-Key: image-send-123' \
-F 'conversationId={conversationId}' \
-F 'bodyText=Attached photo' \
-F 'media=@/absolute/path/photo.jpg;type=image/jpeg'
Forward stored message
curl -X POST 'https://app.ezw.solutions/api/lines/{lineId}/send' \
-H 'Authorization: Bearer {idToken}' \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: forward-123' \
-d '{
"recipientPhoneNumber": "+972501234567",
"forwardedFromMessageId": "{messageId}"
}'
Campaigns
Create draft
curl -X POST 'https://app.ezw.solutions/api/campaigns' \
-H 'Authorization: Bearer {idToken}' \
-F 'name=May offers' \
-F 'lineId={lineId}' \
-F 'bodyText=Hello, {name}. Your offer is ready.' \
-F 'recipientsCsv=phone,name
+972501234567,Dana Levi' \
-F 'sourceFilename=may-offers.csv' \
-F 'minDelaySeconds=30' \
-F 'maxDelaySeconds=120' \
-F 'hourlyCap=60'
Launch and inspect
curl 'https://app.ezw.solutions/api/campaigns?limit=100' \
-H 'Authorization: Bearer {idToken}'
curl -X POST 'https://app.ezw.solutions/api/campaigns/{campaignId}/launch' \
-H 'Authorization: Bearer {idToken}'
curl 'https://app.ezw.solutions/api/campaigns/{campaignId}' \
-H 'Authorization: Bearer {idToken}'
Read inbox data
curl 'https://app.ezw.solutions/api/conversations?lineId={lineId}&limit=25' \
-H 'Authorization: Bearer {idToken}'
curl 'https://app.ezw.solutions/api/conversations/{conversationId}/messages?limit=50' \
-H 'Authorization: Bearer {idToken}'
Record internal team visibility
curl -X POST 'https://app.ezw.solutions/api/conversations/{conversationId}/messages/seen' \
-H 'Authorization: Bearer {idToken}' \
-H 'Content-Type: application/json' \
-d '{"messageIds":["{inboundMessageId}"]}'
Submit 1–100 unique visible inbound message UUIDs from the same conversation after they are displayed to an operator. This records internal team seen state, not customer read or delivery status.
JavaScript fetch example
const response = await fetch("https://app.ezw.solutions/api/v1/messages/text", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.EZW_LINE_API_TOKEN}`,
"Content-Type": "application/json",
"Idempotency-Key": `order:${order.id}:ready`
},
body: JSON.stringify({
to: order.customerPhone,
body: `Your order ${order.number} is ready.`,
ctaUrlButton: {
displayText: "Open order",
url: `https://store.example.com/orders/${order.id}`
}
})
});
if (!response.ok) {
throw new Error(`EZWhatsApp send failed: ${response.status} ${await response.text()}`);
}
const queued = await response.json();
Webhook receiver example
export async function POST(request) {
const deliveryId = request.headers.get("x-ezw-delivery-id");
const event = request.headers.get("x-ezw-webhook-event");
const lineId = request.headers.get("x-ezw-line-id");
const payload = await request.json();
if (!deliveryId || !event || !lineId) {
return new Response("missing EZWhatsApp headers", { status: 400 });
}
if (await alreadyProcessed(deliveryId)) {
return new Response("duplicate accepted", { status: 200 });
}
await saveEvent({ deliveryId, event, lineId, payload });
return new Response("accepted", { status: 200 });
}