Update Form Filling Session Context
Partially update Form filling session context using the Form filling URL binding
curl --request PATCH \
--url https://sdp.suki.ai/api/v1/form-filling/session/<ambient_session_id>/context \
--header 'Content-Type: application/json' \
--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}/context"
payload = { "form_filling": { "values": [{ "form_template_id": "019d4cdc-9319-7d81-ae2e-fd6de7f1b4f0" }] } }
headers = {
"sdp_suki_token": "<api-key>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PATCH',
headers: {sdp_suki_token: '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
form_filling: {values: [{form_template_id: '019d4cdc-9319-7d81-ae2e-fd6de7f1b4f0'}]}
})
};
fetch('https://sdp.suki.ai/api/v1/form-filling/session/{ambient_session_id}/context', 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}/context",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PATCH",
CURLOPT_POSTFIELDS => json_encode([
'form_filling' => [
'values' => [
[
'form_template_id' => '019d4cdc-9319-7d81-ae2e-fd6de7f1b4f0'
]
]
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"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"
"strings"
"net/http"
"io"
)
func main() {
url := "https://sdp.suki.ai/api/v1/form-filling/session/{ambient_session_id}/context"
payload := strings.NewReader("{\n \"form_filling\": {\n \"values\": [\n {\n \"form_template_id\": \"019d4cdc-9319-7d81-ae2e-fd6de7f1b4f0\"\n }\n ]\n }\n}")
req, _ := http.NewRequest("PATCH", url, payload)
req.Header.Add("sdp_suki_token", "<api-key>")
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.patch("https://sdp.suki.ai/api/v1/form-filling/session/{ambient_session_id}/context")
.header("sdp_suki_token", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"form_filling\": {\n \"values\": [\n {\n \"form_template_id\": \"019d4cdc-9319-7d81-ae2e-fd6de7f1b4f0\"\n }\n ]\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://sdp.suki.ai/api/v1/form-filling/session/{ambient_session_id}/context")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Patch.new(url)
request["sdp_suki_token"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"form_filling\": {\n \"values\": [\n {\n \"form_template_id\": \"019d4cdc-9319-7d81-ae2e-fd6de7f1b4f0\"\n }\n ]\n }\n}"
response = http.request(request)
puts response.read_bodyform_filling, each values[] entry must use exactly one of form_template_id or schema. Refer to Dynamic Form filling.- Python
- TypeScript
from typing import Any, NotRequired, Optional, TypedDict, Union, cast
import requests
BASE_URL = "https://sdp.suki-stage.com"
class StaticFormEntry(TypedDict):
# Suki Medical form template. Do not also send `schema` in this object.
form_template_id: str
class DynamicFormEntry(TypedDict):
# Partner-defined form. Do not also send `form_template_id` in this object.
schema: dict[str, Any]
id: NotRequired[str]
name: NotRequired[str]
type: NotRequired[str]
FormFillingMetadata = Union[StaticFormEntry, DynamicFormEntry]
class FormFillingContext(TypedDict):
# Non-empty list. Mix static and dynamic entries when needed.
values: list[FormFillingMetadata]
class FormFillingUpdateContextRequest(TypedDict, total=False):
form_filling: FormFillingContext
class FormFillingReturnedContext(TypedDict, total=False):
form_filling: FormFillingContext
class FormFillingUpdateContextResponse(TypedDict):
context: FormFillingReturnedContext
class ApiHttpError(RuntimeError):
def __init__(self, status: int, url: str, detail: str) -> None:
super().__init__(f"HTTP {status} {url}: {detail}")
self.status = status
self.url = url
def _patch_json_expect(
url: str,
headers: dict[str, str],
payload: dict[str, Any],
expect_status: int,
) -> dict[str, Any]:
r = requests.patch(url, json=payload, 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 login_for_suki_token(partner_id: str, partner_token: str, *, provider_id: Optional[str] = None) -> str:
url = f"{BASE_URL}/api/v1/auth/login"
body: dict[str, Any] = {"partner_id": partner_id, "partner_token": partner_token}
if provider_id is not None:
body["provider_id"] = provider_id
r = requests.post(url, json=body, headers={"Content-Type": "application/json"}, timeout=60)
if r.status_code != 200:
raise ApiHttpError(r.status_code, url, (r.text or "")[:500] or "(no body)")
data = r.json()
token = data.get("suki_token") if isinstance(data, dict) else None
if not isinstance(token, str) or not token:
raise ValueError(f"{url}: 200 response missing suki_token")
return token
def update_form_filling_session_context(
suki_token: str,
ambient_session_id: str,
body: FormFillingUpdateContextRequest,
) -> FormFillingUpdateContextResponse:
"""PATCH /api/v1/form-filling/session/{ambient_session_id}/context. HTTP 200 returns FormFillingUpdateContextResponse."""
url = f"{BASE_URL}/api/v1/form-filling/session/{ambient_session_id}/context"
headers = {"sdp_suki_token": suki_token, "sdp_provider_id": "<sdp_provider_id>", "Content-Type": "application/json"}
data = _patch_json_expect(url, headers, dict(body), 200)
ctx = data.get("context")
if not isinstance(ctx, dict):
raise ValueError(f"{url}: 200 response missing context")
return cast(FormFillingUpdateContextResponse, {"context": cast(FormFillingReturnedContext, ctx)})
if __name__ == "__main__":
try:
token = login_for_suki_token("<partner_id>", "<partner_token>")
# Example mixes one Suki template and one partner schema.
# Each values[] entry must use either form_template_id or schema, never both.
out = update_form_filling_session_context(
token,
ambient_session_id="<ambient_session_id>",
body={
"form_filling": {
"values": [
{"form_template_id": "019d4cdc-9319-7d81-ae2e-fd6de7f1b4f0"},
{
"id": "partner-custom-1",
"name": "Custom Partner Form",
"type": "NEURO_ASSESSMENT",
"schema": {
"type": "object",
"properties": {"gcs": {"type": "number"}},
},
},
]
}
},
)
form_filling = out["context"].get("form_filling")
print(form_filling)
except (ApiHttpError, ValueError) as e:
print(e)
const BASE_URL = "https://sdp.suki-stage.com";
// Suki Medical form template. Do not also send `schema` in this object.
type StaticFormEntry = { form_template_id: string };
// Partner-defined form. Do not also send `form_template_id` in this object.
type DynamicFormEntry = {
schema: Record<string, unknown>;
id?: string;
name?: string;
type?: string;
};
type FormFillingMetadata = StaticFormEntry | DynamicFormEntry;
type FormFillingContext = { values: FormFillingMetadata[] }; // non-empty; mix allowed
type FormFillingUpdateContextRequest = { form_filling?: FormFillingContext };
type FormFillingReturnedContext = { form_filling?: FormFillingContext };
type FormFillingUpdateContextResponse = { context: FormFillingReturnedContext };
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 patchJsonExpectObject(
url: string,
init: RequestInit,
expectStatus: number,
): Promise<Record<string, unknown>> {
const res = await fetch(url, init);
const text = await res.text();
if (res.status !== expectStatus) {
let msg = text.slice(0, 500);
try {
const data: unknown = text ? JSON.parse(text) : null;
if (data && typeof data === "object" && "message" in data) {
msg = String((data as { message?: string }).message ?? msg);
}
} catch {
// keep raw text
}
throw new ApiHttpError(res.status, url, msg || "(no body)");
}
if (!text) throw new ApiHttpError(res.status, url, "(empty body)");
const data: unknown = JSON.parse(text);
if (data && typeof data === "object" && !Array.isArray(data)) {
return data as Record<string, unknown>;
}
throw new ApiHttpError(res.status, url, "response JSON was not an object");
}
async function loginForSukiToken(body: {
partner_id: string;
partner_token: string;
provider_id?: string;
}): Promise<string> {
const url = `${BASE_URL}/api/v1/auth/login`;
const json = await patchJsonExpectObject(
url,
{
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(body),
},
200,
);
const token = json.suki_token;
if (typeof token !== "string" || !token) throw new Error(`${url}: missing suki_token`);
return token;
}
async function updateFormFillingSessionContext(
sukiToken: string,
ambientSessionId: string,
body: FormFillingUpdateContextRequest,
): Promise<FormFillingUpdateContextResponse> {
const url = `${BASE_URL}/api/v1/form-filling/session/${ambientSessionId}/context`;
const json = await patchJsonExpectObject(
url,
{
method: "PATCH",
headers: {
sdp_suki_token: sukiToken, sdp_provider_id: "<sdp_provider_id>",
"Content-Type": "application/json",
},
body: JSON.stringify(body),
},
200,
);
const context = json.context;
if (!context || typeof context !== "object" || Array.isArray(context)) {
throw new Error(`${url}: 200 response missing context`);
}
return { context: context as FormFillingReturnedContext };
}
async function main(): Promise<void> {
try {
const token = await loginForSukiToken({
partner_id: "<partner_id>",
partner_token: "<partner_token>",
});
// Example mixes one Suki template and one partner schema.
// Each values[] entry must use either form_template_id or schema, never both.
const out = await updateFormFillingSessionContext(token, "<ambient_session_id>", {
form_filling: {
values: [
{ form_template_id: "019d4cdc-9319-7d81-ae2e-fd6de7f1b4f0" },
{
id: "partner-custom-1",
name: "Custom Partner Form",
type: "NEURO_ASSESSMENT",
schema: {
type: "object",
properties: { gcs: { type: "number" } },
},
},
],
},
});
console.log(out.context.form_filling);
} catch (e) {
console.error(e instanceof Error ? e.message : e);
}
}
void main();
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.
Body
Partial update for Form filling session context. Send only the fields you want to change.
Updated forms to fill for this session.
Show child attributes
Show child attributes
Response
Request succeeded.
Response body for the /api/v1/form-filling/session/{ambient_session_id}/context PATCH endpoint
Updated context for the form-filling session
Show child attributes
Show child attributes
Was this page helpful?
curl --request PATCH \
--url https://sdp.suki.ai/api/v1/form-filling/session/<ambient_session_id>/context \
--header 'Content-Type: application/json' \
--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}/context"
payload = { "form_filling": { "values": [{ "form_template_id": "019d4cdc-9319-7d81-ae2e-fd6de7f1b4f0" }] } }
headers = {
"sdp_suki_token": "<api-key>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PATCH',
headers: {sdp_suki_token: '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
form_filling: {values: [{form_template_id: '019d4cdc-9319-7d81-ae2e-fd6de7f1b4f0'}]}
})
};
fetch('https://sdp.suki.ai/api/v1/form-filling/session/{ambient_session_id}/context', 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}/context",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PATCH",
CURLOPT_POSTFIELDS => json_encode([
'form_filling' => [
'values' => [
[
'form_template_id' => '019d4cdc-9319-7d81-ae2e-fd6de7f1b4f0'
]
]
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"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"
"strings"
"net/http"
"io"
)
func main() {
url := "https://sdp.suki.ai/api/v1/form-filling/session/{ambient_session_id}/context"
payload := strings.NewReader("{\n \"form_filling\": {\n \"values\": [\n {\n \"form_template_id\": \"019d4cdc-9319-7d81-ae2e-fd6de7f1b4f0\"\n }\n ]\n }\n}")
req, _ := http.NewRequest("PATCH", url, payload)
req.Header.Add("sdp_suki_token", "<api-key>")
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.patch("https://sdp.suki.ai/api/v1/form-filling/session/{ambient_session_id}/context")
.header("sdp_suki_token", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"form_filling\": {\n \"values\": [\n {\n \"form_template_id\": \"019d4cdc-9319-7d81-ae2e-fd6de7f1b4f0\"\n }\n ]\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://sdp.suki.ai/api/v1/form-filling/session/{ambient_session_id}/context")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Patch.new(url)
request["sdp_suki_token"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"form_filling\": {\n \"values\": [\n {\n \"form_template_id\": \"019d4cdc-9319-7d81-ae2e-fd6de7f1b4f0\"\n }\n ]\n }\n}"
response = http.request(request)
puts response.read_body