Embeddable signing request editor
Embed Firma’s signing request editor inside your application using JWT authentication for secure, time-limited access. This is ideal for white-label integrations and multi-tenant applications.Use cases
- White-label signing workflows: Manage signing requests under your brand
- Multi-tenant applications: Secure per-signer access without exposing API keys
- Embedded document workflows: Seamless signing request management within your product
- Time-limited access: Tokens expire automatically for security (7-day expiration)
How it works
- Your server requests a JWT token from Firma’s API using your API key
- Firma returns a short-lived JWT token with the signing request ID
- Your frontend embeds the editor with the JWT token
- The token expires automatically after 7 days
Rate limit: JWT endpoints support 100 requests per minute per API key for high-volume applications.
JWT Authentication
Generate JWT token
Generate a JWT token for a specific signing request using the/jwt/generate-signing-request endpoint.
Endpoint: POST /jwt/generate-signing-request
Request body:
Implementation guide
Backend: Generate JWT token
Call the Firma API from your backend to generate a JWT token. Your backend endpoint should accept a signing request ID and return the JWT to your frontend. Node.js example:Frontend implementation — HTML / Vanilla JavaScript
Frontend implementation — React
Configuration Options
| Option | Type | Description |
|---|---|---|
container | HTMLElement | DOM element to mount the editor (required) |
jwt | string | Authentication token from your backend (required) |
signingRequestId | string | Signing request identifier (required) |
theme | 'dark' | 'light' | Editor theme (default: 'dark') |
readOnly | boolean | Enable read-only mode (default: false) |
height | string | Container height (default: '100vh') |
width | string | Container width (default: '100%') |
onSave | function | Callback when signing request is saved |
onSend | function | Callback when signing request is sent |
onError | function | Callback for error handling |
onLoad | function | Callback when editor loads with signing request data |
postMessage events (editor → host)
Firma’s signing request editor will emit postMessage events for important lifecycle actions. Below is a recommended, minimal event schema you can implement for reacting to editor saves and sends. Event envelope (window.postMessage payload):Client listener example (plain JS)
Token lifecycle management
JWT tokens are generated with a 7-day expiration time for typical editing workflows. The editor will automatically handle token expiration.Automatic expiration
JWT tokens expire automatically after 7 days based on theexpires_at timestamp. After expiration:
- The embedded editor will reject the token
- A new token must be requested to continue
- No API call needed — tokens expire passively
Token refresh (optional)
For long-running editing sessions, you can refresh the token before expiration using theupdateJWT() method:
Rate limiting
JWT endpoints support 100 requests per minute per API key. Rate limit headers:- Cache tokens and reuse them until expiration (7 days)
- Implement exponential backoff for retries
- Monitor
X-RateLimit-Remainingheader - Generate tokens on-demand, not preemptively
Security best practices
✅ Do’s
- ✅ Generate tokens from your backend server
- ✅ Monitor rate limits (100 requests/minute)
- ✅ Use HTTPS for all API requests
- ✅ Use
readOnly: truefor view-only access
❌ Don’ts
- ❌ Don’t expose API keys in frontend code
- ❌ Don’t reuse tokens across sessions or signers
- ❌ Don’t log JWT tokens (security risk)
- ❌ Don’t share tokens between different signing requests
Troubleshooting
Token expired error
Symptom: Editor shows “Token expired” or authentication error Solution:- Implement token refresh before expiration (7-day window)
- Generate a new token and call
editor.updateJWT(newToken) - Check system clock synchronization
401 Unauthorized
Symptom: JWT generation fails with 401 Possible causes:- Invalid or missing API key
- API key doesn’t have required permissions
- API key is disabled
404 Not Found
Symptom: Signing request not found when generating JWT Possible causes:- Signing request ID doesn’t exist
- Signing request belongs to different workspace
- Signing request was deleted
Rate limit exceeded
Symptom: 429 Too Many Requests Solution:- Implement token caching (7-day expiration window is generous)
- Wait for rate limit reset (check
X-RateLimit-Resetheader) - Implement retry logic with exponential backoff
Editor not loading
Symptom: Container is empty or shows loading spinner indefinitely Possible causes:- Script not loaded (check
script.onloadevent) - Invalid JWT or signing request ID
- CORS issues (check browser console)
- Verify script is loaded from
https://app.firma.dev/embed/signing-request-editor.js - Check JWT is valid and not expired
- Ensure backend returns correct CORS headers
Next steps
- Embed template editor for white-label template creation (120 req/min)
- Send signing requests programmatically (100 req/min)
- Set up webhooks to track signing request events (60 req/min)
- Configure workspace settings for multi-tenant apps (100-200 req/min)