Product Keep your app Developers Pricing Contact Sign in Start free for 14 days

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