> ## 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 Webhook Handler

> Build a server-side Webhook handler that verifies Form filling notifications, fetches structured data, and saves results to your EHR

This example shows how to build a server-side webhook handler for Form filling results. `onSubmit` runs in the browser when structured data is ready, but it may not run if the clinician closes the tab before processing finishes.

The example receives a [Partner notification webhook](/documentation/webhook/overview) after Suki completes backend processing, verifies the request, and fetches structured data to save to your EHR. Webhook `session_id` maps to `ambient_session_id` in the SDK. Webhook `encounter_id` maps to `correlation_id` when you pass your encounter UUID at session start.

```javascript JavaScript theme={"theme":{"light":"github-dark","dark":"material-theme-darker"}}
import express from "express";

const app = express();
app.use(express.json());

app.post("/webhooks/suki", async (req, res) => {
  // 1. Verify signature (required in production)
  // verifySukiSignature(req.headers, req.body);

  const { status, session_id: sessionId, encounter_id: encounterId } = req.body;

  if (!sessionId) {
    res.status(400).json({ error: "Missing session_id" });
    return;
  }

  if (status === "success") {
    const { structured_data: structured } = await fetchFormFillingStructuredData(sessionId);

    await saveFormsToEhr({
      encounterId,
      sessionId,
      forms: structured.generated_values,
    });
  }

  if (status === "failure") {
    console.error("Form filling session failed", req.body.error_code, req.body.error_detail);
  }

  res.status(200).json({ received: true });
});

async function fetchFormFillingStructuredData(ambientSessionId) {
  const res = await fetch(
    `https://sdp.suki-stage.com/api/v1/form-filling/session/${ambientSessionId}/structured-data`,
    {
      headers: {
        sdp_suki_token: process.env.SUKI_SERVICE_TOKEN,
        sdp_provider_id: process.env.SUKI_PROVIDER_ID,
      },
    }
  );
  if (!res.ok) throw new Error(`structured-data fetch failed: ${res.status}`);
  return res.json();
}
```

<Note>
  Verify every request with [Signature verification](/documentation/webhook/signature-verification). Use `session_id` as an idempotency key. Refer to [Get Form filling structured data](/form-filling-api-reference/form-filling-sessions/structured-data) for production URLs and auth headers.
</Note>

## Available cookbooks

<div className="hp-io-method-grid tut-hub-card-grid" data-cookbook-related-grid>
  <a className="hp-io-method-card tut-hub-method-card" href="/documentation/cookbooks/verify-webhook-hmac-signature">
    <div className="tut-hub-card-media tut-hub-card-media--blue" aria-hidden="true" />

    <div className="hp-io-method-card-body">
      <div className="tut-hub-card-badges">
        <span className="hp-wn-badge hp-wn-badge-new">Webhooks</span>
        <span className="hp-wn-badge cookbook-hub-badge-surface cookbook-hub-badge-surface--api">API</span>
      </div>

      <h3 className="hp-io-method-card-title">Verify Webhook HMAC Signature</h3>

      <p className="hp-io-method-card-desc cookbook-hub-card-desc">
        Verify HMAC before parsing JSON.
      </p>

      <div className="hp-io-method-card-meta tut-hub-card-foot" aria-label="5 min">
        <div className="tut-hub-card-foot-meta">
          <span className="hp-io-method-card-meta-time">5 min</span>
        </div>
      </div>
    </div>
  </a>
</div>

## Available tutorials

<div className="hp-io-method-grid tut-hub-card-grid">
  <a className="hp-io-method-card tut-hub-method-card" href="/documentation/tutorials/webhook-notification-receiver">
    <div className="tut-hub-card-media" aria-hidden="true" />

    <div className="hp-io-method-card-body">
      <span className="hp-wn-badge hp-wn-badge-new">Webhooks</span>
      <h3 className="hp-io-method-card-title">Build a Webhook Notification Receiver</h3>

      <p className="hp-io-method-card-desc">
        Verify HMAC signatures, parse partner notifications, and handle success and failure events.
      </p>

      <div className="hp-io-method-card-meta tut-hub-card-foot" aria-label="10 min, Beginner">
        <div className="tut-hub-card-foot-meta">
          <span className="hp-io-method-card-meta-time">10 min</span>
          <span className="tut-hub-level">Beginner</span>
        </div>
      </div>
    </div>
  </a>
</div>

## Next steps

<Icon icon="file-lines" iconType="solid" /> Refer to [EHR handoff](/form-filling-sdk/examples/ehr-handoff) to map `structured_data` to your EHR fields

<Icon icon="file-lines" iconType="solid" /> Refer to [Session workflow](/form-filling-sdk/guides/integration-patterns#get-structured-data) for browser vs server delivery

<Icon icon="file-lines" iconType="solid" /> Refer to [Webhook quickstart](/documentation/webhook/quickstart) for endpoint setup and testing
