Get Form Filling Structured Data
Retrieve structured medical form data for a Form filling session
curl --request GET \
--url https://sdp.suki.ai/api/v1/form-filling/session/<ambient_session_id>/structured-data \
--header 'sdp_suki_token: <sdp_suki_token>' \
--header 'sdp_provider_id: <sdp_provider_id>'import requests
url = "https://sdp.suki.ai/api/v1/form-filling/session/{ambient_session_id}/structured-data"
headers = {"sdp_suki_token": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {sdp_suki_token: '<api-key>'}};
fetch('https://sdp.suki.ai/api/v1/form-filling/session/{ambient_session_id}/structured-data', 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/api/v1/form-filling/session/{ambient_session_id}/structured-data",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"sdp_suki_token: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://sdp.suki.ai/api/v1/form-filling/session/{ambient_session_id}/structured-data"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("sdp_suki_token", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://sdp.suki.ai/api/v1/form-filling/session/{ambient_session_id}/structured-data")
.header("sdp_suki_token", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://sdp.suki.ai/api/v1/form-filling/session/{ambient_session_id}/structured-data")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["sdp_suki_token"] = '<api-key>'
response = http.request(request)
puts response.read_bodygenerated_values: Form instances for which Suki generated structured data. Entries can come from static Suki templates, dynamic partner schemas, or both in a mixed session.non_generated_values: Form template IDs for which Suki did not generate structured data.
id or title. Use the same id and name you sent when you set session context. Do not assume results come back in the same order. Refer to Dynamic Form filling.Code examples
sdp.suki-stage.com only as examples.
For credentials, base URLs, where to run Python or TypeScript, CORS, and cURL, refer to Using code examples in your integration in the API Reference Guidelines.- Python
- TypeScript
from typing import Any, TypedDict, cast
import requests
BASE_URL = "https://sdp.suki-stage.com"
class GeneratedFormInstance(TypedDict, total=False):
# Shared shape for static templates and dynamic schemas.
id: str # Dynamic: partner form_filling.values[].id when provided
data: dict[str, Any]
correlation_id: str
created_at: str
type: str
title: str # Dynamic: Context name when provided
patient_id: str
# Usually set for Suki templates; often empty for partner schemas.
status: str
form_template_id: str
metadata: dict[str, Any]
class NonGeneratedFormInstance(TypedDict, total=False):
# Sparse placeholder when a form did not produce output.
form_template_id: str
class FormFillingStructuredData(TypedDict, total=False):
generated_values: list[GeneratedFormInstance]
non_generated_values: list[NonGeneratedFormInstance]
class FormFillingStructuredDataResponse(TypedDict):
structured_data: FormFillingStructuredData
class ApiHttpError(RuntimeError):
"""Wrong HTTP status; OpenAPI errors usually include JSON with message + code."""
def __init__(self, status: int, url: str, detail: str) -> None:
super().__init__(f"HTTP {status} {url}: {detail}")
self.status = status
self.url = url
def _get_expect_json_object(url: str, headers: dict[str, str], expect_status: int) -> dict[str, Any]:
r = requests.get(url, headers=headers, timeout=60)
if r.status_code == expect_status:
data = r.json()
if isinstance(data, dict):
return data
raise ApiHttpError(expect_status, url, "response JSON was not an object")
detail = ""
try:
err = r.json()
if isinstance(err, dict) and isinstance(err.get("message"), str):
detail = err["message"]
except ValueError:
detail = (r.text or "")[:500]
raise ApiHttpError(r.status_code, url, detail or "(no body)")
def get_form_filling_structured_data(suki_token: str, ambient_session_id: str) -> FormFillingStructuredDataResponse:
"""GET /api/v1/form-filling/session/{ambient_session_id}/structured-data (sdp_suki_token header required). HTTP 200."""
url = f"{BASE_URL}/api/v1/form-filling/session/{ambient_session_id}/structured-data"
data = _get_expect_json_object(url, {"sdp_suki_token": suki_token, "sdp_provider_id": "<sdp_provider_id>"}, 200)
sd = data.get("structured_data")
if not isinstance(sd, dict):
raise ValueError(f"{url}: 200 response missing structured_data object")
return cast(FormFillingStructuredDataResponse, {"structured_data": sd})
if __name__ == "__main__":
try:
out = get_form_filling_structured_data("YOUR_SUKI_TOKEN", "YOUR_AMBIENT_SESSION_ID")
structured = out["structured_data"]
generated = structured.get("generated_values") or []
# For dynamic forms, match by id (Context form_filling.values[].id) or title (name).
by_id = {item.get("id"): item for item in generated if item.get("id")}
print(structured)
print("by_id keys:", list(by_id.keys()))
except (ApiHttpError, ValueError) as e:
print(e)
const BASE_URL = "https://sdp.suki-stage.com";
// Shared shape for static templates and dynamic schemas.
type GeneratedFormInstance = {
id?: string; // Dynamic: partner form_filling.values[].id when provided
data?: Record<string, unknown>;
correlation_id?: string;
created_at?: string;
type?: string;
title?: string; // Dynamic: Context name when provided
patient_id?: string;
// Usually set for Suki templates; often empty for partner schemas.
status?: string;
form_template_id?: string;
metadata?: Record<string, unknown>;
};
// Sparse placeholder when a form did not produce output.
type NonGeneratedFormInstance = {
form_template_id?: string;
};
type FormFillingStructuredData = {
generated_values?: GeneratedFormInstance[];
non_generated_values?: NonGeneratedFormInstance[];
};
type FormFillingStructuredDataResponse = {
structured_data: FormFillingStructuredData;
};
class ApiHttpError extends Error {
status: number;
url: string;
constructor(status: number, url: string, detail: string) {
super(`HTTP ${status} ${url}: ${detail}`);
this.status = status;
this.url = url;
}
}
async function getExpectJsonObject(url: string, headers: Record<string, string>, expectStatus: number) {
const res = await fetch(url, { method: "GET", headers });
const text = await res.text();
const json = text ? JSON.parse(text) : {};
if (res.status !== expectStatus) {
const msg = typeof (json as any)?.message === "string" ? (json as any).message : text?.slice(0, 500) || "(no body)";
throw new ApiHttpError(res.status, url, msg);
}
if (json && typeof json === "object" && !Array.isArray(json)) return json as Record<string, unknown>;
throw new ApiHttpError(res.status, url, "response JSON was not an object");
}
export async function getFormFillingStructuredData(
sukiToken: string,
ambientSessionId: string
): Promise<FormFillingStructuredDataResponse> {
const url = `${BASE_URL}/api/v1/form-filling/session/${ambientSessionId}/structured-data`;
const data = await getExpectJsonObject(url, { sdp_suki_token: sukiToken, sdp_provider_id: "<sdp_provider_id>" }, 200);
const sd = data.structured_data;
if (!sd || typeof sd !== "object" || Array.isArray(sd)) {
throw new Error(`${url}: 200 response missing structured_data object`);
}
return { structured_data: sd as FormFillingStructuredData };
}
// Example usage
const out = await getFormFillingStructuredData("YOUR_SUKI_TOKEN", "YOUR_AMBIENT_SESSION_ID");
const generated = out.structured_data.generated_values ?? [];
// For dynamic forms, match by id (Context form_filling.values[].id) or title (name).
const byId = Object.fromEntries(
generated.filter((item) => item.id).map((item) => [item.id as string, item]),
);
console.log(out.structured_data);
console.log("by_id keys:", Object.keys(byId));
Authorizations
Suki access token (suki_token) from Login or Register. Expires after one hour.
Headers
Optional for standard partners.
Required for:
- Bearer authentication. Use the same
provider_idreturned by the Login or Register API. - Single Auth Token authentication. Include the same
provider_idon every request assdp_provider_id.
"provider-123"
Path Parameters
Form-filling session ID. The path parameter is named ambient_session_id, but this value identifies the form-filling session, not an ambient clinical documentation session. Use the ID returned from Create Form filling Session, or the UUID you supplied in that request.
Response
Request succeeded.
Structured medical form output for a form-filling session. Response shape is the same for static, dynamic, and mixed sessions; field population differs by entry type.
Medical form instances for a form-filling session. generated_values can include static template instances and dynamic schema instances from the same session.
Show child attributes
Show child attributes
Was this page helpful?
curl --request GET \
--url https://sdp.suki.ai/api/v1/form-filling/session/<ambient_session_id>/structured-data \
--header 'sdp_suki_token: <sdp_suki_token>' \
--header 'sdp_provider_id: <sdp_provider_id>'import requests
url = "https://sdp.suki.ai/api/v1/form-filling/session/{ambient_session_id}/structured-data"
headers = {"sdp_suki_token": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {sdp_suki_token: '<api-key>'}};
fetch('https://sdp.suki.ai/api/v1/form-filling/session/{ambient_session_id}/structured-data', 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/api/v1/form-filling/session/{ambient_session_id}/structured-data",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"sdp_suki_token: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://sdp.suki.ai/api/v1/form-filling/session/{ambient_session_id}/structured-data"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("sdp_suki_token", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://sdp.suki.ai/api/v1/form-filling/session/{ambient_session_id}/structured-data")
.header("sdp_suki_token", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://sdp.suki.ai/api/v1/form-filling/session/{ambient_session_id}/structured-data")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["sdp_suki_token"] = '<api-key>'
response = http.request(request)
puts response.read_body