Ai telnyx-whatsapp-curl

install
source · Clone the upstream repo
git clone https://github.com/team-telnyx/ai
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/team-telnyx/ai "$T" && mkdir -p ~/.claude/skills && cp -r "$T/providers/cursor/plugin/skills/telnyx-whatsapp-curl" ~/.claude/skills/team-telnyx-ai-telnyx-whatsapp-curl-778015 && rm -rf "$T"
manifest: providers/cursor/plugin/skills/telnyx-whatsapp-curl/SKILL.md
source content

Telnyx WhatsApp Business API - curl

Installation

# curl is pre-installed on macOS, Linux, and Windows 10+

Setup

export TELNYX_API_KEY="YOUR_API_KEY_HERE"

All examples below use

$TELNYX_API_KEY
for authentication.

Error Handling

All API calls can fail with network errors, rate limits (429), validation errors (422), or authentication errors (401). Always handle errors in production code:

curl \
  -X POST \
  -H "Authorization: Bearer $TELNYX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
      "from": "+19452940762",
      "to": "+18005551234",
      "type": "WHATSAPP",
      "whatsapp_message": {
        "type": "text",
        "text": { "body": "Hello from Telnyx!" }
      }
  }' \
  "https://api.telnyx.com/v2/messages/whatsapp"

Common error codes:

401
invalid API key,
403
insufficient permissions,
404
resource not found,
422
validation error (check field formats),
429
rate limited (retry with exponential backoff).

WhatsApp-Specific Errors

  • 40008 — Meta catch-all error. Check template parameters, phone number formatting, and 24-hour window rules.
  • 131047 — Message failed to send during the 24-hour window. The customer hasn't messaged you first (for non-template messages).
  • 131026 — Recipient phone number is not a WhatsApp user.
  • 132000 — Template parameter count mismatch. Ensure the number of parameters matches the template definition.
  • 132015 — Template paused or disabled by Meta due to quality issues.

Important Notes

  • Phone numbers must be in E.164 format (e.g.,
    +13125550001
    ). Include the
    +
    prefix and country code.
  • Template messages can be sent anytime. Free-form (session) messages can only be sent within a 24-hour window after the customer last messaged you.
  • Template IDs: You can reference templates by Telnyx UUID (
    template_id
    ) instead of
    name
    +
    language
    . When
    template_id
    is provided, name and language are resolved automatically.
  • Billing types: Template messages are billed as
    whatsapp_marketing
    ,
    whatsapp_utility
    ,
    whatsapp_authentication
    , or
    whatsapp_authentication_international
    based on category and destination.

Operational Caveats

  • The sending phone number must be registered with a WhatsApp Business Account (WABA) and associated with a messaging profile.
  • Templates must be in
    APPROVED
    status before they can be used for sending.
  • Template names must be lowercase with underscores only (e.g.,
    order_confirmation
    ). No spaces, hyphens, or uppercase.
  • When creating templates, provide realistic sample values for body parameters — Meta reviewers check these during approval.
  • Category selection matters for billing:
    AUTHENTICATION
    templates get special pricing but must contain an OTP.
    UTILITY
    is for transactional messages.
    MARKETING
    for promotional content.
  • Meta may reclassify your template category (e.g., UTILITY to MARKETING) which affects billing.

Reference Use Rules

Do not invent Telnyx parameters, enums, response fields, or webhook fields.

Core Tasks

Send a WhatsApp template message

Send a pre-approved template message. Templates can be sent anytime — no 24-hour window restriction.

POST /messages/whatsapp

ParameterTypeRequiredDescription
from
string (E.164)YesWhatsApp-enabled phone number in +E.164 format
to
string (E.164)YesRecipient phone number in +E.164 format
type
stringNoMust be
WHATSAPP
whatsapp_message.type
stringYesMust be
template
whatsapp_message.template.name
stringYes*Template name (e.g.,
order_confirmation
)
whatsapp_message.template.language.code
stringYes*Language code (e.g.,
en_US
)
whatsapp_message.template.template_id
string (UUID)NoTelnyx template UUID. If provided,
name
and
language
are resolved from DB
whatsapp_message.template.components
arrayNoTemplate parameter values
messaging_profile_id
string (UUID)NoMessaging profile to use
webhook_url
string (URL)NoCallback URL for delivery status updates

*Required unless

template_id
is provided.

# Send by template name + language
curl \
  -X POST \
  -H "Authorization: Bearer $TELNYX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
      "from": "+19452940762",
      "to": "+18005551234",
      "type": "WHATSAPP",
      "whatsapp_message": {
        "type": "template",
        "template": {
          "name": "order_confirmation",
          "language": { "code": "en_US" },
          "components": [
            {
              "type": "body",
              "parameters": [
                { "type": "text", "text": "ORD-12345" },
                { "type": "text", "text": "March 15, 2026" }
              ]
            }
          ]
        }
      }
  }' \
  "https://api.telnyx.com/v2/messages/whatsapp"
# Send by Telnyx template_id (no name/language needed)
curl \
  -X POST \
  -H "Authorization: Bearer $TELNYX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
      "from": "+19452940762",
      "to": "+18005551234",
      "type": "WHATSAPP",
      "whatsapp_message": {
        "type": "template",
        "template": {
          "template_id": "019cd44b-3a1c-781b-956e-bd33e9fd2ac6",
          "components": [
            {
              "type": "body",
              "parameters": [
                { "type": "text", "text": "483291" }
              ]
            }
          ]
        }
      }
  }' \
  "https://api.telnyx.com/v2/messages/whatsapp"

Primary response fields:

  • .data.id
    — Message UUID
  • .data.to[0].status
    queued
    ,
    sent
    ,
    delivered
    ,
    failed
  • .data.from.phone_number
  • .data.type
    WHATSAPP

Send a free-form WhatsApp text message

Send a text message within the 24-hour customer service window (customer must have messaged you first).

POST /messages/whatsapp

ParameterTypeRequiredDescription
from
string (E.164)YesWhatsApp-enabled phone number
to
string (E.164)YesRecipient phone number
whatsapp_message.type
stringYes
text
whatsapp_message.text.body
stringYesMessage content
curl \
  -X POST \
  -H "Authorization: Bearer $TELNYX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
      "from": "+19452940762",
      "to": "+18005551234",
      "type": "WHATSAPP",
      "whatsapp_message": {
        "type": "text",
        "text": { "body": "Your order has shipped!" }
      }
  }' \
  "https://api.telnyx.com/v2/messages/whatsapp"

List WhatsApp Business Accounts

Retrieve all WABAs associated with your Telnyx account.

GET /v2/whatsapp/business_accounts

ParameterTypeRequiredDescription
page[number]
integerNoPage number (default: 1)
page[size]
integerNoPage size (default: 20)
curl \
  -H "Authorization: Bearer $TELNYX_API_KEY" \
  "https://api.telnyx.com/v2/whatsapp/business_accounts"

Primary response fields:

  • .data[].id
    — Telnyx WABA UUID
  • .data[].waba_id
    — Meta WABA ID
  • .data[].name
    — Business name
  • .data[].status
    — Account status
  • .data[].country
    — WABA country

List templates

Retrieve message templates, optionally filtered by WABA.

GET /v2/whatsapp/message_templates

ParameterTypeRequiredDescription
waba_id
string (UUID)NoFilter by Telnyx WABA UUID (query parameter)
category
stringNoFilter by category:
AUTHENTICATION
,
MARKETING
,
UTILITY
status
stringNoFilter by status:
APPROVED
,
PENDING
,
REJECTED
,
DISABLED
page[number]
integerNoPage number
page[size]
integerNoPage size
curl \
  -H "Authorization: Bearer $TELNYX_API_KEY" \
  "https://api.telnyx.com/v2/whatsapp/message_templates?waba_id=019c1ff0-5c30-7f36-8436-730b1d0b0e56&status=APPROVED"

Primary response fields:

  • .data[].id
    — Telnyx template UUID (use this as
    template_id
    when sending)
  • .data[].name
    — Template name
  • .data[].category
    AUTHENTICATION
    ,
    MARKETING
    , or
    UTILITY
  • .data[].language
    — Language code (e.g.,
    en_US
    )
  • .data[].status
    APPROVED
    ,
    PENDING
    ,
    REJECTED
    ,
    DISABLED
  • .data[].components
    — Template components (header, body, footer, buttons)

Create a message template

Submit a new template for Meta review. Templates typically take minutes to hours for approval.

POST /v2/whatsapp/message_templates

ParameterTypeRequiredDescription
waba_id
string (UUID)YesTelnyx WABA UUID (body parameter)
name
stringYesLowercase with underscores only (e.g.,
order_update
)
category
stringYes
AUTHENTICATION
,
MARKETING
, or
UTILITY
language
stringYesLanguage code (e.g.,
en_US
)
components
arrayYesTemplate components
curl \
  -X POST \
  -H "Authorization: Bearer $TELNYX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
      "waba_id": "019c1ff0-5c30-7f36-8436-730b1d0b0e56",
      "name": "order_shipped",
      "category": "UTILITY",
      "language": "en_US",
      "components": [
        {
          "type": "BODY",
          "text": "Your order {{1}} has been shipped and will arrive by {{2}}.",
          "example": {
            "body_text": [["ORD-12345", "March 20, 2026"]]
          }
        }
      ]
  }' \
  "https://api.telnyx.com/v2/whatsapp/message_templates"

Primary response fields:

  • .data.id
    — Telnyx template UUID
  • .data.name
    — Template name
  • .data.status
    — Initially
    PENDING
    until Meta approves

List phone numbers

GET /v2/whatsapp/phone_numbers

ParameterTypeRequiredDescription
waba_id
string (UUID)NoFilter by Telnyx WABA UUID (query parameter)
curl \
  -H "Authorization: Bearer $TELNYX_API_KEY" \
  "https://api.telnyx.com/v2/whatsapp/phone_numbers?waba_id=019c1ff0-5c30-7f36-8436-730b1d0b0e56"

Primary response fields:

  • .data[].phone_number
    — Phone number in E.164 format
  • .data[].number_id
    — Meta phone number ID
  • .data[].quality_rating
    GREEN
    ,
    YELLOW
    , or
    RED
  • .data[].messaging_limit_tier
    — Current messaging tier

Webhook Verification

Telnyx signs webhooks with Ed25519. Each request includes

telnyx-signature-ed25519
and
telnyx-timestamp
headers. Always verify signatures in production.

Webhooks

These webhook payload fields are inline because they are part of the primary integration path.

Message Delivery Update

FieldTypeDescription
data.event_type
enum: message.sent, message.finalizedDelivery status event
data.payload.id
uuidMessage ID
data.payload.to[0].status
string
queued
,
sent
,
delivered
,
read
,
failed
data.payload.template_id
stringTelnyx template UUID (if template message)
data.payload.template_name
stringTemplate name (if template message)
data.payload.cost
objectCost information
data.payload.errors
arrayError details if failed

Template Status Change

Configure webhook events on your WABA to receive template lifecycle notifications.

FieldTypeDescription
event_type
string
whatsapp.template.approved
,
whatsapp.template.rejected
,
whatsapp.template.disabled
payload.template_id
stringTelnyx template UUID
payload.template_name
stringTemplate name
payload.status
stringNew template status
payload.reason
stringRejection/disable reason (if applicable)
payload.waba_id
stringWABA ID

Phone Number Quality Change

FieldTypeDescription
event_type
string
whatsapp.phone_number.quality_changed
payload.phone_number
stringPhone number in E.164 format
payload.previous_quality_rating
stringPrevious rating (GREEN, YELLOW, RED)
payload.new_quality_rating
stringNew rating

Template Best Practices

  • Naming: Use lowercase with underscores. Be descriptive (e.g.,
    appointment_reminder
    , not
    msg1
    ).
  • Sample values: Provide realistic examples in the
    example
    field — Meta reviewers check these.
  • Category selection:
    • AUTHENTICATION
      — OTP/verification codes only. Gets special pricing.
    • UTILITY
      — Transactional (order updates, shipping, account alerts).
    • MARKETING
      — Promotional content, offers, newsletters.
  • Keep it concise: Meta prefers shorter templates. Avoid unnecessary formatting.
  • Avoid prohibited content: No misleading claims, prohibited products, or URL shorteners in template body.
  • Parameters: Use
    {{1}}
    ,
    {{2}}
    , etc. for variable content. Always provide the correct number of parameters when sending.

Important Supporting Operations

OperationEndpointUse Case
Get template details
GET /v2/whatsapp_message_templates/{id}
Check template status, view components
Get business profile
GET /v2/whatsapp/phone_numbers/{phone_number}/profile
View business display name, photo, description
Configure WABA settings
PATCH /v2/whatsapp/business_accounts/{id}/settings
Subscribe to template/account events

Additional Operations

OperationMethodEndpointUse CaseRequired Params
Send WhatsApp messagePOST
/messages/whatsapp
Send template or free-form message
from
,
to
,
whatsapp_message
List WABAsGET
/v2/whatsapp/business_accounts
List all business accounts
Get WABAGET
/v2/whatsapp/business_accounts/{id}
Get WABA details
id
List templatesGET
/v2/whatsapp/message_templates
List templates with filtering
Get templateGET
/v2/whatsapp_message_templates/{id}
Get template details
id
Create templatePOST
/v2/whatsapp/message_templates
Create new template
waba_id
,
name
,
category
,
language
,
components
List phone numbersGET
/v2/whatsapp/phone_numbers
List WABA phone numbers
Get business profileGET
/v2/whatsapp/phone_numbers/{phone_number}/profile
View profile info
phone_number
Update business profilePATCH
/v2/whatsapp/phone_numbers/{phone_number}/profile
Update profile info
phone_number
Get WABA settingsGET
/v2/whatsapp/business_accounts/{id}/settings
View WABA settings/webhook config
id
Update WABA settingsPATCH
/v2/whatsapp/business_accounts/{id}/settings
Set webhook URL and events
id