ThunderPhone 2.0 is live.Self-serve, from 2¢/min.Read the announcement

Connect tools & data

Use ThunderPhone with n8n

Install the ThunderPhone node for n8n, connect a server API key, and build a workflow that runs every time a call ends.

n8n is a workflow automation tool. The ThunderPhone package for n8n adds two nodes:

  • ThunderPhone Trigger starts a workflow when a call ends (Call Completed) or a call grading run finishes (Call Graded).
  • ThunderPhone places outbound calls, adds contacts to campaigns and starts them, gets calls with their transcript and recording, and lists your agents and phone numbers.

It is a verified community node, listed at ThunderPhone on n8n.

Install the node

In the n8n editor, click + to open the nodes panel and search for ThunderPhone. An instance owner may need to set up verified nodes before other users can add them.

On self-hosted n8n, you can also install by package name: open Settings > Community Nodes and install n8n-nodes-thunderphone. Check community-node risks and your instance policy before you install.

Create a server API key

  1. Open the Keys tab

    In ThunderPhone, go to Organization → Keys and click Create key.

  2. Name it

    Use a name that says where the key lives, such as "n8n".

  3. Copy it now

    The full sk_live_... secret is shown once. Copy it before you close the dialog.

Only an admin or owner can create the key, and ThunderPhone treats requests made with it as coming from that person. The trigger and the campaign operations need that person to keep the admin or owner role. Create a server API key covers rotation and revocation.

Add the credential in n8n

  1. In n8n, create a credential of type ThunderPhone API.
  2. Paste the key into API Key.
  3. Save it and run the credential test. The test reads one call from your organization with GET /v1/calls?limit=1.

Build a first workflow

This workflow adds a row to a Google Sheet every time a call ends.

  1. Add the trigger

    Add ThunderPhone Trigger, select your ThunderPhone API credential, and set Event to Call Completed.

  2. Get the call

    Add a ThunderPhone node. Set Resource to Call, Operation to Get, and Call ID to the expression {{ $json.data.call_id }}. The output is the call record plus transcripts and recording_url, a short-lived link that is null when the call has no recording.

  3. Append a row

    Add a Google Sheets node that appends a row, and map the columns you want from the Get Call output (see the table below).

  4. Activate the workflow

    Save and activate. The trigger registers its Production URL as a webhook endpoint in your ThunderPhone organization. Deactivating the workflow deletes that endpoint.

  5. Test it

    Open an agent in the builder, click Talk, and end the call. Builder test calls are delivered as web.complete, one of the two events behind Call Completed, so the workflow runs and a row appears.

Useful columns:

ColumnExpression
Call ID{{ $json.call_id }}
Direction{{ $json.direction }}
From{{ $json.from_number }}
To{{ $json.to_number }}
Started{{ $json.start_time }}
Duration (s){{ $json.duration_seconds }}
Status{{ $json.status }}
End reason{{ $json.end_reason }}
Transcript{{ $json.transcripts.filter(t => typeof t.content === 'string').map(t => t.role + ': ' + t.content).join('\n') }}

The recording URL expires. Store the call ID and run Get Call again when you need a fresh link.

The trigger outputs the complete event: type, event_id and data. See telephony.complete / web.complete and call.graded for every field. Delivery is at least once, and event_id stays the same across retries of one event, so check it before a step that must not repeat.

Place outbound calls safely

Place Outbound Call (Resource Outbound Call, Operation Place) takes:

FieldMeaning
Agent Name or IDA saved agent. The dropdown lists your agents.
Phone Number Name or IDThe from number. The dropdown lists only numbers enabled for outbound calls.
To NumberDestination in E.164 format, e.g. +14155550199.
VariablesJSON object of values for placeholders in the agent prompt.
Idempotency KeyA stable ID from the upstream record or event. Required.

Map the Idempotency Key to an ID from whatever caused the run, such as a CRM record ID or the trigger's event_id. The node sends n8n:<node ID>:<your value>, so:

  • An automatic retry or Retry execution sends the same key, and ThunderPhone returns the original call with idempotent_replay: true instead of dialing again.
  • Two ThunderPhone nodes fed the same record send different keys.
  • A blank value fails before any request is sent.

Avoid timestamps, random values, and n8n execution or workflow IDs. A new value on retry places a second real call. The whole key can be at most 128 characters. Reusing a key with a different agent, number or variables fails with a conflict.

Campaigns. Add Contacts (Resource Campaign) adds contacts to a draft campaign. It takes a Campaign ID and a JSON array of contacts. Each contact needs phone_number; other keys become call variables. The node fails when every contact is rejected and sets partial_success: true when only some are. Start requires the checkbox confirming that the campaign places real calls and spends ThunderPhone credits. See Outbound campaigns.

Before a workflow starts calls:

  • If ThunderPhone asks your organization to confirm that its outbound calls follow the TCPA and other calling laws, an admin must record that confirmation in the dashboard first.
  • The from number must be enabled for outbound calls. Numbers you bring from your own carrier qualify once verified. ThunderPhone numbers start inbound-only and can be approved for outbound use: an admin requests it from the Phone Numbers page. See Get a phone number.
  • Your organization is responsible for having consent to call each number and for following the calling laws that apply. See Outbound calling laws.

Example workflows

  • CRM contacts to a campaign. Add CRM contacts to a draft ThunderPhone campaign, then start the campaign once someone approves the list.
  • Completed call to the customer record. On Call Completed, run Get Call and save the transcript and recording link to the matching customer record.
  • Low grades to review. On Call Graded, filter on {{ $json.data.grade.score }} and route low-scoring calls to a review queue with the call ID and grade details. A call can be graded more than once, and each finished grading run fires the trigger, so keep only the latest graded_at for each call ID.