IllyVoIPdevelopers Back to IllyVoIP

WhatsApp

Send a WhatsApp message

Send a WhatsApp message

Try in API Playground ↗Sign in to prepare and run this request.
POST/api/v1/whatsapp/messages

Before you start

Connect your business and number in Portal → WhatsApp → Numbers & accounts first. Use an account-owner Production API key. Create templates in the Portal.

Result

Send from a number connected and activated in the Portal. Provide number_id, recipient and text, an approved template or ready media. One request calculates the current fee and queues the message; quote_id is optional for a previously quoted exact payload. max_platform_fee is an optional EUR decimal string limiting only the IllyVoIP fee, not Meta charges or temporary wallet hold rounding.

Meta bills separately. Idempotency-Key is required: retry with the identical key and body; never create a replacement for an unknown result. 202 means queued, not delivered. IllyVoIP reserves its fee before dispatch and charges delivered outbound messages only.

Unknown outcomes retain their hold. Consent, service-window, ownership, account and balance checks still apply.

Charges and safe retries

Inspect uncertain operations before retrying. A queued message is not delivered. IllyVoIP reserves its fee at queue admission and charges only delivered outbound messages; incoming messages are free.

Authentication

Send your account API key in the X-Api-Key header. Keep it on your server; never embed it in browser code.

Request examples

Replace the example values with your own inputs. Examples do not run on this page. Production requests can change your account or incur charges.

cURL

cURL
curl -X POST "https://app.illyvoip.com/api/v1/whatsapp/messages" \
  -H "X-Api-Key: ${ILLYVOIP_API_KEY:?Set ILLYVOIP_API_KEY}" \
  -H "Idempotency-Key: YOUR_UNIQUE_IDEMPOTENCY_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "number_id": "YOUR_NUMBER_ID",
    "to": "YOUR_TO",
    "type": "text",
    "text": "YOUR_MESSAGE_TEXT"
}'

Node.js

Node.js
const response = await fetch("https://app.illyvoip.com/api/v1/whatsapp/messages", {
  method: "POST",
  headers: {
    "X-Api-Key": process.env.ILLYVOIP_API_KEY,
    "Idempotency-Key": "YOUR_UNIQUE_IDEMPOTENCY_KEY",
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    "number_id": "YOUR_NUMBER_ID",
    "to": "YOUR_TO",
    "type": "text",
    "text": "YOUR_MESSAGE_TEXT"
})
});

const data = await response.json();
console.log(response.status, data);

PHP

PHP
<?php
$ch = curl_init('https://app.illyvoip.com/api/v1/whatsapp/messages');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'X-Api-Key: ' . getenv('ILLYVOIP_API_KEY'),
        'Idempotency-Key: YOUR_UNIQUE_IDEMPOTENCY_KEY',
        'Content-Type: application/json'
    ],
    CURLOPT_POSTFIELDS => '{
    "number_id": "YOUR_NUMBER_ID",
    "to": "YOUR_TO",
    "type": "text",
    "text": "YOUR_MESSAGE_TEXT"
}',
]);

$response = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

echo $status . PHP_EOL;
echo $response;

Python

Python
import os
import json
import requests

response = requests.request(
    "POST",
    "https://app.illyvoip.com/api/v1/whatsapp/messages",
    headers={
        "X-Api-Key": os.environ["ILLYVOIP_API_KEY"],
        "Idempotency-Key": "YOUR_UNIQUE_IDEMPOTENCY_KEY",
        'Content-Type': 'application/json'
    },
    json=json.loads("{\n    \"number_id\": \"YOUR_NUMBER_ID\",\n    \"to\": \"YOUR_TO\",\n    \"type\": \"text\",\n    \"text\": \"YOUR_MESSAGE_TEXT\"\n}"),
)

print(response.status_code)
print(response.json())

Node.js examples run on the server (Node.js 22.17+). Python examples require requests; PHP examples require cURL. Set the environment variables referenced in each example.

Request parameters

Header parameters

Idempotency-Keystringrequired
pattern "^[A-Za-z0-9._:-]{8,128}$"

Request body

application/json

Body required.

oneOf schema alternatives

number_idintegerrequired
minimum 1
tostringrequired
pattern "^\\+[1-9][0-9]{7,14}$"
typestringrequired
enum ["text"]
textstringrequired
minLength 1maxLength 4096
quote_idstringoptional
pattern "^[a-f0-9]{48}$"
max_platform_feestringoptional

Maximum IllyVoIP platform fee in EUR. Meta charges are separate.

pattern "^(0|[1-9][0-9]{0,5})(\\.[0-9]{1,8})?$"

Additional properties: not allowed.

number_idintegerrequired
minimum 1
tostringrequired
pattern "^\\+[1-9][0-9]{7,14}$"
typestringrequired
enum ["template"]
template_idintegerrequired
minimum 1
parametersarray<string>required
maxItems 100
View nested fields

Array items

Type: string

Constraints
{
  "maxLength": 4096
}
named_parametersobjectoptional
header_parametersarray<string>optional
maxItems 100
View nested fields

Array items

Type: string

Constraints
{
  "maxLength": 4096
}
named_header_parametersobjectoptional
quote_idstringoptional
pattern "^[a-f0-9]{48}$"
max_platform_feestringoptional

Maximum IllyVoIP platform fee in EUR. Meta charges are separate.

pattern "^(0|[1-9][0-9]{0,5})(\\.[0-9]{1,8})?$"

Additional properties: not allowed.

number_idintegerrequired
minimum 1
tostringrequired
pattern "^\\+[1-9][0-9]{7,14}$"
typestringrequired
enum ["image"]
media_idstringrequired
pattern "^[a-f0-9]{48}$"
captionstringoptional
maxLength 1024
quote_idstringoptional
pattern "^[a-f0-9]{48}$"
max_platform_feestringoptional

Maximum IllyVoIP platform fee in EUR. Meta charges are separate.

pattern "^(0|[1-9][0-9]{0,5})(\\.[0-9]{1,8})?$"

Additional properties: not allowed.

number_idintegerrequired
minimum 1
tostringrequired
pattern "^\\+[1-9][0-9]{7,14}$"
typestringrequired
enum ["audio"]
media_idstringrequired
pattern "^[a-f0-9]{48}$"
quote_idstringoptional
pattern "^[a-f0-9]{48}$"
max_platform_feestringoptional

Maximum IllyVoIP platform fee in EUR. Meta charges are separate.

pattern "^(0|[1-9][0-9]{0,5})(\\.[0-9]{1,8})?$"

Additional properties: not allowed.

number_idintegerrequired
minimum 1
tostringrequired
pattern "^\\+[1-9][0-9]{7,14}$"
typestringrequired
enum ["video"]
media_idstringrequired
pattern "^[a-f0-9]{48}$"
captionstringoptional
maxLength 1024
quote_idstringoptional
pattern "^[a-f0-9]{48}$"
max_platform_feestringoptional

Maximum IllyVoIP platform fee in EUR. Meta charges are separate.

pattern "^(0|[1-9][0-9]{0,5})(\\.[0-9]{1,8})?$"

Additional properties: not allowed.

number_idintegerrequired
minimum 1
tostringrequired
pattern "^\\+[1-9][0-9]{7,14}$"
typestringrequired
enum ["document"]
media_idstringrequired
pattern "^[a-f0-9]{48}$"
captionstringoptional
maxLength 1024
quote_idstringoptional
pattern "^[a-f0-9]{48}$"
max_platform_feestringoptional

Maximum IllyVoIP platform fee in EUR. Meta charges are separate.

pattern "^(0|[1-9][0-9]{0,5})(\\.[0-9]{1,8})?$"

Additional properties: not allowed.

Full schema
Schema
{
  "oneOf": [
    {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "number_id",
        "to",
        "type",
        "text"
      ],
      "properties": {
        "number_id": {
          "type": "integer",
          "minimum": 1
        },
        "to": {
          "type": "string",
          "pattern": "^\\+[1-9][0-9]{7,14}$"
        },
        "type": {
          "type": "string",
          "enum": [
            "text"
          ]
        },
        "text": {
          "type": "string",
          "minLength": 1,
          "maxLength": 4096
        },
        "quote_id": {
          "type": "string",
          "pattern": "^[a-f0-9]{48}$"
        },
        "max_platform_fee": {
          "type": "string",
          "pattern": "^(0|[1-9][0-9]{0,5})(\\.[0-9]{1,8})?$",
          "description": "Maximum IllyVoIP platform fee in EUR. Meta charges are separate."
        }
      }
    },
    {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "number_id",
        "to",
        "type",
        "template_id",
        "parameters"
      ],
      "properties": {
        "number_id": {
          "type": "integer",
          "minimum": 1
        },
        "to": {
          "type": "string",
          "pattern": "^\\+[1-9][0-9]{7,14}$"
        },
        "type": {
          "type": "string",
          "enum": [
            "template"
          ]
        },
        "template_id": {
          "type": "integer",
          "minimum": 1
        },
        "parameters": {
          "type": "array",
          "maxItems": 100,
          "items": {
            "type": "string",
            "maxLength": 4096
          }
        },
        "named_parameters": {
          "type": "object",
          "maxProperties": 100,
          "additionalProperties": {
            "type": "string",
            "minLength": 1,
            "maxLength": 4096
          }
        },
        "header_parameters": {
          "type": "array",
          "maxItems": 100,
          "items": {
            "type": "string",
            "maxLength": 4096
          }
        },
        "named_header_parameters": {
          "type": "object",
          "maxProperties": 100,
          "additionalProperties": {
            "type": "string",
            "minLength": 1,
            "maxLength": 4096
          }
        },
        "quote_id": {
          "type": "string",
          "pattern": "^[a-f0-9]{48}$"
        },
        "max_platform_fee": {
          "type": "string",
          "pattern": "^(0|[1-9][0-9]{0,5})(\\.[0-9]{1,8})?$",
          "description": "Maximum IllyVoIP platform fee in EUR. Meta charges are separate."
        }
      }
    },
    {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "number_id",
        "to",
        "type",
        "media_id"
      ],
      "properties": {
        "number_id": {
          "type": "integer",
          "minimum": 1
        },
        "to": {
          "type": "string",
          "pattern": "^\\+[1-9][0-9]{7,14}$"
        },
        "type": {
          "type": "string",
          "enum": [
            "image"
          ]
        },
        "media_id": {
          "type": "string",
          "pattern": "^[a-f0-9]{48}$"
        },
        "caption": {
          "type": "string",
          "maxLength": 1024
        },
        "quote_id": {
          "type": "string",
          "pattern": "^[a-f0-9]{48}$"
        },
        "max_platform_fee": {
          "type": "string",
          "pattern": "^(0|[1-9][0-9]{0,5})(\\.[0-9]{1,8})?$",
          "description": "Maximum IllyVoIP platform fee in EUR. Meta charges are separate."
        }
      }
    },
    {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "number_id",
        "to",
        "type",
        "media_id"
      ],
      "properties": {
        "number_id": {
          "type": "integer",
          "minimum": 1
        },
        "to": {
          "type": "string",
          "pattern": "^\\+[1-9][0-9]{7,14}$"
        },
        "type": {
          "type": "string",
          "enum": [
            "audio"
          ]
        },
        "media_id": {
          "type": "string",
          "pattern": "^[a-f0-9]{48}$"
        },
        "quote_id": {
          "type": "string",
          "pattern": "^[a-f0-9]{48}$"
        },
        "max_platform_fee": {
          "type": "string",
          "pattern": "^(0|[1-9][0-9]{0,5})(\\.[0-9]{1,8})?$",
          "description": "Maximum IllyVoIP platform fee in EUR. Meta charges are separate."
        }
      }
    },
    {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "number_id",
        "to",
        "type",
        "media_id"
      ],
      "properties": {
        "number_id": {
          "type": "integer",
          "minimum": 1
        },
        "to": {
          "type": "string",
          "pattern": "^\\+[1-9][0-9]{7,14}$"
        },
        "type": {
          "type": "string",
          "enum": [
            "video"
          ]
        },
        "media_id": {
          "type": "string",
          "pattern": "^[a-f0-9]{48}$"
        },
        "caption": {
          "type": "string",
          "maxLength": 1024
        },
        "quote_id": {
          "type": "string",
          "pattern": "^[a-f0-9]{48}$"
        },
        "max_platform_fee": {
          "type": "string",
          "pattern": "^(0|[1-9][0-9]{0,5})(\\.[0-9]{1,8})?$",
          "description": "Maximum IllyVoIP platform fee in EUR. Meta charges are separate."
        }
      }
    },
    {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "number_id",
        "to",
        "type",
        "media_id"
      ],
      "properties": {
        "number_id": {
          "type": "integer",
          "minimum": 1
        },
        "to": {
          "type": "string",
          "pattern": "^\\+[1-9][0-9]{7,14}$"
        },
        "type": {
          "type": "string",
          "enum": [
            "document"
          ]
        },
        "media_id": {
          "type": "string",
          "pattern": "^[a-f0-9]{48}$"
        },
        "caption": {
          "type": "string",
          "maxLength": 1024
        },
        "quote_id": {
          "type": "string",
          "pattern": "^[a-f0-9]{48}$"
        },
        "max_platform_fee": {
          "type": "string",
          "pattern": "^(0|[1-9][0-9]{0,5})(\\.[0-9]{1,8})?$",
          "description": "Maximum IllyVoIP platform fee in EUR. Meta charges are separate."
        }
      }
    }
  ]
}

Request behavior

Send from a number connected and activated in the Portal. Provide number_id, recipient and text, an approved template or ready media. One request calculates the current fee and queues the message; quote_id is optional for a previously quoted exact payload. max_platform_fee is an optional EUR decimal string limiting only the IllyVoIP fee, not Meta charges or temporary wallet hold rounding.

Meta bills separately. Idempotency-Key is required: retry with the identical key and body; never create a replacement for an unknown result. 202 means queued, not delivered. IllyVoIP reserves its fee before dispatch and charges delivered outbound messages only.

Unknown outcomes retain their hold. Consent, service-window, ownership, account and balance checks still apply.

Conditions and examples

Production only; no WhatsApp Sandbox is available. Replace placeholders with your own account data. Response examples are abbreviated; use the OpenAPI schemas for the full contract. Meta bills its charges separately.

Response fields

  • message: Customer-facing explanation of the result.

HTTP responses

Expand a status to inspect its documented response format and examples. Example prices, IDs and timestamps are illustrative values, not quotes or account records.

202 Durably queued or exact replay; body contains success and message (not data). Delivery and settlement remain asynchronous.

application/json

successbooleanrequired
messageobjectrequired
Full schema
Schema
{
  "type": "object",
  "required": [
    "success",
    "message"
  ],
  "properties": {
    "success": {
      "type": "boolean"
    },
    "message": {
      "type": "object"
    }
  }
}
400 Invalid input.
401 Invalid API credential.
403 Account access denied.
409 Operation unavailable or request identity conflict.
503 Temporarily unavailable; a mutation outcome may be unknown. Preserve its request identity.

Production only

This operation is not available in Sandbox. Use an enabled Production account and review its effects before executing.

Search API operations, parameters, SDK and webhooks.