01
Fastest launchHosted by Savart
Send a client from your CRM or adviser workflow into the branded, accessible assessment.
// Server only: select the frozen arm, then upsert and enroll.
const programId = mode === "full"
? process.env.SYNAPSE_SAVART_FULL_PROGRAM_ID!
: process.env.SYNAPSE_SAVART_ADAPTIVE_PROGRAM_ID!;
const subject = await synapse.subjects.upsert(orgId, appId, envId,
{ externalId: crmClientId }, { idempotencyKey: subjectKey });
await synapse.programs.enroll(orgId, appId, envId,
{ subjectId: subject.subject.id, programId });
const session = await synapse.participantSessions.create(
orgId, appId, envId,
{ subjectId: subject.subject.id, programId },
{ idempotencyKey: sessionKey },
);
cookies().set("savart_participant", session.participant_token, {
httpOnly: true, secure: true, sameSite: "strict", path: "/",
});
redirect("https://efg.savart.in/assessment");
02
Native journeyEmbedded experience
Use the compile-tested React artifact with an authenticated BFF-issued, short-lived participant token. No app or environment key enters browser code.
"use client";
import { useEffect, useState } from "react";
import {
EmbeddedAssessmentExample,
createSavartEmbeddedController,
} from "./embedded-assessment-example";
export function HostAssessment() {
const [controller, setController] = useState(null);
useEffect(() => {
// An authenticated same-origin BFF returns only a short-lived spt_ token
// and opaque session ID. App/environment credentials remain server-side.
fetch("/api/synapse-participant-token", {
method: "POST", credentials: "same-origin",
}).then((response) => response.json()).then((launch) => {
setController(createSavartEmbeddedController({
baseUrl: "https://api.synapse.example",
participantToken: launch.participantToken,
opaqueSessionId: launch.sessionId, // never use the token as a queue key
}));
});
}, []);
return controller
? <EmbeddedAssessmentExample controller={controller} />
: <p>Starting secure assessment…</p>;
}
03
Full controlServer API + SDK
Sync managed users and enroll them in the correct published pilot program from your backend.
import { createSynapseClient } from "@apart-ai/synapse";
const synapse = createSynapseClient({
baseUrl: process.env.SYNAPSE_API_URL!,
apiKey: process.env.SYNAPSE_ENVIRONMENT_KEY!, // server only
});
const synced = await synapse.subjects.upsert(
process.env.SYNAPSE_ORGANIZATION_ID!,
process.env.SYNAPSE_APP_ID!,
process.env.SYNAPSE_ENVIRONMENT_ID!,
{ externalId: crmClientId },
{ idempotencyKey: requestId },
);
04
Reliable eventsSigned webhooks
Verify the raw payload before parsing, then deduplicate every at-least-once delivery by event ID.
import { verifyWebhookSignature } from "@apart-ai/synapse/webhooks";
export async function POST(request: Request) {
const payload = await request.text(); // verify before JSON parsing
await verifyWebhookSignature(
payload,
request.headers.get("x-synapse-signature") ?? "",
[process.env.SYNAPSE_WEBHOOK_SECRET!,
process.env.SYNAPSE_WEBHOOK_PREVIOUS_SECRET!],
);
const event = JSON.parse(payload);
await processEventOnce(event.id, event); // deliveries are at least once
return new Response(null, { status: 204 });
}