Interactive Requests
with full reply capture

Any buttons. Any list. Any media. And when they reply "no, I don't like it" with a marked-up photo attached — you get that too.

Why this exists

Approve/Reject covers one workflow. Real businesses need more: "Confirm / Reschedule / Cancel" for bookings, a 10-option service menu, "Rate this delivery" flows, or feedback collection where customers attach photos of a damaged item. The Interactions API is one endpoint that does all of it — your system defines the options, the follow-up behavior per option, and receives everything the customer sends back.

Buttons mode (up to 3 options)

POST /api/interactions
{
  "callbackUrl": "https://your-system.co.za/webhooks/chatreach",
  "items": [{
    "to": "27821234567",
    "mode": "buttons",
    "mediaType": "image",
    "mediaUrl": "https://cdn/delivery-photo.jpg",
    "body": "Your order #4521 was delivered. How did we do?",
    "externalRef": "ORDER-4521",
    "captureWindowMinutes": 120,
    "options": [
      { "id": "great", "title": "Great! 🎉" },
      { "id": "ok", "title": "It was OK" },
      { "id": "problem", "title": "There's a problem",
        "followUpPrompt": "Sorry to hear that! Please describe the issue — photos help us fix it faster:",
        "capture": true }
    ]
  }]
}

The magic is in that third option: followUpPrompt is sent automatically when tapped, and capture: true means every reply after it — text, photos, videos, documents — is collected into the interaction and streamed to your webhook. Media arrives as hosted URLs you can download.

List mode (up to 10 options)

POST /api/interactions
{
  "items": [{
    "to": "27821234567",
    "mode": "list",
    "body": "What can we help you with today?",
    "listButtonText": "Choose a service",
    "externalRef": "MENU-MAIN",
    "options": [
      { "id": "svc_quote",   "title": "Get a quote",      "description": "Free, within 24 hours" },
      { "id": "svc_book",    "title": "Book a callout",   "description": "Next available slot" },
      { "id": "svc_status",  "title": "Job status",       "description": "Track an existing job" },
      { "id": "svc_billing", "title": "Billing question" },
      { "id": "svc_other",   "title": "Something else",
        "followUpPrompt": "No problem — tell us what you need:", "capture": true }
    ]
  }]
}

The three webhooks

EventFires when
interaction.respondedAn option was tapped — carries selectedOptionId + selectedOptionTitle
interaction.replyEach captured follow-up message — carries the individual reply (type, body, mediaUrl) plus the running replies array
interaction.completedThe capture window closed (timeout, explicit complete call, or a new interaction to the same contact) — carries everything gathered
interaction.reply → your endpoint
{
  "event": "interaction.reply",
  "data": {
    "interactionId": "…",
    "externalRef": "ORDER-4521",
    "to": "27821234567",
    "selectedOptionId": "problem",
    "status": "capturing",
    "reply": {
      "type": "image",
      "body": null,
      "mediaUrl": "https://yourdomain.co.za/media/wamid123.jpg",
      "at": "2026-07-11T10:05:33Z"
    },
    "replies": [
      { "type": "text", "body": "The box arrived crushed", "mediaUrl": null, "at": "…" },
      { "type": "image", "body": null, "mediaUrl": "https://…/wamid123.jpg", "at": "…" }
    ]
  }
}

Closing the loop

Control endpoints
# Close the capture window early (fires interaction.completed)
POST /api/interactions/{id}/complete

# Poll instead of webhooks
GET /api/interactions/{id}
GET /api/interactions?externalRef=ORDER-4521
GET /api/interactions?batchId=…&status=completed

Capture window rules: default 60 minutes from the option tap (set captureWindowMinutes per item). It also closes when your system calls /complete or when you send the same contact a new interaction — so back-to-back workflows never bleed into each other.

Recipes

Use caseSetup
Artwork approval with markup feedbackButtons: Approve / Reject — Reject has capture: true so annotated screenshots come back
Appointment confirmationsButtons: Confirm / Reschedule / Cancel — Reschedule prompts "which day suits you?"
Damage claimsSingle "Report damage" button with capture — photos + description collected in one thread
Service menus / IVR replacementList mode with 10 departments, each option ID routes in your system
Quote acceptanceDocument media + Accept / Decline / Ask a question (capture on the last)

One endpoint. Every workflow.

Free trial includes the full Interactions API and webhooks from day one.

Start Free Trial