Elements embed
Compose signing UI into your React product with typed primitives — Provider + status + signer + signature-capture components you render inside your own page shell.
Integrate Elements in four steps
- 1
Install the package
Add @endorsed/elements to your React 18+ project. Peer deps are React and React DOM only — no vendor SDK sprawl.
- 2
Mint a signing-session token server-side
From your backend, POST /api/signing-sessions with the envelope id + signer email. The response contains a short-lived signing-session token scoped to that signer.
- 3
Wrap your signing route in <EndorsedProvider>
The provider carries your API config into the primitives — no prop drilling. Redeem the session token with useSigningSession() and render <EnvelopeStatus>, <SignerInfo>, and <SignatureField> inside your own layout.
- 4
Handle signature submit + status callbacks
useSignatureSubmit() posts the captured signature to /api/signing-sessions/:id/signature. Listen for status transitions and route the signer to your own success/decline pages when SigningSessionStatus flips.
Minimal embed example
A composable signing surface using the shipped primitives. Prerequisites: React 18+ and a signing-session token minted server-side. Expected output: a signer sees their envelope status, their identity, and a signature pad — all inside your product chrome.
import {
EndorsedProvider,
EnvelopeStatus,
SignerInfo,
SignatureField,
useSigningSession,
} from '@endorsed/elements';
// 1. Wrap once at the app root (or per-signing-route).
export function App({ children }: { children: React.ReactNode }) {
return (
<EndorsedProvider
baseUrl={process.env.NEXT_PUBLIC_ENDORSED_BASE_URL}
// No API key in the browser. The provider only holds config.
>
{children}
</EndorsedProvider>
);
}
// 2. Render the signing surface. Compose these primitives into your
// own page shell — headers, footers, and layout stay yours.
export function SigningPage({ sessionToken }: { sessionToken: string }) {
const { status, envelope, signer } = useSigningSession(sessionToken);
if (status === 'loading') return <p>Loading signing session…</p>;
if (status === 'expired' || status === 'revoked') return <p>This link has expired.</p>;
return (
<section>
<EnvelopeStatus value={envelope.status} />
<SignerInfo values={{ name: signer.name, email: signer.email }} />
<SignatureField
onSubmitted={(result) => {
// Advance your product state — redirect, mark task done, etc.
console.log('Signature captured', result.signatureId);
}}
/>
</section>
);
}Elements ships composable primitives (Provider, status/signer display, signature capture). Compose the primitives above or embed the hosted signer via the signing-session URL.
What embed handles for you
Document rendering
PDF rendering, zoom, scroll, and page navigation — cross-browser, including mobile Safari.
Signature capture
Draw, type, or upload signature. Consistent capture experience across devices without browser quirks.
Identity verification
OTP check is handled inside the embed. No separate authentication UI required in your product.
Field navigation
Guided field-by-field navigation with required-field enforcement before submission is allowed.
Common questions
Elements embed — inside your product
The signing surface renders inline on your domain with your brand. Your product frame, your header, your navigation — EndorsedSign handles the document and field interaction.

Try Elements in your own sandbox tenant
Claim a sandbox via the quickstart, mint a signing-session token from your backend, and drop the primitives above into any React 18+ app.