Skip to main content

Approvals

Flow supports optional human review before delivery. When a gate is configured with approvalMode: "manual", validated runs are held for approver decision before proceeding.

Approval Modes

ModeBehavior
auto (default)Runs proceed directly after validation — no human review
manualRuns wait at pending_approval status until an approver approves or rejects

Configuring Approvers

Set up approval when creating or updating a gate:

{
"approvalMode": "manual",
"approvalConfig": {
"approvers": [
{ "type": "internal", "email": "manager@company.com" },
{ "type": "external", "email": "auditor@partner.com" }
],
"timeout_hours": 48
}
}

Approver Types

TypeDescription
internalA user with a Rynko account on your team — reviews via the dashboard
externalAny email address — reviews via a magic link sent by email

Decision Logic

Flow uses any-approves logic:

  • The first approval moves the run to approved and triggers delivery immediately
  • The first rejection moves the run to rejected (terminal) — no delivery

Once a decision is made, other approvers cannot override it.


Internal Approvers

Internal approvers review runs directly in the Rynko dashboard.

Dashboard Inbox

curl https://api.rynko.dev/api/flow/approvals \
-H "Authorization: Bearer YOUR_API_KEY"

Returns all pending approvals assigned to the authenticated user.

Making a Decision

# Approve
curl -X POST https://api.rynko.dev/api/flow/approvals/APPROVAL_ID/approve \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "comment": "Looks good, approved." }'

# Reject
curl -X POST https://api.rynko.dev/api/flow/approvals/APPROVAL_ID/reject \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "comment": "Amount exceeds policy limit." }'

The comment field is optional (max 1000 characters).


External approvers receive an email with a magic link that takes them to a review portal — no Rynko account required.

How It Works

  1. A run reaches pending_approval status
  2. Flow sends an email to each external approver with a unique magic link
  3. The approver clicks the link and enters their email as identity verification
  4. They receive a short-lived review token (valid for 2 hours)
  5. They can view the run details and approve or reject

Review Portal Endpoints

These endpoints are public (no API key required) — they use the magic link token for authentication.

Authenticate

curl -X POST https://api.rynko.dev/api/flow/review/authenticate \
-H "Content-Type: application/json" \
-d '{
"token": "MAGIC_LINK_TOKEN",
"email": "auditor@partner.com"
}'

Response:

{
"reviewToken": "eyJ...",
"expiresIn": 7200
}

The email must match the token's intended recipient (identity challenge).

View Inbox

curl https://api.rynko.dev/api/flow/review/inbox \
-H "Authorization: Bearer REVIEW_TOKEN"

View Approval Details

curl https://api.rynko.dev/api/flow/review/approvals/APPROVAL_ID \
-H "Authorization: Bearer REVIEW_TOKEN"

Returns the approval record with full run context (payload, validation results, gate info).

Approve or Reject

# Approve
curl -X POST https://api.rynko.dev/api/flow/review/approvals/APPROVAL_ID/approve \
-H "Authorization: Bearer REVIEW_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "comment": "Approved after review." }'

# Reject
curl -X POST https://api.rynko.dev/api/flow/review/approvals/APPROVAL_ID/reject \
-H "Authorization: Bearer REVIEW_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "comment": "Data does not match requirements." }'

If the approver didn't receive the email or the link expired:

curl -X POST https://api.rynko.dev/api/flow/review/resend \
-H "Content-Type: application/json" \
-d '{
"token": "ORIGINAL_MAGIC_LINK_TOKEN",
"email": "auditor@partner.com"
}'

Timeout

If no approver makes a decision within the configured timeout_hours, the approval expires. Configure the timeout (1-720 hours) in the gate's approvalConfig.


Approval Limits by Plan

PlanMax Approvers per Gate
Free5
Starter10
Growth25
ScaleUnlimited