Send Notifications
Asynchronous Notifications
Webhook endpoint for receiving asynchronous notifications from Suki platform
POST
/
webhooks
/
notification
Receive asynchronous notifications (partner webhook)
curl --request POST \
--url https://sdp.suki.ai/webhooks/notification \
--header 'Content-Type: application/json' \
--data '
{
"encounter_id": "29de56bc-960a-4cd5-b18f-79a798d62874",
"error_code": "ERROR_CODE_TRANSCRIPTION",
"error_detail": "Error in transcription",
"session_id": "20965414-929a-4f71-a3e5-b92bec07d086",
"status": "failure"
}
'import requests
url = "https://sdp.suki.ai/webhooks/notification"
payload = {
"encounter_id": "29de56bc-960a-4cd5-b18f-79a798d62874",
"error_code": "ERROR_CODE_TRANSCRIPTION",
"error_detail": "Error in transcription",
"session_id": "20965414-929a-4f71-a3e5-b92bec07d086",
"status": "failure"
}
headers = {"Content-Type": "application/json"}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
encounter_id: '29de56bc-960a-4cd5-b18f-79a798d62874',
error_code: 'ERROR_CODE_TRANSCRIPTION',
error_detail: 'Error in transcription',
session_id: '20965414-929a-4f71-a3e5-b92bec07d086',
status: 'failure'
})
};
fetch('https://sdp.suki.ai/webhooks/notification', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://sdp.suki.ai/webhooks/notification",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'encounter_id' => '29de56bc-960a-4cd5-b18f-79a798d62874',
'error_code' => 'ERROR_CODE_TRANSCRIPTION',
'error_detail' => 'Error in transcription',
'session_id' => '20965414-929a-4f71-a3e5-b92bec07d086',
'status' => 'failure'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://sdp.suki.ai/webhooks/notification"
payload := strings.NewReader("{\n \"encounter_id\": \"29de56bc-960a-4cd5-b18f-79a798d62874\",\n \"error_code\": \"ERROR_CODE_TRANSCRIPTION\",\n \"error_detail\": \"Error in transcription\",\n \"session_id\": \"20965414-929a-4f71-a3e5-b92bec07d086\",\n \"status\": \"failure\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://sdp.suki.ai/webhooks/notification")
.header("Content-Type", "application/json")
.body("{\n \"encounter_id\": \"29de56bc-960a-4cd5-b18f-79a798d62874\",\n \"error_code\": \"ERROR_CODE_TRANSCRIPTION\",\n \"error_detail\": \"Error in transcription\",\n \"session_id\": \"20965414-929a-4f71-a3e5-b92bec07d086\",\n \"status\": \"failure\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://sdp.suki.ai/webhooks/notification")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Content-Type"] = 'application/json'
request.body = "{\n \"encounter_id\": \"29de56bc-960a-4cd5-b18f-79a798d62874\",\n \"error_code\": \"ERROR_CODE_TRANSCRIPTION\",\n \"error_detail\": \"Error in transcription\",\n \"session_id\": \"20965414-929a-4f71-a3e5-b92bec07d086\",\n \"status\": \"failure\"\n}"
response = http.request(request)
puts response.read_bodyThis response has no body data.{
"code": 400,
"message": "invalid request"
}{
"code": 401,
"message": "invalid token"
}{
"code": 500,
"message": "internal server error"
}- Notification Webhooks are available through the Partner APIs. Sessions created with the Web SDK, Mobile SDK, or Headless Web SDK use the same platform Webhook callbacks.
- Webhooks are available for ambient session and CKG data ingestion events..
Code examples
- Python
- TypeScript
from flask import Flask, request, jsonify
app = Flask(__name__)
@app.route('/webhooks/notification', methods=['POST'])
def handle_webhook():
"""
Webhook endpoint to receive notifications from Suki platform.
This endpoint should be hosted by your application.
"""
# The payload is received in the request body from Suki
data = request.get_json() # This is the payload sent by Suki
if not data:
return jsonify({"error": "Invalid request"}), 400
status = data.get("status")
if status == "success":
# Handle success notification
session_id = data.get("session_id")
encounter_id = data.get("encounter_id")
sessions = data.get("sessions", [])
additional_info = data.get("additional_info")
print(f"Session {session_id} completed successfully")
print(f"Encounter ID: {encounter_id}")
print(f"Total sessions: {len(sessions)}")
if additional_info:
print(f"Additional info: {additional_info}")
# Access links to retrieve content
if "_links" in data:
links = data["_links"]
print("Available links:")
# contents is an array of Link objects
if "contents" in links:
print(" Session contents:")
for link in links["contents"]:
print(f" {link.get('method')} {link.get('href')} - {link.get('name')}")
# encounter_content is an array of Link objects
if "encounter_content" in links:
print(" Encounter content:")
for link in links["encounter_content"]:
print(f" {link.get('method')} {link.get('href')} - {link.get('name')}")
# transcripts is an array of Link objects
if "transcripts" in links:
print(" Transcripts:")
for link in links["transcripts"]:
print(f" {link.get('method')} {link.get('href')} - {link.get('name')}")
# status is an array of Link objects
if "status" in links:
print(" Status:")
for link in links["status"]:
print(f" {link.get('method')} {link.get('href')} - {link.get('name')}")
return jsonify({"message": "Notification received"}), 200
elif status == "failure":
# Handle failure notification
session_id = data.get("session_id")
encounter_id = data.get("encounter_id")
error_code = data.get("error_code")
error_detail = data.get("error_detail")
print(f"Session {session_id} failed")
print(f"Encounter ID: {encounter_id}")
print(f"Error Code: {error_code}")
print(f"Error Detail: {error_detail}")
return jsonify({"message": "Failure notification received"}), 200
else:
return jsonify({"error": "Unknown status"}), 400
if __name__ == '__main__':
app.run(port=3000)
import express from 'express';
const app = express();
app.use(express.json());
app.post('/webhooks/notification', (req, res) => {
/**
* Webhook endpoint to receive notifications from Suki platform.
* This endpoint should be hosted by your application.
*/
// The payload is received in the request body from Suki
const data = req.body; // This is the payload sent by Suki
if (!data) {
return res.status(400).json({ error: 'Invalid request' });
}
const status = data.status;
if (status === 'success') {
// Handle success notification
const sessionId = data.session_id;
const encounterId = data.encounter_id;
const sessions = data.sessions || [];
const additionalInfo = data.additional_info;
console.log(`Session ${sessionId} completed successfully`);
console.log(`Encounter ID: ${encounterId}`);
console.log(`Total sessions: ${sessions.length}`);
if (additionalInfo) {
console.log(`Additional info:`, additionalInfo);
}
// Access links to retrieve content
if (data._links) {
const links = data._links;
console.log('Available links:');
// contents is an array of Link objects
if (links.contents) {
console.log(' Session contents:');
links.contents.forEach((link: any) => {
console.log(` ${link.method} ${link.href} - ${link.name}`);
});
}
// encounter_content is an array of Link objects
if (links.encounter_content) {
console.log(' Encounter content:');
links.encounter_content.forEach((link: any) => {
console.log(` ${link.method} ${link.href} - ${link.name}`);
});
}
// transcripts is an array of Link objects
if (links.transcripts) {
console.log(' Transcripts:');
links.transcripts.forEach((link: any) => {
console.log(` ${link.method} ${link.href} - ${link.name}`);
});
}
// status is an array of Link objects
if (links.status) {
console.log(' Status:');
links.status.forEach((link: any) => {
console.log(` ${link.method} ${link.href} - ${link.name}`);
});
}
}
return res.status(200).json({ message: 'Notification received' });
} else if (status === 'failure') {
// Handle failure notification
const sessionId = data.session_id;
const encounterId = data.encounter_id;
const errorCode = data.error_code;
const errorDetail = data.error_detail;
console.log(`Session ${sessionId} failed`);
console.log(`Encounter ID: ${encounterId}`);
console.log(`Error Code: ${errorCode}`);
console.log(`Error Detail: ${errorDetail}`);
return res.status(200).json({ message: 'Failure notification received' });
} else {
return res.status(400).json({ error: 'Unknown status' });
}
});
app.listen(3000, () => {
console.log('Webhook server listening on port 3000');
});
Body
application/json
Webhook payload Suki sends when session processing fails.
Id of the encounter to which the payload belongs.
Example:
"29de56bc-960a-4cd5-b18f-79a798d62874"
Error code.
Example:
"ERROR_CODE_TRANSCRIPTION"
Details of the error, if any.
Example:
"Error in transcription"
Id of the session that failed.
Example:
"20965414-929a-4f71-a3e5-b92bec07d086"
Example:
"failure"
Response
Last modified on August 13, 2026
Was this page helpful?
Receive asynchronous notifications (partner webhook)
curl --request POST \
--url https://sdp.suki.ai/webhooks/notification \
--header 'Content-Type: application/json' \
--data '
{
"encounter_id": "29de56bc-960a-4cd5-b18f-79a798d62874",
"error_code": "ERROR_CODE_TRANSCRIPTION",
"error_detail": "Error in transcription",
"session_id": "20965414-929a-4f71-a3e5-b92bec07d086",
"status": "failure"
}
'import requests
url = "https://sdp.suki.ai/webhooks/notification"
payload = {
"encounter_id": "29de56bc-960a-4cd5-b18f-79a798d62874",
"error_code": "ERROR_CODE_TRANSCRIPTION",
"error_detail": "Error in transcription",
"session_id": "20965414-929a-4f71-a3e5-b92bec07d086",
"status": "failure"
}
headers = {"Content-Type": "application/json"}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
encounter_id: '29de56bc-960a-4cd5-b18f-79a798d62874',
error_code: 'ERROR_CODE_TRANSCRIPTION',
error_detail: 'Error in transcription',
session_id: '20965414-929a-4f71-a3e5-b92bec07d086',
status: 'failure'
})
};
fetch('https://sdp.suki.ai/webhooks/notification', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://sdp.suki.ai/webhooks/notification",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'encounter_id' => '29de56bc-960a-4cd5-b18f-79a798d62874',
'error_code' => 'ERROR_CODE_TRANSCRIPTION',
'error_detail' => 'Error in transcription',
'session_id' => '20965414-929a-4f71-a3e5-b92bec07d086',
'status' => 'failure'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://sdp.suki.ai/webhooks/notification"
payload := strings.NewReader("{\n \"encounter_id\": \"29de56bc-960a-4cd5-b18f-79a798d62874\",\n \"error_code\": \"ERROR_CODE_TRANSCRIPTION\",\n \"error_detail\": \"Error in transcription\",\n \"session_id\": \"20965414-929a-4f71-a3e5-b92bec07d086\",\n \"status\": \"failure\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://sdp.suki.ai/webhooks/notification")
.header("Content-Type", "application/json")
.body("{\n \"encounter_id\": \"29de56bc-960a-4cd5-b18f-79a798d62874\",\n \"error_code\": \"ERROR_CODE_TRANSCRIPTION\",\n \"error_detail\": \"Error in transcription\",\n \"session_id\": \"20965414-929a-4f71-a3e5-b92bec07d086\",\n \"status\": \"failure\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://sdp.suki.ai/webhooks/notification")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Content-Type"] = 'application/json'
request.body = "{\n \"encounter_id\": \"29de56bc-960a-4cd5-b18f-79a798d62874\",\n \"error_code\": \"ERROR_CODE_TRANSCRIPTION\",\n \"error_detail\": \"Error in transcription\",\n \"session_id\": \"20965414-929a-4f71-a3e5-b92bec07d086\",\n \"status\": \"failure\"\n}"
response = http.request(request)
puts response.read_bodyThis response has no body data.{
"code": 400,
"message": "invalid request"
}{
"code": 401,
"message": "invalid token"
}{
"code": 500,
"message": "internal server error"
}