Skip to content

No-code automation

Fliok + Make

Start a scenario when a WhatsApp message, a new lead, a form submission or a store order arrives in Fliok, or when an invoice is paid or a booking is made — and have any scenario send a WhatsApp template, add a lead or create a follow-up in Fliok. It works today with Make’s own Webhooks and HTTP steps and Fliok’s signed webhooks and REST API.

Fliok is not listed in Make’s app directory yet, so this guide uses Make’s generic webhook and request steps. Webhooks and HTTP are built into every Make plan.

Before you start

  • The API and webhooks are part of the Pro and Enterprise plans (pricing).
  • In Fliok, open API keys and create a key for Make. Give it the admin role if it will also register webhooks; sending and CRM changes need at least agent. The key starts with wa_ and is shown once.
  • Every request to Fliok carries it as a header: Authorization: Bearer wa_…. Base URL https://fliok.com/api/v1.

Start a scenario from Fliok

  1. In Make, start a scenario with Webhooks → Custom webhook, press Add, name it and copy the address.
  2. In Fliok, open API keys → Webhooks, paste the address into Endpoint URL, pick the event (for example form.submitted) and press Add.
  3. Press Run once in Make, then Send test event next to the webhook in Fliok. Make learns the data structure from that delivery, and every field can be mapped.

Every delivery has the same shape — the event’s fields are under data:

What Fliok POSTs to your URL
{
  "id": "evt_8f2c…",
  "event": "lead.created",
  "createdAt": "2026-10-06T10:00:00.000Z",
  "data": {
    "lead": { "id": "…", "phone": "919876543210", "name": "Asha", "stage": { "name": "New lead", "kind": "initial" }, … },
    "source": "Website",
    "via": "form",
    "form": "Wedding enquiry",
    "createdAt": "2026-10-06T10:00:00.000Z"
  }
}

Deliveries are signed (HMAC-SHA256, see the webhook reference) and retried when your URL does not answer 2xx, so the same id can arrive twice. A workspace can register 25 webhook URLs.

EventWhen it fires
message.receivedA contact sent a message to your number. Deduplicated — Meta redelivers webhooks, you do not get doubles.
contact.createdA customer became a contact for the first time. `phone` is their number — or `wa:<user id>` for a WhatsApp customer whose number Meta has not shared. `userId` and `username` (their WhatsApp user id and username) are present only when known. `source` is inbound_message, smb_echo, user_preferences, api_send or api (POST /contacts and /contacts/bulk). Bulk paths — CSV import, dashboard-created contacts, coexistence address-book sync and Coexistence history backfill — do NOT emit this.
lead.createdA new lead entered the CRM. `via` is form, api, import, manual, integration or whatsapp. `lead` carries id, phone, name, email, stage {id,name,kind}, owner, source, rating, dealValue and tags.
form.submittedSomebody submitted a form to your lead-capture link (a website form, or a marketplace push such as IndiaMART or JustDial). Every submission fires, including a repeat from a number you already have (`created` false); a portal re-sending the same enquiry does not. `note` is what they wrote in the message box, `fields` holds answers matched to your custom fields, `extra` everything else the form sent.
lead.stage_changedA lead moved stage. `from`/`to` are {id,name,kind} with kind initial, active, won or lost; `lostReason` is set on a move to a lost stage. Restructuring the pipeline in settings does not fire this.
lead.assignedA lead's owner changed — by a person, a routing rule, an automation or inbox auto-assign. `to` is null when the lead was unassigned.
task.createdA follow-up task was created on a lead. `task` carries id, title, type, dueAt, priority, status and assignee.
message.statusAn outbound message changed state: sent, delivered, read or failed. Each state fires at most once; statuses never move backwards.
message.failedAn outbound message failed for good, with the Meta error code explained. Fires once per message. Messages we deliberately did not send (status "skipped") never appear here.
conversation.closedThe 24-hour customer-service window expired. Only approved templates can be sent until the customer messages again. Detected within ~5 minutes of expiry.
conversation.ratedA customer answered the satisfaction survey on a resolved conversation. `score` is 1-5. Fired once per conversation; later taps are ignored.
template.approvedMeta approved a message template. Fired on the transition into approved, so a redelivered Meta webhook does not re-fire it.
template.rejectedMeta rejected a message template. `reason` carries Meta's rejection reason when it supplies one.
order.eventA connected Shopify or WooCommerce store reported an order event. `type` is order_placed, order_paid, order_shipped or order_cancelled. Fires once per store, event and order, whether or not a WhatsApp template is set for that event; the store's retries do not fire it again.
payment.paidA customer paid a WhatsApp Pay request. Amounts are in paise (INR); `paymentMethod` is Meta's method type (upi, card, netbanking, wallet…) when it says. If `paidPaise` differs from `totalPaise`, Meta reported a different amount than was asked: check the payment before you fulfil the order. Fired on the transition into paid, so Meta's repeated payment updates never fire it twice.
invoice.issuedAn invoice or a proforma was issued in Invoices. `invoice` carries id, kind (invoice or proforma), number, status, version, issueDate, dueDate, validUntil, currency, the totals in minor units (taxableMinor, taxMinor, totalMinor, receivedMinor, tdsMinor, balanceMinor) with `total` and `balance` as printed text, `customer` {contactId, name, phone, email} and `url`, the page the customer was sent. Totals only: the lines are on the document. `customer.phone` is null when the document carries no number. `bookingId` is set when the document is the receipt of a booking's advance — that money is the booking's own `advance`, so count it once — and null otherwise. Fires once per document; an invoice made from a proforma names it in `fromProforma`, and arrives already `paid` when the proforma was.
invoice.payment_recordedMoney was recorded on an invoice or a proforma — by a person, or reported by your own payment gateway. `payment` carries id, receiptNumber, amountMinor and `amount` as text, tdsMinor, currency, paidOn, method, reference and source (manual or gateway); `invoice` is the document after this payment. One event per payment: a gateway reporting the same payment again fires nothing.
invoice.paidAn invoice or a proforma became paid in full. Fires on the payment that closed the balance (`paymentId`), alongside that payment's own invoice.payment_recorded. If a payment is voided and the balance is paid again later, it fires again.
quotation.acceptedA quotation was accepted — by the customer on the quotation's page, or marked accepted by a team member (`acceptedBy` is customer or staff). `quotation` carries id, number, status, version, issueDate, validUntil, currency, totalMinor with `total` as text (the optional items the customer chose are in it), `customer` and `url`. A revised quotation that is accepted again fires again.
booking.createdA booking was made in Bookings — by a customer on your booking page, or added by a team member (`by` is customer or staff). Where a service asks for an advance to hold the slot, this fires when the booking is confirmed — the advance was paid, or your team confirmed it without one — and never while the slot is only being held; a held slot that is given up or runs out of time fires nothing. Once per booking. `booking` carries id, service, `summary` (the service as the customer reads it: "Haircut with Riya", "Badminton — Court 1"), `staff` {id, name, kind: person or resource} or null, startAt and endAt (ISO, UTC) with the calendar's `timeZone`, durationMinutes, status, locationKind, location, priceMinor with `price` as text (the price shown, never charged by the booking), currency, `advance` {amountMinor, amount, currency, status, paidAt, invoiceId} or null, `customer` {contactId, name, phone, email} and source (public or staff). `customer.phone` is null when the booking carries no number.
booking.rescheduledA booking was moved to another time, by the customer from their link or by a team member. `booking` carries the new time, `previousStartAt` the one it had.
booking.cancelledA booking was cancelled — by the customer from their link, or by a team member. `reason` is what they gave, when they gave one. `booking.advance.status` says what became of an advance that was paid: refund_due or kept.
booking.completedA team member marked a booking as completed: the visit happened.
review.receivedA customer answered a review request sent after an invoice was paid or a visit was completed. `rating` is 1-5 and `comment` what they wrote; `about` is invoice or booking, with its id in `subjectId` and the invoice's number or the service's name in `subjectLabel`. `low` is true when the rating is at or under your own tell-the-team line. Fires once per request.

Also available: template.category_changed, contact.updated, contact.deleted, conversation.opened, flow.completed, call.missed, order.cod_response, broadcast.completed, lead.recaptured, task.completed, instagram.message.received, instagram.comment.received, instagram.post.published, invoice.updated, invoice.payment_voided, invoice.cancelled, quotation.declined, booking.no_show, booking.restored. Every field of every event is listed in the API reference.

Three automations, start to finish

Invoices and Bookings tell Make what happens in them: an invoice issued or paid, a payment recorded, a quotation accepted, a booking made, moved, cancelled or completed, a review received. They fire once you have switched that part of Fliok on. Amounts come twice — in paise (totalMinor) for sums, and as printed text (total) for people.

An invoice is paid → a row in your spreadsheet

  1. Start a scenario from Fliok with the event invoice.paid (the steps above).
  2. Add your spreadsheet app’s own add a row step and pick the sheet.
  3. Map the columns: number = data.invoice.number, customer = data.invoice.customer.name, total = data.invoice.total (as printed, “₹11,800.00”) or data.invoice.totalMinor divided by 100 when you want a number to add up, paid at = data.paidAt, link = data.invoice.url.

For every payment rather than only the last one, start from invoice.payment_recorded instead: data.payment carries the receipt number, the amount and how it was paid, and data.invoice.balanceMinor what is still owed.

A new booking → an event in your calendar

  1. Start a scenario from Fliok with the event booking.created.
  2. Add your calendar app’s own create an event step. Start = data.booking.startAt, end = data.booking.endAt — both are ISO times in UTC, which a calendar converts by itself; the business’s own zone is in data.booking.timeZone.
  3. Title = data.booking.service with data.booking.customer.name; location = data.booking.location. Put data.booking.id in the description.
  4. Make two more scenarios from booking.rescheduled and booking.cancelled: find the calendar event by that id in its description, then move it to the new data.booking.startAt or delete it.

A calendar that only ever hears about new bookings goes wrong the first time a customer moves one — the two extra scenarios are what keep it true.

A quotation is accepted → a follow-up for your team

  1. Start a scenario from Fliok with the event quotation.accepted.
  2. Add a request step: POST https://fliok.com/api/v1/tasks with { "leadId": "<data.quotation.customer.contactId>", "title": "Raise the bill for <data.quotation.number>", "dueAt": "<tomorrow, as an ISO time>" }.
  3. The task goes to the lead’s owner. data.quotation.total is what was agreed, with the optional items the customer chose.

customer.contactId is empty for a quotation that was not made out to a contact — add a filter step so the scenario stops there instead of failing.

Make Fliok do something from a scenario

  1. Add the module HTTP → Make a request.
  2. URL and Method from the table below, e.g. POST https://fliok.com/api/v1/send.
  3. Headers: Authorization = Bearer wa_… (your API key). Body type Raw, content type JSON (application/json), request content = the JSON body. Set Parse response to Yes so the answer can be mapped.

Send an approved template

Works at any time. variables fill the body’s {{1}}, {{2}}… in order; Fliok refuses a blank one before WhatsApp does.

POST https://fliok.com/api/v1/send
{
  "to": "919876543210",
  "type": "template",
  "payload": {
    "type": "template",
    "template": {
      "name": "order_update",
      "language": { "code": "en_US" },
      "variables": ["Asha", "#1042"]
    }
  }
}

Send a text message

Only within 24 hours of the customer’s last message to you — otherwise Fliok answers 422 outside_24h_window. Use a template outside the window.

POST https://fliok.com/api/v1/send
{ "to": "919876543210", "type": "text", "text": "Your table is booked for 8 pm." }

Create or update a contact

Keyed by phone number: a second call updates the same contact. tags here replaces the list; use the next call to add or remove single tags.

POST https://fliok.com/api/v1/contacts
{ "phone": "919876543210", "displayName": "Asha", "attributes": { "city": "Kolkata" } }

Add or remove tags

In Fliok a lead is a contact, so this works on any contact by phone number. Automations that start on a tag run as usual.

PATCH https://fliok.com/api/v1/leads/919876543210
{ "addTags": ["diwali-sale"], "removeTags": ["cold"] }

Create a lead

A number already in the CRM is not duplicated — it is recorded as having come in again. Stage and owner are given by name or email.

POST https://fliok.com/api/v1/leads
{ "phone": "919876543210", "name": "Asha", "source": "Facebook form", "stage": "New lead", "note": "Wants a December date" }

Move a lead to a stage

GET /pipeline lists your stages and lost reasons. The move lands on the lead’s timeline and fires your stage automations.

PATCH https://fliok.com/api/v1/leads/919876543210
{ "stage": "Lost", "lostReason": "Too expensive" }

Create a follow-up task

leadId takes the lead’s phone number or id. The task goes to the lead’s owner unless you give assignee (an email).

POST https://fliok.com/api/v1/tasks
{ "leadId": "919876543210", "title": "Call back about the venue", "dueAt": "2026-10-07T10:00:00+05:30", "type": "call" }

Ask for a payment (WhatsApp Pay)

Needs WhatsApp Pay set up in Fliok and a chat the customer messaged in the last 24 hours. Amounts are in paise; your referenceId makes a retry safe.

POST https://fliok.com/api/v1/payment-requests
{ "to": "919876543210", "referenceId": "ORD-1042", "items": [{ "name": "Silk saree", "quantity": 1, "unitPaise": 149900 }] }

Find a contact by phone

An exact match, with or without the country code. No such contact is an empty list.

GET https://fliok.com/api/v1/contacts?phone=919876543210
GET https://fliok.com/api/v1/contacts?phone=919876543210

When Fliok refuses a call it answers with an error code and usually a message sentence — show the message in your scenario’s error handling. The full list of endpoints (contacts, conversations, broadcasts, Instagram and more) is in the API reference.

Other automation tools