EZWhatsApp Examples

Current examples

Use these examples as the agency implementation baseline.

These examples intentionally cover only current Platform routes. They avoid old `/messages`, device, group, channel, queue, template-message, and official WABA examples that are not part of the current EZWhatsApp API contract.

Check health before sending

curl 'https://app.ezw.solutions/api/v1/health?wakeup=false&channel_type=web' \
  -H 'Authorization: Bearer {lineApiToken}'

Send text with optional CTA URL button

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"
    }
  }'

Send URL media

Channel API media must be reachable through an external HTTP/HTTPS URL.

curl -X POST 'https://app.ezw.solutions/api/v1/messages/media' \
  -H 'Authorization: Bearer {lineApiToken}' \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: invoice-123' \
  -d '{
    "to": "+972501234567",
    "type": "document",
    "media": {
      "url": "https://cdn.example.com/invoices/123.pdf",
      "mime_type": "application/pdf",
      "filename": "invoice-123.pdf"
    },
    "caption": "Invoice 123"
  }'

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."
  }'

One 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'

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}'

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 });
}