Form Filling Asynchronous Notifications
Webhook endpoint for receiving asynchronous notifications when Form filling session processing completes
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"
}Use this endpoint specification to implement a endpoint in your application that receives notifications from the Suki platform.
This endpoint should be hosted by your application to receive notifications about Form filling completion or failure.
Learn more about how webhooks work and how to implement your webhook endpoint in Notification webhook for partners.
Host this endpoint on your server. Suki sends a POST when Form filling processing completes or fails. The payload
session_id is the Form filling session ID from Create Form Filling session.Code examples
- Python
- TypeScript
from flask import Flask, request, jsonify
app = Flask(__name__)
@app.route('/webhooks/notification', methods=['POST'])
def handle_webhook():
"""
Webhook endpoint for Form filling session notifications.
Verify X-API-Key and generated-at before parsing JSON; see Signature verification guide.
"""
# TODO: verify webhook signature (see /documentation/webhook/signature-verification)
data = request.get_json()
if not data:
return jsonify({"error": "Invalid request"}), 400
status = data.get("status")
if status == "success":
session_id = data.get("session_id")
encounter_id = data.get("encounter_id")
print(f"Form filling session {session_id} completed (encounter {encounter_id})")
links = data.get("_links") or {}
for link in links.get("structured_data") or []:
print(f" Structured data: {link.get('method')} {link.get('href')}")
for link in links.get("status") or []:
print(f" Status: {link.get('method')} {link.get('href')}")
return jsonify({"message": "Notification received"}), 200
if status == "failure":
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"Form filling session {session_id} failed (encounter {encounter_id}): "
f"{error_code} - {error_detail}"
)
return jsonify({"message": "Failure notification received"}), 200
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) => {
// TODO: verify webhook signature (see /documentation/webhook/signature-verification)
const data = req.body;
if (!data) {
return res.status(400).json({ error: 'Invalid request' });
}
const status = data.status;
if (status === 'success') {
const sessionId = data.session_id;
const encounterId = data.encounter_id;
console.log(`Form filling session ${sessionId} completed (encounter ${encounterId})`);
const links = data._links ?? {};
(links.structured_data ?? []).forEach((link: { method?: string; href?: string }) => {
console.log(` Structured data: ${link.method} ${link.href}`);
});
(links.status ?? []).forEach((link: { method?: string; href?: string }) => {
console.log(` Status: ${link.method} ${link.href}`);
});
return res.status(200).json({ message: 'Notification received' });
}
if (status === 'failure') {
console.log(
`Form filling session ${data.session_id} failed (encounter ${data.encounter_id}): ` +
`${data.error_code} - ${data.error_detail}`,
);
return res.status(200).json({ message: 'Failure notification received' });
}
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 June 30, 2026
Was this page helpful?
⌘I
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"
}