Embedded signing
Let people sign inside your own app or on your device: create a one-off signing URL for the recipient whose turn it is.
When to use it
- In your app: the person is already logged in to your product, and you want them to sign right there instead of waiting for an email.
- In person: a customer signs on a tablet at your desk or counter. Add them with the role
in_person_signer— they get no emails, so a signing URL is the only way in.
The flow
- Create and send the envelope as usual, with the recipient on it.
- When it’s their turn, your server asks Signkoi for a signing URL.
- You open that URL for the person; they sign on Signkoi’s signing page.
- A webhook (or a status check) tells your server they finished.
Create a signing URL
Call POST/v1/envelopes/{id}/recipients/{rid}/signing-url from your server, right before you need it.
curl -X POST https://signkoi.com/api/v1/envelopes/9b2f4c1e-7a3d-4e8b-9c51-2d6f8a0b3e47/recipients/c4e1a8f2-3b7d-4f19-a6c2-8e5d0b9f1a73/signing-url \
-H "Authorization: Bearer $SIGNKOI_API_KEY"{
"object": "signing_url",
"url": "https://signkoi.com/s/8kQ2…",
"recipient_id": "c4e1a8f2-3b7d-4f19-a6c2-8e5d0b9f1a73"
}Open the signing page
Redirect the browser to the URL, open it in a new tab, or load it in an in-app browser or web view on mobile. The signing page runs on signkoi.com and works on any screen size.
// Your server: an authenticated route in your app, e.g. POST /contracts/:id/sign
app.post('/contracts/:id/sign', requireLogin, async (req, res) => {
const contract = await db.contracts.find(req.params.id, { owner: req.user.id });
const r = await fetch(
`https://signkoi.com/api/v1/envelopes/${contract.envelopeId}/recipients/${contract.recipientId}/signing-url`,
{ method: 'POST', headers: { Authorization: `Bearer ${process.env.SIGNKOI_API_KEY}` } },
);
const body = await r.json();
if (!r.ok) return res.status(409).json({ code: body.error.code });
// Send the browser straight to the signing page; never store or log the URL.
res.redirect(303, body.url);
});No iframes
For security, the signing page can’t be shown inside an iframe on another site (it sends X-Frame-Options: SAMEORIGIN). Use a redirect, a new tab or a web view.
After signing
The recipient sees Signkoi’s confirmation page. Subscribe to recipient.completed and envelope.completed webhooks to update your app, or check the recipient’s status with GET/v1/envelopes/{id}. When the next recipient is also in front of you (for example two in-person signers), request a new URL for them once the first has finished.
Security
- Anyone with the URL can sign as that recipient. Create it only for an authenticated user who is that recipient.
- Request a fresh URL every time; don’t store, log, email or share it.
- Every signing URL you create is recorded in the envelope’s audit trail.
- Verification still applies: a recipient with an access code or SMS/email code must enter it on the signing page.