Skip to main content

Overview

Webhooks let Real Talk Studio push roleplay completion data to your own systems the moment a session finishes. When a user completes a roleplay, we send a POST request containing their score, skill feedback, timings, the full conversation transcript, and an optional anonymous identifier you supply (extCustId) so you can link the result back to the right user in your platform (CRM, LMS, etc.). There are two parts to setting this up:
1

Configure your app to send a user identifier in the URL

Pass extCustId as a query parameter on the embed URL so we can return it to you on completion.
2

Add your webhook address in Studio

Tell Real Talk Studio where to send completion data.
Once both are in place, every completed session triggers a webhook to your endpoint.

Setup

What is extCustId?

extCustId (external customer ID) is an anonymous key that you generate and control on your side. It is simply an opaque identifier you attach to a session so that, when the completion webhook arrives, you can associate that completion record with the right user, learner, or account in your own system. Real Talk Studio never interprets, validates, or stores meaning against this value — we just hold it for the session and hand it back to you untouched in the webhook. Because it is your own reference, you decide what it is:
  • A CRM contact ID, LMS user ID, or internal account ID
  • A hashed or tokenised identifier (recommended — it keeps personal data out of the URL)
  • Any random key you mint per session and store alongside the user in your database
Treat it as an anonymous correlation key, not as personal data. Avoid putting raw emails or names in the URL — use an ID or hash that only your system can resolve back to a person.

1. Send your identifier in the embed URL

When you embed or link to a roleplay, append an extCustId query parameter set to your key for that user. We store it for the session and send it straight back to you in the completion webhook so you can match the result to the correct record.
Embed URL with identifier
Append extCustId to your existing embed URL alongside any other parameters (such as studioId), separating each with &.
The parameter name is exactly extCustId (camelCase). It is optional — if you omit it, the webhook still fires, but extCustId will be null and you will need another way to correlate the result.
How it works: the extCustId from the URL is held for the duration of the session and then included in the completion webhook. It is a round trip — you supply it on the way in, and the same value comes back to you on the way out.

2. Add your webhook address in Studio

Within Real Talk Studio Admin Panel, open the roleplay studio you want to configure and edit its settings. In the Webhook URL field, enter the HTTPS endpoint that should receive completion data:
Example endpoint
The endpoint must be a publicly reachable HTTPS URL that accepts a POST request with a JSON body. We expect a 2x response; non-2xx responses are treated as a failed delivery.

Session: what we send on completion

When a user finishes a roleplay, we send a single POST request to your configured Webhook URL.

Request headers

Body

All fields are nested under a top-level data key.
Example webhook payload
Everything is wrapped in data. Read body.data.score, not body.score. This is the most common integration mistake.

Field reference

Optional fields may be null or absent depending on what was captured for a given session. Code defensively against missing values.

Transcript format

When a transcript was captured, transcript is an ordered array of conversation turns:
The transcript contains the full conversation and can be large. Make sure your endpoint accepts sizeable request bodies, and treat the contents as potentially sensitive (PII) when storing or displaying it.

Consuming the webhook

A typical integration receives the webhook, stores it in a completions table keyed by your extCustId, and then surfaces the data in your own reporting and dashboards. The pattern is the same regardless of stack:
1

Receive and validate

Accept the POST, confirm the data object is present, and respond with 2xx quickly.
2

Store

Upsert a row into your completions table, using extCustId to link it to the user.
3

Report

Query that table to build dashboards, leaderboards, manager views, or exports.

1. A table to hold completions

This schema mirrors the webhook payload. ext_cust_id is the anonymous key you sent in the embed URL, so it joins straight to your existing users table.
Postgres example

2. An endpoint that stores the payload

Node.js / Express
Storing skillsFeedback as a JSON column keeps the per-skill detail intact while remaining easy to query. In Postgres you can later expand it with jsonb_array_elements for skill-level reporting.

3. Integrate into your reporting pipeline

Once completions land in your table, they become a normal data source for your analytics. A few examples:
Average score per roleplay
Per-user progress (joined to your users table)
Skill-level breakdown across all sessions
From here you can feed the table into BI tools (Looker, Power BI, Metabase), push aggregates into a warehouse (BigQuery, Snowflake), or render dashboards directly in your product — for example a learner-facing score history view, a manager team leaderboard, or a skills heatmap built from the skills_feedback data.
Because every row carries ext_cust_id, you can attribute results to individual users, roll them up to teams or cohorts, and track improvement over time — all within your own platform.

Tips

  • Respond quickly with a 2xx. Do any heavy processing asynchronously after acknowledging receipt.
  • Use extCustId to correlate. It is your own anonymous key, returned untouched, and the reliable way to associate a completion record with a specific user in your system.
  • Validate the payload shape. Confirm data exists and handle optional fields gracefully.