Embeddable Approval Widget
Embed a fully functional draft review and approval interface directly into your application using an iframe or the widget API.
Overview
The processa embeddable widget lets your team review and approve AI-generated drafts without leaving your application. The widget is a self-contained UI that communicates with the processa API using a publishable key (prefixed with pk_).
Key capabilities:
- Display draft title, content preview, and current status
- Approve or reject drafts with optional reviewer name and rejection reason
- Real-time status polling with ETag-based caching
- Light and dark theme support
- Fully responsive and self-contained
Quick Start
1. Generate a Publishable Key
Navigate to Dashboard → API Keys and generate a new publishable key. Publishable keys are prefixed with pk_ and are safe to use in client-side code. They can only access the embed endpoints.
2. Configure Allowed Origins
For security, add your application's domain to the allowed origins list in Dashboard → Settings. This ensures the widget can only be embedded on authorized domains.
3. Embed the Widget
Add the iframe embed code to your application, replacing the draft ID and publishable key with your own values:
<iframe src="https://app.getprocessa.com/embed/drafts/DRAFT_ID?key=pk_YOUR_KEY&theme=light" width="100%" height="400" frameborder="0" style="border: none; border-radius: 12px;" ></iframe>
iframe Embed
The simplest way to embed the widget is using an iframe. The widget URL follows this pattern:
https://app.getprocessa.com/embed/drafts/{draftId}?key={publishableKey}&theme={light|dark}Query Parameters
keythemelight or dark. Defaults to light.React Example
function ApprovalEmbed({ draftId }: { draftId: string }) {
const publishableKey = process.env.NEXT_PUBLIC_PROCESSA_PK
return (
<iframe
src={`https://app.getprocessa.com/embed/drafts/${draftId}?key=${publishableKey}&theme=dark`}
width="100%"
height="400"
style={{ border: 'none', borderRadius: '12px' }}
title="Draft Approval"
/>
)
}HTML Example
<!-- Embed in any HTML page -->
<div style="max-width: 500px; margin: 0 auto;">
<iframe
id="getprocessa-widget"
src="https://app.getprocessa.com/embed/drafts/YOUR_DRAFT_ID?key=pk_YOUR_KEY&theme=light"
width="100%"
height="400"
frameborder="0"
style="border: none; border-radius: 12px; box-shadow: 0 1px 3px rgba(0,0,0,0.1);"
></iframe>
</div>Embed API Endpoints
If you prefer to build your own UI, you can use the embed API endpoints directly. All endpoints require a publishable key in the Authorization header.
/api/v1/embed/drafts/:idFetch a single draft by ID. Returns the draft title, content, status, and timestamps.
Request
GET /api/v1/embed/drafts/cmlgx2hvq0002k6gve9fuaz0k Authorization: Bearer pk_your_publishable_key
Response
{
"id": "cmlgx2hvq0002k6gve9fuaz0k",
"title": "Send welcome email",
"content": { "to": "user@example.com", "subject": "Welcome!" },
"status": "PENDING",
"metadata": {},
"createdAt": "2026-02-10T12:00:00Z",
"updatedAt": "2026-02-10T12:00:00Z",
"expiresAt": null
}/api/v1/embed/drafts/:id/approveApprove a pending draft. Optionally include a reviewer name.
Request Body
{
"reviewerName": "Alice Smith" // optional
}Response
{
"id": "cmlgx2hvq0002k6gve9fuaz0k",
"status": "APPROVED",
"reviewedAt": "2026-02-10T12:05:00Z"
}/api/v1/embed/drafts/:id/rejectReject a pending draft. Optionally include a rejection reason and reviewer name.
Request Body
{
"rejectionReason": "Content needs revision", // optional
"reviewerName": "Bob Jones" // optional
}Response
{
"id": "cmlgx2hvq0002k6gve9fuaz0k",
"status": "REJECTED",
"rejectionReason": "Content needs revision",
"reviewedAt": "2026-02-10T12:05:00Z"
}/api/v1/embed/drafts/:id/statusPoll the current status of a draft. Supports ETag-based conditional requests for efficient polling. Returns 304 Not Modified if the status has not changed.
Request
GET /api/v1/embed/drafts/cmlgx2hvq0002k6gve9fuaz0k/status Authorization: Bearer pk_your_publishable_key If-None-Match: "etag_value_from_previous_response"
Response
{
"status": "PENDING",
"reviewedAt": null,
"rejectionReason": null
}Security
Publishable Keys
Publishable keys (pk_) are designed to be used in client-side code. They have restricted permissions and can only access the embed API endpoints. They cannot create drafts, manage webhooks, or access other API resources.
Important: Never expose your secret API key (hal_) in client-side code. Always use publishable keys for the embed widget.
CORS & Origin Allowlist
Embed API endpoints enforce CORS restrictions. Only requests from domains listed in your allowed origins configuration will be accepted. Configure allowed origins in your account settings.
iframe Sandboxing
The embed page runs in a minimal layout with no navigation or session context. It only communicates via the embed API endpoints using the publishable key provided in the URL query parameter. No cookies or session tokens are used.
Theming
The widget supports light and dark themes. Pass the theme query parameter to match your application's appearance.
Light Theme
?theme=light
Dark Theme
?theme=dark
<!-- Light theme (default) --> <iframe src="https://app.getprocessa.com/embed/drafts/ID?key=pk_KEY&theme=light" ...></iframe> <!-- Dark theme --> <iframe src="https://app.getprocessa.com/embed/drafts/ID?key=pk_KEY&theme=dark" ...></iframe>