Flow templates
GET /flow/templates returns the ready-made flows worth offering a project, scored against the events it really receives. This page covers relevance and scoring, the SMS and RCS modes, the language of the messages, the integration filter, and how to create a flow from a template.
Writing a flow graph from nothing is the slowest and most error-prone way to build one. The template list is the shortcut: a catalogue of ready-made journeys (an abandoned-checkout reminder, a welcome, a winback and others), each scored for this particular project against the events it actually receives, and each carrying a complete graph with the trigger event and its source already chosen.
The intended path is to take the payload of the closest template, change only what you need, and create the flow from it.
The dashboard shows the same list as its template gallery, with the same recommendations; how customers use it is described in Flows → Templates.
List the flow templates worth offering this project.
The endpoint takes the PROJECT_AUTOMATION_READ scope and sits in the medium rate-limit class.
Query parameters
langstringdefault: enen or es. The language of each template's title and description. It does not change the language of the messages, which follow the project's own language (see Message language).
channelstringdefault: smssms or rcs: the mode every payload is built in. See SMS or RCS with SMS fallback.
integrationstringAn integration key, such as shopify. Keeps only the templates that integration can feed, scored as if it were connected. See What would an integration unlock.
The response
{
"entities": [
{
"key": "abandoned-checkout",
"title": "Abandoned checkout",
"description": "Reminds shoppers who started a checkout and did not buy within 30 minutes. Stops as soon as they order.",
"categories": ["ecommerce", "checkout_abandoned"],
"icon": "shopping-cart",
"recommended": true,
"integrations": [
{ "integration": "shopify", "name": "Shopify", "connected": true }
],
"channels": ["sms", "rcs"],
"channel": "sms",
"relevance": "received",
"trigger": {
"eventType": "ecommerce_checkout_init",
"datasourceId": "66c3a1b2e5a6b7c8d9e0f1a2",
"candidates": ["ecommerce_checkout_init"],
"lastSeenAt": "2026-09-25T08:41:12+00:00"
},
"score": 60,
"scoring": [
{ "signal": "relevance", "delta": 40, "text": "My Shop sent 412 ecommerce_checkout_init events in the last 30 days" },
{ "signal": "business", "delta": 20, "text": "Suited to ecommerce businesses" }
],
"used": false,
"payload": { "trigger": { "stepClass": "TRIGGER_CONTACT_EVENT", "eventType": "ecommerce_checkout_init", "...": "..." } }
}
],
"window": { "days": 30 }
}keystringThe template's stable identifier. Pass it as template when you create a flow from it.
titlestringThe template's name, in the lang you asked for.
descriptionstringWhat the journey does, in the lang you asked for.
categoriesstring[]Free tags for grouping templates in a gallery.
iconstringA Lucide icon name in kebab-case, fixed per template.
recommendedbooleantrue on at most three templates: the best-scored ones whose trigger event was received and that have not been used yet. The same set the project's recommendations surface.
integrationsobject[]The integrations that can send the trigger event, connected first, each with integration (its key), name and connected. Empty for templates triggered by Instasent's own events, which fire whatever the source.
channelsstring[]The send modes this project can use: sms, plus rcs when the project has an active RCS sender.
channelstringThe mode payload was built in, which is the channel you asked for.
relevancestringreceived, available or unavailable. See Relevance.
triggerobjectThe trigger the template resolved to for this project.
eventTypestringThe event type the payload triggers on.
datasourceIdstringThe data source the payload's trigger listens to: the event's preferred source. null for Instasent's own events, and when no connected source sends the event yet.
candidatesstring[]The event types the template can trigger on, in order of preference. The first one this project receives wins.
lastSeenAtstringThe last time the trigger event arrived inside window, whatever relevance says. On an unavailable template a value means the event is stale — it arrived, but more than 14 days ago — not unknown.
datasourcesobject[]The sources that send the trigger event, best first.
scoreintegerThe template's score for this project. Only templates scoring above zero are listed.
scoringobject[]One entry per reason behind the score: signal, delta (points added or removed) and text, an English sentence built from the facts above.
usedbooleantrue while a flow created from this template exists and is not archived.
payloadobjectThe flow graph, ready to send as the draft of POST /flow. Its shape is described in Nodes.
window.days is the window the event counts behind relevance and scoring cover. It follows the plan: 30 days on free plans, 180 on paid ones, the same bound the event volumes probe applies.
Relevance
Relevance answers the question that decides whether a flow will ever fire: does the event it triggers on actually arrive in this project?
relevance | What it means | What to do |
|---|---|---|
received | A source that can trigger flows sent the trigger event in the last 14 days. | The flow fires today. The natural candidate to offer. |
available | No such event arrived in the last 14 days, but a connected integration declares that it sends it. | The flow is buildable; it will fire once the events start arriving. |
unavailable | No connected source sends the event, or it last arrived more than 14 days ago. | Connecting a source that sends it comes before building the flow. |
Relevance is data first. The events a project really receives outweigh the business type it declared, so a project that sells online while describing itself otherwise still sees the ecommerce journeys, as long as its orders arrive.
When a template can trigger on more than one event (a review request can follow a delivery or, failing that, a shipment), the first candidate the project receives is the one the payload uses, and a scoring sentence says so. A trigger filter in the graph follows the event it was rewritten to.
Scoring and order
score is the sum of the delta of every scoring entry. The signals include the trigger's relevance (a received event weighs most), extra sources that also send it, how well the template suits the project's business type, whether the trigger is the project's own sales conversion event, and whether a complementary or overlapping flow already exists. Each entry says in plain words what it measured, so the list can be shown to a person, or read by a model, as the reason a template is on offer.
Templates are ordered with used ones last, then by score. Treat the weights as the platform's judgement, not a contract: read scoring rather than recomputing it.
SMS or RCS with SMS fallback
Templates are authored as SMS. channel=rcs rebuilds every send in the payload as a plain-text RCS message with the same SMS, unchanged, as its fallback for contacts RCS cannot reach. The consent policy is the same on both levels. There is no RCS-only mode.
rcsis accepted only when the template'schannelslists it, which means the project has an active RCS sender; otherwise the request is a400.- The mode is never chosen for you. RCS messages are billed as RCS, so offer it as an option to the person who will publish the flow rather than switching to it on their behalf.
Message language
The messages in payload are written in the project's language: Spanish for a Spanish project, English otherwise. lang only translates title and description.
When the organization's plan allows multi-language messages, every send in the payload also carries the other language as a translation, in the option's localizations. At send time each contact receives the translation matching their language, and anyone else receives the default text. See Translations.
What the payload leaves to you
A template payload validates as soon as one thing is added: the sender of each send. It is never set, on the message or on its translations, because which sender speaks for the brand is the customer's choice. Created without one, the flow is saved with valid: false and an error on each send, and it can be completed in the dashboard. See The send.
Everything else is already filled in the way the platform recommends:
- The trigger listens to the event's preferred source, and the exits to the same source.
- The audience is restricted to contacts with a mobile phone, so nobody enters a journey that can never send.
- Every marketing send waits in a smart delay that avoids illegal hours, and every send declares its consent policy.
- A contact is never inside two runs of the same flow at once, and journeys that should happen once (a welcome) or not too often (a checkout reminder) carry their own re-entry limits.
Creating a flow from a template
List the templates
Call
GET /flow/templatesand pick the item to use: typically arecommendedone, or the one the user asked for by name.Set the senders
Add the id of a sender from this project to each send in
payload. Change anything else the user asked for, and nothing more.Create the flow
Send the payload as
draftand the item'skeyastemplate, so the flow records where it came from and the template is markedused.
curl -X POST "$BASE/flow" \
-H "Authorization: Bearer $INSTASENT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Abandoned checkout",
"template": "abandoned-checkout",
"draft": { "trigger": { "stepClass": "TRIGGER_CONTACT_EVENT", "eventType": "ecommerce_checkout_init" } }
}'The draft above is shortened: send the whole payload. The response and its errors are in Creating and editing drafts. An unknown template key is a 400.
What would an integration unlock
integration=<key> answers "which journeys would connecting this integration make possible?". It keeps only the templates that integration can feed and scores them as if it were connected:
- If the project has connected it, the templates score on its real data.
- If it has not, the integration counts as a source that has sent nothing yet, so its templates come back
availablewith notrigger.datasourceId, unless another source already sends the event.
An unknown integration, or one that cannot trigger flows, is a 400. Take the keys from the integrations of the items.
Errors
| Status | When |
|---|---|
400 | channel is not one the project can use (rcs without an active RCS sender, or an unknown value), or integration is unknown or cannot trigger flows. |
401, 403, 429, 5xx | As described in Errors. |