Partner & Iframe Embed¶
How a partner integrates vScrawl into their own product: register an app, obtain a token server-side, then either dispatch workflows from a template programmatically, or embed the actual vScrawl signing UI (the app's /client-embed route) in an iframe inside the partner's page. This is a real, shipped integration path.
Not a public embed snippet
Unlike a payment widget with a public key, this is a server-to-server credential-based integration. There is no anonymous/public template link anywhere in the platform — every embed must be backed by a registered Business App and a token minted by the partner's own backend.
Overview¶
sequenceDiagram
participant PartnerBE as Partner Backend
participant PartnerFE as Partner Frontend
participant API
participant Embed as vScrawl /client-embed (iframe)
Note over PartnerBE,API: One-time setup
PartnerBE->>API: POST /organization/v1/apps (register Business App)
API-->>PartnerBE: clientId + clientSecret (shown once)
Note over PartnerBE,API: Per-transaction
PartnerBE->>API: POST /auth/v1/signin (grant_type=CLIENT_CREDENTIALS)
API-->>PartnerBE: Client token
PartnerBE->>API: POST /workflow/v1/templates/{id}/dispatch (Bearer client token)
API-->>PartnerBE: { id: workflowId }
PartnerBE->>PartnerFE: Pass clientToken + workflowId to the page
PartnerFE->>Embed: <iframe src="/client-embed?clientToken=...&wId=...">
Embed->>API: GET /auth/v1/clientAppVerify/{workflowId} (Bearer clientToken)
API-->>Embed: { valid, fileName, documentStatus, callBackUrl }
Embed-->>Embed: Render signing UI
Note over Embed: Recipient signs inside the iframe
Embed->>PartnerFE: postMessage / navigation back to callBackUrl
1. One-time setup: register a Business App¶
See Organization → Business Apps for the full field reference. An org owner registers the integration once and gets a client secret back — shown once, store it securely.
2. Per-transaction: obtain a client token¶
POST /auth/v1/signin
Content-Type: application/json
{
"grant_type": "CLIENT_CREDENTIALS",
"client_id": "acme-crm",
"client_secret": "sk_live_9f8e7d6c5b4a...",
"email": "owner@acmeorg.com"
}
email selects which org member's context the token acts within. Full detail: Authentication → Client-credentials.
Never call this from the browser — client_secret must stay server-side.
3. Dispatch a workflow from a template¶
POST /workflow/v1/templates/{templateId}/dispatch
Authorization: Bearer <client token>
Content-Type: application/json
[
{ "recipientIndex": 1, "name": "Jane Doe", "emailAddress": "jane@example.com" }
]
Full field/error reference: Templates → Using a template. Response: { "id": 887 } — this is the workflowId you'll pass into the iframe next. Use .../apply instead of .../dispatch to leave it as a draft for manual review before sending.
The resulting workflow is automatically tagged with your Business App's client ID, so configured completion/decline webhooks route back to your integration.
4. Embed the signing UI¶
<iframe
src="https://app.vscrawl.com/client-embed?clientToken=eyJhbGciOiJSUzI1NiIs...&wId=887"
style="width:100%; height:800px; border:none;">
</iframe>
On load, the embedded page verifies access:
{
"valid": true,
"fileName": "NDA-Acme-2026.pdf",
"selfSign": false,
"documentStatus": "SENT",
"callBackUrl": "https://acme.example.com/vscrawl/callback"
}
This checks that the token's Business App is entitled to this workflow, and that the acting user is either the workflow's owner or one of its recipients. On success, the page renders the normal signing UI — from here on, the recipient experience is identical to Sending & Signing, just inside an iframe.
Failure — token doesn't own the workflow, or the identified user isn't a participant: the embed shows an access-denied state instead of the document.
5. Returning control to the host page¶
When the recipient finishes (or cancels):
- Same-origin embed: navigates
window.parent.locationdirectly tocallBackUrl, withdocIdandstatus(SUCCESS/DECLINED) appended. - Cross-origin embed: falls back to
window.parent.postMessage({ type: "vscrawl:iframe-exit", url: "<callBackUrl-with-status>" }, "*")— your host page should listen for this and navigate itself:
window.addEventListener("message", (event) => {
if (event.data?.type === "vscrawl:iframe-exit") {
window.location.href = event.data.url;
}
});
- As a last resort, a
target="_top"link click is also attempted.
Why the fallback exists
Some partner sites restrict framing in a way that blocks direct cross-origin parent navigation from within the iframe — the postMessage path keeps the handoff working in those cases. If your page embeds vScrawl and doesn't see navigation happen automatically, add the listener above.
Webhooks (server-side alternative/complement to the iframe callback)¶
If you configured a webhook URL/events when registering the Business App, workflow lifecycle events (signed, declined, completed) for workflows tagged with your client ID are also delivered server-side — useful for a reliable completion signal independent of whether the browser successfully returns to your callback URL.