Embed
Embed a SpreadSpace surface directly in your own application. Your users work with the spreading workspace or the document review panel without leaving your product, and without your page ever holding a SpreadSpace token.
Two packages cover the integration:
How it fits together
- Your backend uses
@spreadspace/embed(or a direct API call) with an API key that holds theembed:writescope to mint a single-use handle or a loan-scoped session. - Your app renders
<SpreadSpaceEmbed />from@spreadspace/reactand gives it agetHandlecallback that fetches that handle from your backend. - The SDK loads the returned
signed_urlinto an iframe served from SpreadSpace’s origin. Inside the iframe, the handle is exchanged for a short-lived, loan-bound embed token that stays in the iframe and never reaches your page.
Install
The security model
Your page never holds a SpreadSpace token. The token is minted server-side,
exchanged inside a same-origin iframe, and kept there. A handle is single-use,
expires in seconds, and is worthless off SpreadSpace’s origin. The browser-facing
token is read-only by default and locked to a single loan. The only grantable
writes are the explicit per-mint upload, review and spread scopes
(documents:write, extractions:write, spreads:write), which stay bound to
that same loan. A leaked token
therefore cannot reach other loans or mint further tokens. The embed:write scope, held
only by your server-side API key, is the control point: revoking it immediately severs every
issued token and in-flight handle.
Persistent user state
Pass an optional external_user_id (your app’s opaque identifier for the
viewing user, up to 256 characters) when minting a session or iframe handle.
Sessions minted with the same id share server-kept state for that user: board
arrangements, view preferences, and saved memo templates survive across that
user’s sessions and devices. Omit it and each session starts from defaults.
The mint response says which mode you got. persistence is user when an
external_user_id was supplied and session when it was not, and session
means nothing the viewer arranges is ever saved.
The id also comes back to you: when that user finalizes a spread, the
attribute snapshot carries it as
finalized_by_external_user_id, so your backend can say who finalized from
its own user table. SpreadSpace never has to hand a person’s name to your
service key.
You can also pass an optional display_name (up to 120 characters) beside
the id. Reserved. Stored with the id, not shown anywhere yet. It requires
external_user_id in the same request.
How the numbers reach your backend
The analyst finishes the spread inside the embed and finalizes it there. Your
backend receives a spread.finalized webhook naming the loan
and the snapshot it just created, then reads the frozen figures by id with
GET /api/loans/{loanId}/attributes/{snapshotId} (the same
attribute snapshot the workspace produces) straight into your
own fields. Nobody re-keys anything, and the numbers your system stores are the
ones the analyst approved. If the analyst later reopens the spread to revise
it, spread.reopened names that same snapshot so you can mark your copy stale
until the next finalize arrives.
A session whose user is expected to finalize must be minted with
spreads:write (or the wider extractions:write). The SDK’s
webhook receiver reads the
snapshot the event names for you on spread.finalized, so the handler you
write is the half that stores it.
Quickstarts
- React embed SDK: render
<SpreadSpaceEmbed />with agetHandlecallback. - Node embed SDK: mint an embed session or iframe handle server-side.