Skip to main content
POST
/
api
/
v1
/
form-filling
/
session
/
{ambient_session_id}
/
{entity}
/
feedback
cURL
curl --request POST \
  --url https://sdp.suki.ai/api/v1/form-filling/session/<ambient_session_id>/<entity>/feedback \
  --header 'Content-Type: application/json' \
  --header 'sdp_suki_token: <sdp_suki_token>' \
  --header 'sdp_provider_id: <sdp_provider_id>' \
  --data '{
  "feedback": {
    "qualitative_comments": "Accurate and well-structured form output.",
    "ratingFeedback": {
      "min_rating": 1,
      "max_rating": 5,
      "rating": 5
    }
  },
  "feedback_metadata": {
    "form_id": "018f94e8-7aa8-7bfd-bc83-046262001234"
  }
}'
import requests

url = "https://sdp.suki.ai/api/v1/form-filling/session/{ambient_session_id}/{entity}/feedback"

payload = {
    "feedback": {
        "qualitative_comments": "Accurate and well-structured form output.",
        "ratingFeedback": {
            "min_rating": 1,
            "max_rating": 5,
            "rating": 5
        }
    },
    "feedback_metadata": { "form_id": "018f94e8-7aa8-7bfd-bc83-046262001234" }
}
headers = {
    "sdp_suki_token": "<api-key>",
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.text)
const options = {
  method: 'POST',
  headers: {sdp_suki_token: '<api-key>', 'Content-Type': 'application/json'},
  body: JSON.stringify({
    feedback: {
      qualitative_comments: 'Accurate and well-structured form output.',
      ratingFeedback: {min_rating: 1, max_rating: 5, rating: 5}
    },
    feedback_metadata: {form_id: '018f94e8-7aa8-7bfd-bc83-046262001234'}
  })
};

fetch('https://sdp.suki.ai/api/v1/form-filling/session/{ambient_session_id}/{entity}/feedback', 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}/{entity}/feedback",
  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([
    'feedback' => [
        'qualitative_comments' => 'Accurate and well-structured form output.',
        'ratingFeedback' => [
                'min_rating' => 1,
                'max_rating' => 5,
                'rating' => 5
        ]
    ],
    'feedback_metadata' => [
        'form_id' => '018f94e8-7aa8-7bfd-bc83-046262001234'
    ]
  ]),
  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}/{entity}/feedback"

	payload := strings.NewReader("{\n  \"feedback\": {\n    \"qualitative_comments\": \"Accurate and well-structured form output.\",\n    \"ratingFeedback\": {\n      \"min_rating\": 1,\n      \"max_rating\": 5,\n      \"rating\": 5\n    }\n  },\n  \"feedback_metadata\": {\n    \"form_id\": \"018f94e8-7aa8-7bfd-bc83-046262001234\"\n  }\n}")

	req, _ := http.NewRequest("POST", 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.post("https://sdp.suki.ai/api/v1/form-filling/session/{ambient_session_id}/{entity}/feedback")
  .header("sdp_suki_token", "<api-key>")
  .header("Content-Type", "application/json")
  .body("{\n  \"feedback\": {\n    \"qualitative_comments\": \"Accurate and well-structured form output.\",\n    \"ratingFeedback\": {\n      \"min_rating\": 1,\n      \"max_rating\": 5,\n      \"rating\": 5\n    }\n  },\n  \"feedback_metadata\": {\n    \"form_id\": \"018f94e8-7aa8-7bfd-bc83-046262001234\"\n  }\n}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://sdp.suki.ai/api/v1/form-filling/session/{ambient_session_id}/{entity}/feedback")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["sdp_suki_token"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"feedback\": {\n    \"qualitative_comments\": \"Accurate and well-structured form output.\",\n    \"ratingFeedback\": {\n      \"min_rating\": 1,\n      \"max_rating\": 5,\n      \"rating\": 5\n    }\n  },\n  \"feedback_metadata\": {\n    \"form_id\": \"018f94e8-7aa8-7bfd-bc83-046262001234\"\n  }\n}"

response = http.request(request)
puts response.read_body
{
  "feedback_id": "<string>"
}
{
  "code": 400,
  "message": "invalid request"
}
{
  "code": 401,
  "message": "invalid token"
}
{
  "code": 403,
  "message": "forbidden"
}
{
  "code": 404,
  "message": "not found"
}
{
  "code": 500,
  "message": "internal server error"
}
Use this endpoint to submit feedback for a Form filling ambient session. This endpoint calls SubmitFormFillingFeedback, which is separate from the ambient SubmitFeedback API.

Requirements

  • ambient_session_id must reference a Form filling session with the underlying job type FORM_FILLING_ORCHESTRATION. If the session type does not match, the API returns a FailedPrecondition error.
  • Set entity to AMBIENT_GENERATED_MEDICAL_FORM when submitting feedback for a generated medical form.
  • feedback_metadata.form_id is required when entity is AMBIENT_GENERATED_MEDICAL_FORM. Pass the generated medical form instance ID. The API uses this ID to load the form details before forwarding the request to the feedback service.
On success, the API returns a feedback_id. The value matches the provided ambient_session_id, consistent with the ambient feedback API behavior. For rating scale guidance, refer to Form Filling feedback section.

Code examples

The code examples below use placeholders and the stage host 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.
from typing import Any, TypedDict, cast

import requests

BASE_URL = "https://sdp.suki-stage.com"

ENTITY_AMBIENT_GENERATED_MEDICAL_FORM = "AMBIENT_GENERATED_MEDICAL_FORM"


class QuantitativeFeedback(TypedDict, total=False):
    max_rating: int
    min_rating: int
    rating: int


class Feedback(TypedDict, total=False):
    qualitative_comments: str
    ratingFeedback: QuantitativeFeedback


class FeedbackMetadata(TypedDict):
    form_id: str


class FormFillingFeedbackPayload(TypedDict):
    feedback: Feedback
    feedback_metadata: FeedbackMetadata


class SubmitFeedbackResponse(TypedDict):
    feedback_id: str


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 _post_json_expect(url: str, headers: dict[str, str], payload: dict[str, Any], expect_status: int) -> dict[str, Any]:
    r = requests.post(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 submit_form_filling_feedback(
    suki_token: str,
    ambient_session_id: str,
    entity: str,
    body: FormFillingFeedbackPayload,
) -> SubmitFeedbackResponse:
    """POST /api/v1/form-filling/session/{ambient_session_id}/{entity}/feedback (sdp_suki_token header required). HTTP 201."""
    url = f"{BASE_URL}/api/v1/form-filling/session/{ambient_session_id}/{entity}/feedback"
    headers = {"sdp_suki_token": suki_token, "sdp_provider_id": "<sdp_provider_id>", "Content-Type": "application/json"}
    data = _post_json_expect(url, headers, dict(body), 201)
    fid = data.get("feedback_id")
    if not isinstance(fid, str) or not fid:
        raise ValueError(f"{url}: 201 response missing feedback_id")
    return cast(SubmitFeedbackResponse, {"feedback_id": fid})


if __name__ == "__main__":
    try:
        out = submit_form_filling_feedback(
            "YOUR_SUKI_TOKEN",
            "YOUR_AMBIENT_SESSION_ID",
            ENTITY_AMBIENT_GENERATED_MEDICAL_FORM,
            {
                "feedback": {
                    "qualitative_comments": "Accurate and well-structured form output.",
                    "ratingFeedback": {"min_rating": 1, "max_rating": 5, "rating": 5},
                },
                "feedback_metadata": {
                    "form_id": "018f94e8-7aa8-7bfd-bc83-046262001234",
                },
            },
        )
        print(out["feedback_id"])
    except (ApiHttpError, ValueError) as e:
        print(e)

Authorizations

sdp_suki_token
string
header
required

Suki access token for the authenticated provider. Obtain this by calling Login or Register with a valid partner_token. Pass the suki_token value from the JSON response as the sdp_suki_token header on REST requests and non-browser WebSocket upgrades. Browser WebSocket clients pass the token in Sec-WebSocket-Protocol instead. Tokens expire after one hour; call Login again to refresh.

Headers

sdp_provider_id
string

Optional - Stable identifier for the active provider. Omit for standard partners whose partner_token identifies the user. Required for Bearer partners and Single Auth Token authentication where multiple providers share one partner_token. Use the same provider_id you sent on Login or Register.

Example:

"provider-123"

Path Parameters

ambient_session_id
string
required

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.

entity
string
required

Entity type you are rating. For form-filling sessions, use AMBIENT_GENERATED_MEDICAL_FORM for generated medical form output.

Example:

"AMBIENT_GENERATED_MEDICAL_FORM"

Body

application/json

Quantitative rating and optional qualitative comments for the specified form-filling entity.

feedback
object
required

Required quantitative and qualitative feedback.

feedback_metadata
object

Required when entity is AMBIENT_GENERATED_MEDICAL_FORM.

Response

Resource created successfully.

Response body for /api/v1/form-filling/session/{ambient_session_id}/{entity}/feedback.

feedback_id
string

feedback identifier

Last modified on June 30, 2026