EZWhatsApp Docs

Agency-ready reference

Build against the current EZWhatsApp Platform API.

This is the public implementation reference for agencies and developers building client WhatsApp workflows on EZWhatsApp. It documents the current support-inbox-first API surface, the line-token Channel API, workspace operations, webhooks, examples, and the product boundaries developers must not cross.

Quickstart

1. Workspace login

Log in as an owner or admin.

Workspace routes use a Cognito workspace ID token. Use it for admin/operator routes such as line token rotation, inbox reads, and workspace sends.

curl -X POST 'https://app.ezw.solutions/api/auth/login' \
  -H 'Content-Type: application/json' \
  -d '{
    "email": "owner@example.com",
    "password": "password"
  }'
2. Create line token

Create or rotate a line-scoped API token.

Channel API routes use a line API token that starts with ezw_line_. It is scoped to exactly one WhatsApp line.

curl -X POST 'https://app.ezw.solutions/api/lines/{lineId}/api-token' \
  -H 'Authorization: Bearer {idToken}'
3. Check health

Confirm the line is sendable before sending.

Do not flatten health into connected or disconnected. The response separates lifecycle, effective send state, and sendability.

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

Queue a message with an idempotency key.

The API returns 202 because delivery is asynchronous. Workers reconcile provider delivery later.

curl -X POST 'https://app.ezw.solutions/api/v1/messages/text' \
  -H 'Authorization: Bearer {lineApiToken}' \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: client-order-123' \
  -d '{
    "to": "+972501234567",
    "body": "Your order is ready"
  }'

Base URLs

Production

Workspace API: https://app.ezw.solutions
Channel API v1: https://app.ezw.solutions/api/v1

Local operator runtime

Workspace API: http://127.0.0.1:3010
Channel API v1: http://127.0.0.1:3010/api/v1

Authentication

API family Token Use for Do not use for
Channel API v1 Authorization: Bearer ezw_line_... Machine-to-machine health, text sends, URL media sends, and line webhook configuration for one line. Workspace admin/operator routes, inbox UI actions, team management, or cross-line operations.
Workspace API Authorization: Bearer {idToken} Logged-in owner/admin/operator actions: line token management, QR, inbox, assignments, notes, image sends, signed media reads. Channel API v1 routes.

Current support matrix

Capability Endpoint Auth Status
Check line health GET /api/v1/health Line API token Supported.
Send direct text POST /api/v1/messages/text Line API token Supported, including optional CTA URL button.
Send URL media POST /api/v1/messages/media Line API token Supported for external URL image, video, audio, and document.
Configure line webhooks GET/POST /api/v1/webhooks Line API token Supported for current line.
Configure webhooks from workspace GET/POST /api/lines/{lineId}/webhooks Workspace ID token Supported for allowed owner/admin users.
Create or rotate line token POST /api/lines/{lineId}/api-token Workspace ID token Supported for users allowed to manage the line.
Workspace reply POST /api/lines/{lineId}/send Workspace ID token Supported for text and one image attachment.
Read inbox data GET /api/conversations, GET /api/conversations/{conversationId}/messages Workspace ID token Supported with tenant and line visibility checks.
Fetch archived media GET /api/attachments/{attachmentId}/url Workspace ID token Supported through short-lived signed URLs.
Live update hints GET /api/live/stream Workspace ID token Supported through SSE hints. Refetch durable APIs for truth.

Check channel health

Use this before sending and before diagnosing client automation failures. wakeup=false makes the check read-only.

curl -X GET 'https://app.ezw.solutions/api/v1/health?wakeup=false&channel_type=web' \
  -H 'Authorization: Bearer {lineApiToken}'
{
  "channelId": "{lineId}",
  "channelType": "web",
  "wakeupRequested": false,
  "health": {
    "status": {
      "code": 4,
      "text": "AUTH"
    }
  },
  "line": {
    "displayName": "Billing",
    "phoneNumber": "+972...",
    "lifecycleState": "connected",
    "effectiveSendState": "sendable",
    "sendable": true
  }
}

Send text with Channel API v1

Use this for machine-to-machine sends from the line resolved by the line API token. Use exactly one target: to or conversationId.

curl -X POST 'https://app.ezw.solutions/api/v1/messages/text' \
  -H 'Authorization: Bearer {lineApiToken}' \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: send-once-123' \
  -d '{
    "to": "+972501234567",
    "body": "Test message",
    "ctaUrlButton": {
      "displayText": "Open offer",
      "url": "https://example.com/offers/123"
    }
  }'
Field Required Notes
to Conditional Direct recipient phone number. Use one of to or conversationId.
conversationId or conversation_id Conditional Use this for webhook replies when available. Do not derive phone numbers from provider-specific ids.
body Yes Text body. Empty strings are rejected.
ctaUrlButton No Requires displayText or text, plus an HTTP/HTTPS URL.
Idempotency-Key Recommended Header takes precedence over body idempotencyKey.

Send URL media with Channel API v1

Use this when the media is already available at a public HTTP/HTTPS URL. Channel API media is URL-only.

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

Workspace API essentials

Workspace routes act as logged-in users. They enforce organization scope, line visibility, and membership permissions.

Send workspace 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-send-001' \
  -d '{
    "conversationId": "{conversationId}",
    "bodyText": "Thanks, I am checking this now."
  }'

Send one workspace image

curl -X POST 'https://app.ezw.solutions/api/lines/{lineId}/send' \
  -H 'Authorization: Bearer {idToken}' \
  -H 'Idempotency-Key: image-send-001' \
  -F 'conversationId={conversationId}' \
  -F 'bodyText=Optional caption text' \
  -F 'media=@/absolute/path/photo.jpg;type=image/jpeg'

Webhooks

Webhooks let client systems receive durable event deliveries for the configured line. Configure by line token or by workspace token.

Line token

Configure current 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
  }'
Workspace token

Configure webhook for a managed line

curl -X POST 'https://app.ezw.solutions/api/lines/{lineId}/webhooks' \
  -H 'Authorization: Bearer {idToken}' \
  -H 'Content-Type: application/json' \
  -d '{
    "targetUrl": "https://agency.example.com/ezw/webhook",
    "events": ["messages.post", "statuses.post"],
    "enabled": true
  }'

Webhook deliveries are sent as JSON with X-EZW-Webhook-Event, X-EZW-Line-Id, X-EZW-Webhook-Id, and X-EZW-Delivery-Id headers. Return any 2xx status to accept a delivery.

Read the webhook guide

Read inbox data

Use workspace tokens for inbox reads. SSE events are hints only; clients must refetch durable DB-backed APIs.

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

curl -N 'https://app.ezw.solutions/api/live/stream' \
  -H 'Authorization: Bearer {idToken}' \
  -H 'Accept: text/event-stream'

Common status codes

Status Meaning
200Read succeeded.
201Token or webhook configuration was created or updated.
202Send was durably queued or an idempotent attempt already existed.
400Invalid query, payload, target, media, webhook, or idempotency key.
401Missing or invalid bearer token.
403Authenticated actor is not allowed to perform the operation.
404Tenant-scoped resource was not visible or does not exist.
409Optimistic conflict or line not currently sendable.
501Required source of truth or media bucket is not configured.

Non-negotiable implementation boundaries

  • The API is for support inbox workflows, client notifications, and scoped customer-admin campaign workflows, not cold outbound tooling.
  • Every customer-owned record is organization-scoped.
  • Line API tokens are scoped to exactly one WhatsApp line.
  • Outbound sends are idempotent and asynchronous.
  • Provider echoes must not be treated as authoritative assignment or ownership state.
  • Redis and live events are never the source of truth. Refetch DB-backed APIs.
  • Session credentials and provider runtime details stay behind EZWhatsApp provider contracts.