EdgeInteract
Approval
The approval interaction type requests a human decision on a specific item or action. It presents context and structured fields to the approver, who can approve, reject, or abstain. An optional comment field is always available.
When to Use
- Invoice or purchase order approvals
- Workflow step authorization (e.g., "proceed to production deployment?")
- Content moderation review
- AI-generated output review requiring human sign-off
- Multi-level approval chains (send one approval, wait for response, then send the next)
Live Mockup
Approve Invoice INV-2026-0042
Invoice from Acme Supplies Ltd for $14,200 is awaiting your approval before payment is processed.
VendorAcme Supplies Ltd
Amount$14,200.00
Due Date2026-06-15
PO ReferencePO-2026-0099
Request Payload Schema
interface ApprovalPayload {
/** Human-readable explanation of what is being approved */
context: string;
/** Structured key-value fields presented in the approval UI */
fields?: ApprovalField[];
}
interface ApprovalField {
key: string; // internal key
label: string; // display label
value: string; // display value
}
Full Request Example
await sendInteraction({
type: 'approval',
targetUserId: 'usr_mgr_jane',
title: 'Approve Invoice INV-2026-0042',
payload: {
context: 'Invoice from Acme Supplies Ltd for $14,200 requires your approval before payment is processed.',
fields: [
{ key: 'vendor', label: 'Vendor', value: 'Acme Supplies Ltd' },
{ key: 'amount', label: 'Amount', value: '$14,200.00' },
{ key: 'due', label: 'Due Date', value: '2026-06-15' },
{ key: 'po', label: 'PO Reference', value: 'PO-2026-0099' }
]
},
timeoutMs: 86_400_000, // 24 hours
priority: 'high'
});
Response Schema
interface ApprovalResponse {
interactionId: string;
respondedBy: string;
outcome: 'approved' | 'rejected' | 'abstained';
data: {
comment?: string; // optional comment from the approver
};
timestamp: string; // ISO 8601
}
Response Example
{
"interactionId": "int_01HXY4Z8KQ2W3V9G",
"respondedBy": "usr_mgr_jane",
"outcome": "approved",
"data": {
"comment": "Vendor terms checked — proceed with payment."
},
"timestamp": "2026-05-25T10:37:51Z"
}
Handling the Response
const response = await sendInteraction({ type: 'approval', ... });
switch (response.outcome) {
case 'approved':
await processPayment(invoice.id);
notifyRequester('Your invoice has been approved by ' + response.respondedBy);
break;
case 'rejected':
notifyRequester('Invoice rejected. Comment: ' + (response.data?.comment ?? 'none'));
break;
case 'abstained':
// Re-route to next approver or escalate
await escalateApproval(invoice.id, response.data?.comment);
break;
}
Validation Rules
| Field | Rule |
|---|---|
payload.context | Required, max 1000 characters |
payload.fields | Optional, max 20 items per array |
response.outcome | Must be one of: approved, rejected, abstained |
response.data.comment | Optional, max 2000 characters |
Abstain vs. Reject
Abstain means the approver declines to make a decision (not the same as rejecting). Use it when you want to support escalation paths — an abstain can trigger re-routing to another approver, while a rejection is a definitive no.