Skip to content

Documentation

Build with Engage

Connect customer data, business events, and communication channels to build automated journeys with workflows and AI.

Sales and results

The question every business asks after a few weeks: is this making me money? Mark a conversation as a sale when a customer pays, and the Results page adds it up alongside the conversations and messages that led there.

Mark a conversation as a sale

In the inbox, open the conversation and press Mark as sold. Enter the amount, choose the currency and, if it helps, a note - “3 bags, paid by transfer”. Any member of the workspace can, and any member can remove one marked by mistake.

POST /v1/conversations/{conversationId}/sales

{
  "amount": "25000.50",
  "currency": "NGN",
  "note": "3 bags, paid by transfer"
}
FieldTypeNotes
amountstringIn the main unit - naira, not kobo. Commas are fine. At most two decimal places.
currencystringNGN, GHS, KES, ZAR, EGP, USD, GBP or EUR. NGN when left out.
notestringOptional, up to 500 characters.

GET on the same path lists a conversation's sales, newest first, and DELETE /v1/sales/{saleId} removes one.

Sales after a follow-up

If a workflow's message reached the customer in the 7 days before the sale, the sale is credited to that follow-up, and the response names the workflow:

"followUp": { "workflowId": "…", "workflowName": "Follow up quiet customers" }

Timing, not proof

A customer who got a reminder on Monday and paid on Wednesday may have paid anyway. The credit says the follow-up was part of the conversation, not that it made the sale. It is still the best signal there is of whether your workflows are worth keeping.

Results

The Results page, or GET /v1/stats?from=…&to=…, counts over a range you choose. Both are instants with an offset; from is included and to is not, and the range can be a year at most. The dashboard sends whole days in your own time zone.

FieldTypeNotes
conversationsStartednumberConversations opened in the range.
messagesReceivednumberMessages from customers.
sentByTeamnumberMessages people sent from the inbox. Sends that failed are left out.
sentByWorkflowsnumberWorkflow messages WhatsApp accepted.
sentByCampaignsnumberCampaign messages WhatsApp accepted.
salesobjectcount, and amounts per currency - different currencies are never added together.
salesAfterFollowUpobjectThe same, for sales credited to a follow-up.

One workflow

curl "https://api.engentra.io/v1/workflows/{id}/stats?from=2026-09-01T00:00:00%2B01:00&to=2026-10-01T00:00:00%2B01:00"   -H "X-API-Key: $ENGAGE_API_KEY"

The same range rules, counted over the runs that started in the range - so a run that began on the last day and sends next week still belongs to this range. The workflow's page in the dashboard shows these under Results.

FieldTypeNotes
startednumberRuns that started.
completed, stopped, failed, inProgressnumberHow those runs ended, or that they have not yet. Stopped includes stop-early rules.
messagesSentnumberMessages those runs sent that WhatsApp accepted.
repliednumberRuns whose customer wrote back within 7 days of the run starting - by timing, like sales.
salesobjectSales credited to this workflow: count, and amounts per currency.

Which door produced the sale

curl "https://api.engentra.io/v1/stats/doors?from=2026-09-01T00:00:00%2B01:00&to=2026-10-01T00:00:00%2B01:00"   -H "X-API-Key: $ENGAGE_API_KEY"

A business cannot message first on Instagram. That rule does not bend, so the only thing left to work on is where the door is: an ig.me link on the packaging, one in an email, a QR on a poster, an ad that clicks straight to Direct. Meta tells us which one was used — once, on the message that opens the thread — and this is what that becomes.

response

[
  {
    "ref": "packaging-qr",
    "adId": null,
    "adTitle": null,
    "source": "SHORTLINK",
    "conversations": 31,
    "customers": 29,
    "sales": { "count": 4, "amounts": { "NGN": "72000.00" } }
  },
  {
    "ref": null,
    "adId": "239847",
    "adTitle": "Ankara sale - October",
    "source": "ADS",
    "conversations": 9,
    "customers": 9,
    "sales": { "count": 3, "amounts": { "NGN": "54000.00" } }
  }
]

Conversations are counted from when the thread started and sales from when the money arrived. A door can show sales in a month it started nothing — it did its work earlier and somebody paid later. Counting the sale back to the month of the click would quietly rewrite last month's numbers every time a customer returned.

Threads that came through no door are not a row. An “(other)” line would be the largest number on a page whose only purpose is comparing links, and there is nothing to choose about traffic that arrived from nowhere in particular.

Naming a door

An ig.me link opens a Direct thread with your account, and a ref on it is the name you will see above. Build one under Settings › Channels, which fills in your username for you:

https://ig.me/m/adafabrics?ref=packaging-qr

Meta drops a ref it does not like

Letters, numbers and - . : _ + / = only. A ref with a space or an accent in it is discarded at Meta's end — the link still works, the thread still opens, and every conversation it starts is untraceable, with nothing anywhere saying why. The builder in the dashboard checks this before you print it on anything.

An ad needs no setup. A click-to-Direct ad carries its own ad_id, and its title where Meta sends one, so it appears here on its own.

Each door also raises a conversation.referred event on the customer when the thread opens, carrying ref, source, adId and adTitle. A workflow can trigger on it — “somebody came from the October ad” — like any other event.

Two more Instagram events exist for the same reason: conversation.story_reply when somebody answers one of your stories, and conversation.story_mention when they put you in one of theirs. Both are also written into the message text so the inbox and the AI can read them, but a workflow should trigger on the event rather than matching a prefix inside free text.

Next

Workflows →

The follow-ups that get the credit.