> ## Documentation Index
> Fetch the complete documentation index at: https://developer.suki.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Form Filling Session Feedback

> Submit feedback for a Form filling session entity

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](/form-filling-api-reference/form-filling-feedback#rating-system) section.

## Code examples

<Note>
  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](/api-reference/api-guidelines#using-code-examples-in-your-integration) in the **API Reference Guidelines**.
</Note>

<Tabs>
  <Tab title="Python">
    ```python expandable theme={"theme":{"light":"github-dark","dark":"material-theme-darker"}}
    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)
    ```
  </Tab>

  <Tab title="TypeScript">
    ```typescript expandable theme={"theme":{"light":"github-dark","dark":"material-theme-darker"}}
    const BASE_URL = "https://sdp.suki-stage.com";

    const ENTITY_AMBIENT_GENERATED_MEDICAL_FORM = "AMBIENT_GENERATED_MEDICAL_FORM";

    type QuantitativeFeedback = {
      max_rating?: number;
      min_rating?: number;
      rating?: number;
    };

    type Feedback = {
      qualitative_comments?: string;
      ratingFeedback?: QuantitativeFeedback;
    };

    type FeedbackMetadata = {
      form_id: string;
    };

    type FormFillingFeedbackPayload = {
      feedback: Feedback;
      feedback_metadata: FeedbackMetadata;
    };

    type SubmitFeedbackResponse = { feedback_id: string };

    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 postJsonExpectObject(
      url: string,
      headers: Record<string, string>,
      body: Record<string, unknown>,
      expectStatus: number
    ): Promise<Record<string, unknown>> {
      const res = await fetch(url, { method: "POST", headers, body: JSON.stringify(body) });
      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 submitFormFillingFeedback(
      sukiToken: string,
      ambientSessionId: string,
      entity: string,
      body: FormFillingFeedbackPayload
    ): Promise<SubmitFeedbackResponse> {
      const url = `${BASE_URL}/api/v1/form-filling/session/${ambientSessionId}/${entity}/feedback`;
      const data = await postJsonExpectObject(
        url,
        { sdp_suki_token: sukiToken, sdp_provider_id: "<sdp_provider_id>", "Content-Type": "application/json" },
        body as Record<string, unknown>,
        201
      );
      const feedbackId = data.feedback_id;
      if (typeof feedbackId !== "string" || !feedbackId) {
        throw new Error(`${url}: 201 response missing feedback_id`);
      }
      return { feedback_id: feedbackId };
    }

    // Example usage
    const out = await submitFormFillingFeedback("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",
      },
    });
    console.log(out.feedback_id);
    ```
  </Tab>
</Tabs>


## OpenAPI

````yaml POST /api/v1/form-filling/session/{ambient_session_id}/{entity}/feedback
openapi: 3.0.1
info:
  title: Suki Developer Platform
  description: >-
    REST and WebSocket APIs for the Suki Developer Platform. Authenticate with
    Login or Register to obtain a Suki access token, then integrate ambient
    clinical documentation, form filling, transcription, and reference metadata
    endpoints.
  contact: {}
  version: '1.0'
servers:
  - url: https://sdp.suki.ai
    description: >-
      Production base URL for Suki Developer Platform REST APIs. WebSocket
      endpoints use the same host with `wss://`.
security:
  - SukiTokenAuth: []
paths:
  /api/v1/form-filling/session/{ambient_session_id}/{entity}/feedback:
    post:
      tags:
        - /api/v1/form-filling/session
      summary: Submit form-filling session feedback
      description: >-
        Submits feedback on form-filling session output. You can submit feedback
        once per entity type per session.
      parameters:
        - name: ambient_session_id
          in: path
          description: >-
            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.
          required: true
          schema:
            type: string
        - name: entity
          in: path
          description: >-
            Entity type you are rating. For form-filling sessions, use
            `AMBIENT_GENERATED_MEDICAL_FORM` for generated medical form output.
          required: true
          schema:
            type: string
            example: AMBIENT_GENERATED_MEDICAL_FORM
        - $ref: '#/components/parameters/ProviderIdHeader'
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/controllers.FormFillingFeedbackPayload'
            example:
              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
        required: true
      responses:
        '201':
          description: Resource created successfully.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/controllers.SubmitFeedbackResponse'
        '400':
          description: Bad request. The request body or parameters failed validation.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/controllers.BadRequestError'
        '401':
          description: Unauthorized. The Suki access token is missing, expired, or invalid.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/controllers.AuthenticationError'
        '403':
          description: Forbidden. The authenticated user cannot access this resource.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/controllers.ForbiddenError'
        '404':
          description: Not found. The session, encounter, or resource ID does not exist.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/controllers.NotFoundError'
        '500':
          description: Internal server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/controllers.InternalServerError'
      security:
        - SukiTokenAuth: []
      x-codeSamples:
        - lang: bash
          label: cURL
          source: |-
            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"
              }
            }'
components:
  parameters:
    ProviderIdHeader:
      name: sdp_provider_id
      in: header
      description: >-
        **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.
      required: false
      schema:
        type: string
        example: provider-123
  schemas:
    controllers.FormFillingFeedbackPayload:
      description: >-
        Quantitative rating and optional qualitative comments for the specified
        form-filling entity.
      type: object
      required:
        - feedback
      properties:
        feedback:
          description: Required quantitative and qualitative feedback.
          allOf:
            - $ref: '#/components/schemas/controllers.Feedback'
        feedback_metadata:
          description: Required when entity is `AMBIENT_GENERATED_MEDICAL_FORM`.
          allOf:
            - $ref: '#/components/schemas/controllers.FormFillingFeedbackMetadata'
      example:
        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
    controllers.SubmitFeedbackResponse:
      description: >-
        Response body for
        /api/v1/form-filling/session/{ambient_session_id}/{entity}/feedback.
      type: object
      properties:
        feedback_id:
          description: feedback identifier
          type: string
    controllers.BadRequestError:
      type: object
      properties:
        code:
          type: integer
          example: 400
          description: HTTP status code for the error.
        message:
          type: string
          example: invalid request
          description: Human-readable description of the validation or request error.
      description: Error response when the request fails validation.
    controllers.AuthenticationError:
      type: object
      properties:
        code:
          type: integer
          example: 401
          description: HTTP status code for the error.
        message:
          type: string
          example: invalid token
          description: Human-readable description of the authentication failure.
      description: Error response when authentication fails.
    controllers.ForbiddenError:
      type: object
      properties:
        code:
          type: integer
          example: 403
          description: HTTP status code for the error.
        message:
          type: string
          example: forbidden
          description: Human-readable description of the authorization failure.
      description: Error response when the caller lacks permission.
    controllers.NotFoundError:
      type: object
      properties:
        code:
          type: integer
          example: 404
          description: HTTP status code for the error.
        message:
          type: string
          example: not found
          description: Human-readable description of the missing resource.
      description: Error response when the requested resource was not found.
    controllers.InternalServerError:
      type: object
      properties:
        code:
          type: integer
          example: 500
          description: HTTP status code for the error.
        message:
          type: string
          example: internal server error
          description: Human-readable description of the server error.
      description: Error response when the server encounters an unexpected error.
    controllers.Feedback:
      type: object
      properties:
        qualitative_comments:
          description: Freeform text comments.
          type: string
          maxLength: 2000
          example: Accurate and well-structured form output.
        ratingFeedback:
          description: >-
            Present for Likert or binary scales (`min_rating`, `max_rating`,
            `rating`).
          allOf:
            - $ref: '#/components/schemas/controllers.QuantitativeFeedback'
    controllers.FormFillingFeedbackMetadata:
      description: >-
        Metadata required for form-filling feedback when entity is
        `AMBIENT_GENERATED_MEDICAL_FORM` (identifies which medical form instance
        the feedback refers to).
      type: object
      required:
        - form_id
      properties:
        form_id:
          description: Medical form instance ID used to load full form details server-side.
          type: string
          example: 018f94e8-7aa8-7bfd-bc83-046262001234
    controllers.QuantitativeFeedback:
      description: Quantitative feedback for the session
      type: object
      properties:
        max_rating:
          type: integer
          description: >-
            Maximum rating value - you can choose any number that is greater
            than the minimum value
        min_rating:
          type: integer
          description: >-
            Minimum rating value - you can choose any number as the minimum i.e
            0 and above
        rating:
          type: integer
          description: The actual rating given within the min-max range
  securitySchemes:
    SukiTokenAuth:
      type: apiKey
      in: header
      name: sdp_suki_token
      description: >-
        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.

````