Workflows

A workflow is a reusable automation that fires on a call event, calls an HTTP API (your CRM, an ITSM, a Power Automate flow, any HTTPS endpoint), and can store fields from the response as variables that the rest of the call can reuse. Use workflows to look up a customer at the moment of pickup, store their CRM/ITSM record id, and push the call result back to that record when the call ends.

Each workflow is built from one Action — a single HTTP call with a method, URL, headers, body and an optional response mapping.

The big picture: get → map → store → reuse

The pattern that makes workflows powerful is looking data up early and reusing it later:

  1. Get — on Agent Connected, a workflow calls your CRM/ITSM API with the caller’s number.
  2. Map & store — the Mapping pulls the record id out of the response and stores it as $CRM_CONTACT_ID$.
  3. Reuse — on Call Ended, a second workflow pushes the call outcome (duration, summary, recording link) back to that same record using $CRM_CONTACT_ID$.

Stored variables live on the call (in its workflowContext) and persist across triggers, so a value captured at Agent Connected is still available at Call Ended.

Agent Connected ──► GET  https://crm/contacts?phone=$CALLER_ID_E164$
                     mapping: { CRM_CONTACT_ID: "id" }      ─┐  stores $CRM_CONTACT_ID$
                                                             │
Call Ended ───────► POST https://crm/contacts/$CRM_CONTACT_ID$/calls  ◄─┘  reuses it
                     body: { duration: "$CALL_HANDLE_TIME$", summary: "$CALL_SUMMARY$" }

Creating a workflow

  1. Open Workflows from the sidebar.
  2. Click +Add.
  3. Fill in the fields and click Save.

Fields

Field Description
Display name Workflow name. Required.
Scope The Entity the workflow belongs to. Required.
Trigger event The call event that fires the workflow — one of the five below. Required.
Action → Method HTTP method: GET, POST or PUT.
Action → URL The API endpoint to call. Supports $VARIABLE$ tokens (e.g. ?phone=$CALLER_ID_E164$).
Action → Headers Key/value list of HTTP headers (e.g. Authorization). Values support $VARIABLE$.
Action → Body (JSON) JSON object sent with POST/PUT. Values support $VARIABLE$. Toggle on/off.
Action → Mapping Key/value list that stores response fields as variables — { variableName : responseField }. Toggle on/off.

Trigger events

Pick one event per workflow from the fixed list shown in the portal.

Event When it fires Typical use
Agent Connected An agent picks up the call. Screen-pop / look up the customer and store their CRM/ITSM id for later.
Customer Abandoned The caller hangs up while waiting in queue. Log a missed call / create a call-back task.
Call Connected The call is connected end to end. Notify an external system that a conversation started.
Call Ended The call ends, regardless of outcome. Push the call result (duration, summary, recording) back to the CRM/ITSM.
Agent Declined An alerted agent rejects or lets it ring out (RONA). Alerting / supervision hooks.

Look-ups belong on Agent Connected (early, so the value is available for the rest of the call). Write-backs belong on Call Ended (late, when the duration, summary and recording link exist).

Action: calling an API

The Action is one HTTP request.

  • MethodGET to read, POST/PUT to send a body. For GET, put any query parameters directly in the URL.
  • URL — the full HTTPS endpoint. Every $VARIABLE$ is replaced before the call is sent.
  • Headers — add one row per header. Common headers:
Header Example value
Authorization Bearer $env.CRM_TOKEN$
Ocp-Apim-Subscription-Key $env.APIM_KEY$
Content-Type application/json
  • Body (JSON) — sent with POST/PUT. Must be a valid JSON object (no duplicate keys, not an array).

Calling a Power Automate flow

Paste the flow’s HTTP request trigger URL into URL, set Method to POST, and send your fields in the Body:

// Action
"method": "POST",
"url": "https://prod-xx.westeurope.logic.azure.com/workflows/.../triggers/manual/paths/invoke?...sig=...",
"headers": { "Content-Type": "application/json" },
"body": {
  "callId": "$callId$",
  "caller": "$CALLER_ID_E164$",
  "agent": "$AGENT_NAME$",
  "summary": "$CALL_SUMMARY$"
}

If the Power Automate flow responds with data, add a Mapping to capture it (see below).

Variables — using call data in the Action

Anywhere in the URL, Headers or Body, wrap a variable name in $...$ and Heedify replaces it with the live value before sending the request. Names are case-sensitive; an unknown token is left unchanged.

Most-used variables

Variable Value
$callId$ Unique call id
$tenantId$ Tenant id
$CALLER_ID$ Caller number (digits, no +) or Teams user id
$CALLER_ID_E164$ Caller number in E.164 (+33…) — use this for CRM lookups
$AGENT_ID$ / $AGENT_NAME$ Connected agent id / display name
$FLOW_NAME$ Call flow name
$QUEUE_NAME$ First queue the call went through
$CALL_HANDLE_TIME$ Talk time in seconds (available at Call Ended)
$CALL_TERMINATION_REASON$ How the call ended (available at Call Ended)
$CALL_SUMMARY$ AI call summary (available at Call Ended when transcription is on)
$CALL_SENTIMENT$ Call sentiment: positive / neutral / negative / mixed
$RECORDING_FILE_URL$ Link to the recording (available at Call Ended when recording is on)
$TRANSCRIPT_FILE_URL$ Link to the transcript
$env.NAME$ An environment secret (for tokens/keys — never hard-code secrets)

Not every variable exists at every moment. Caller, agent, flow and queue values are available from Agent Connected. Duration, termination reason, summary, sentiment and recording/transcript links only become available at Call Ended (summary and transcript require transcription/recording to be enabled on the flow).

Mapping — storing the response for later

A Mapping turns fields from the API response into named variables you can reuse for the rest of the call. Each line is:

variableName  ⟶  responseField
  • Left (key) — the variable name you invent. Use it later as $variableName$. Pick names that won’t clash with the built-ins above.
  • Right (value) — the field to read from the response JSON.

Example — look up a customer at pickup and store their CRM contact id and tier:

// Workflow A — Trigger: Agent Connected
"action": {
  "method": "GET",
  "url": "https://crm.example.com/contacts?phone=$CALLER_ID_E164$",
  "headers": { "Authorization": "Bearer $env.CRM_TOKEN$" },
  "mapping": {
    "CRM_CONTACT_ID": "id",
    "CRM_TIER": "tier"
  }
}

After Workflow A runs, $CRM_CONTACT_ID$ and $CRM_TIER$ are available to every later workflow on the same call.

Then push the result back when the call ends:

// Workflow B — Trigger: Call Ended
"action": {
  "method": "POST",
  "url": "https://crm.example.com/contacts/$CRM_CONTACT_ID$/activities",
  "headers": { "Authorization": "Bearer $env.CRM_TOKEN$" },
  "body": {
    "type": "phone_call",
    "agent": "$AGENT_NAME$",
    "durationSec": "$CALL_HANDLE_TIME$",
    "outcome": "$CALL_TERMINATION_REASON$",
    "summary": "$CALL_SUMMARY$",
    "recording": "$RECORDING_FILE_URL$"
  }
}

The same pattern works for an ITSM: store the ticket id at Agent Connected, append the call notes/recording to that ticket at Call Ended.

Worked example — CRM/ITSM screen-pop and write-back

Step Trigger Action Stores / uses
1. Look up Agent Connected GET …/contacts?phone=$CALLER_ID_E164$ stores $CRM_CONTACT_ID$
2. Open ticket (optional) Agent Connected POST …/tickets with { "contactId": "$CRM_CONTACT_ID$" } stores $TICKET_ID$
3. Write back Call Ended POST …/tickets/$TICKET_ID$/notes with summary, duration, recording uses $CRM_CONTACT_ID$, $TICKET_ID$, $CALL_SUMMARY$

Order matters: a workflow that stores a variable must run before the workflow that uses it. The look-up (step 1) is on an early trigger; the write-back (step 3) is on Call Ended.

Validation

  • Action URL must use HTTP or HTTPS.
  • Body must be valid JSON — an object, no duplicate keys, not an array.
  • Mapping and Header values must be strings.

Attaching a workflow

Workflows run for the Entity (Scope) you selected, on the trigger you picked. You can also reference them from:

FAQ

Q: How do I store data from an API call and reuse it later? A: Add a Mapping to the Action. Each line stores a response field under a variable name (e.g. CRM_CONTACT_ID = id). It becomes $CRM_CONTACT_ID$ and stays available for the rest of the call, including later workflows on later triggers.

Q: Can a workflow send custom HTTP headers? A: Yes — the Headers key/value list. Use it for Authorization, Ocp-Apim-Subscription-Key, serviceApiKey, Content-Type, etc. Values support $VARIABLE$, so inject secrets with $env.NAME$.

Q: Can I call a Power Automate flow? A: Yes. Paste the flow’s HTTP trigger URL into the Action URL, set the method to POST, and send fields in the Body with $VARIABLE$ tokens. Map the response if the flow returns data you need later.

Q: What events trigger a workflow? A: Five fixed events: Agent Connected, Customer Abandoned, Call Connected, Call Ended, Agent Declined. Each workflow listens to exactly one.

Q: What validation does Heedify apply? A: The Action URL must be HTTP/HTTPS. The Body must be valid JSON (object, no duplicate keys). Mapping and Header values must be strings.

Works with: Microsoft Teams, Teams Phone, HTTPS APIs, Power Automate, webhook-based CRMs and ITSMs, Variables, Call Flows, Queues. </content> </invoke>