Flow API
Complete API reference for Rynko Flow. All endpoints are under the /api/flow/ prefix.
Authentication
All endpoints (except the Review portal) require an API key:
Authorization: Bearer YOUR_API_KEY
API keys are scoped to a workspace. All operations return data for the workspace associated with the key.
Gates
Create Gate
POST /api/flow/gates
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Gate name (max 255 chars) |
description | string | No | Description (max 1000 chars) |
validationMode | string | No | variables (default) or freetext |
schema | object | No | ObjectSchema format (see Gates > Schema) |
freetextConfig | object | No | Required when validationMode is freetext |
businessRules | array | No | Business rule definitions (max 20) |
renderMode | string | No | none (default), rynko, or custom_api |
renderTemplateId | string | No | Template ID for rynko render mode |
renderConfig | object | No | Render configuration (e.g., { "format": "pdf" }) |
approvalMode | string | No | auto (default) or manual |
approvalConfig | object | No | Approvers and timeout (required when manual) |
deliveryChannels | array | No | Webhook delivery targets |
maxSubmissionsPerMinute | integer | No | Rate limit (1-1000) |
notificationMode | string | No | immediate or digest (default) |
notificationDigestMinutes | integer | No | Digest interval in minutes (1-60, default 5) |
circuitBreakerEnabled | boolean | No | Enable circuit breaker (default true) |
maxFailures | integer | No | Failures before circuit opens (default 5) |
cooldownSeconds | integer | No | Circuit open duration in seconds (min 60, default 300) |
Example:
curl -X POST https://api.rynko.dev/api/flow/gates \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Order Validation",
"schema": {
"type": "object",
"properties": {
"orderId": { "type": "string", "required": true },
"amount": { "type": "number", "required": true, "min": 0 }
}
}
}'
Response (201):
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"shortId": "fgate_a1b2c3d4",
"slug": "order-validation",
"name": "Order Validation",
"status": "active",
"validationMode": "variables",
"schema": { ... },
"schemaVersion": 1,
"createdAt": "2026-03-04T10:00:00Z"
}
List Gates
GET /api/flow/gates
| Parameter | Type | Default | Description |
|---|---|---|---|
page | integer | 1 | Page number |
limit | integer | 25 | Results per page (1-100) |
search | string | — | Search by name |
status | string | — | active, paused, or archived |
sortBy | string | createdAt | createdAt, name, or updatedAt |
sortOrder | string | desc | asc or desc |
Get Gate
GET /api/flow/gates/:id
The :id parameter accepts UUID, shortId (fgate_xxx), or slug.
Update Gate
PUT /api/flow/gates/:id
Same fields as Create Gate, all optional. Additionally accepts:
| Field | Type | Description |
|---|---|---|
status | string | active, paused, or archived |
To update schema and business rules, use the dedicated Update Schema endpoint instead.
Delete Gate
DELETE /api/flow/gates/:id
Soft-deletes the gate. Returns 204.
Update Gate Schema
PUT /api/flow/gates/:id/schema
Creates a new schema version.
| Field | Type | Required | Description |
|---|---|---|---|
schema | object | Yes | ObjectSchema format |
businessRules | array | No | Updated business rules |
Import Schema from Template
POST /api/flow/gates/:id/import-schema
| Field | Type | Required | Description |
|---|---|---|---|
templateId | string | Yes | Template UUID, shortId (etpl_xxx), or slug |
Copies the template's variables into the gate schema as a new version.
List Schema Versions
GET /api/flow/gates/:id/versions
Returns all schema versions for the gate, ordered by version number.
Test Gate (Dry Run)
POST /api/flow/gates/:id/test
Validates the request body against the gate's schema and business rules without creating a run or consuming quota.
Request body: Raw JSON payload (the data to validate).
Response (200):
{
"valid": true,
"durationMs": 4.2,
"steps": [
{
"name": "Schema Validation",
"status": "pass",
"durationMs": 1.1,
"errors": null
},
{
"name": "Rule name here",
"ruleId": "rule_xxx",
"status": "pass",
"durationMs": 0.3,
"expression": "amount > 0"
}
]
}
Step status values: pass, fail, error, skipped.
Validate (Create Run)
POST /api/flow/gates/:id/validate
Validates the request body and creates a run. This is the primary submission endpoint.
Request body: Raw JSON payload.
Success response (200):
{
"success": true,
"runId": "...",
"shortId": "frun_xxx",
"status": "validated",
"validation_id": "v_abc123...",
"validated_payload": { ... },
"layers": {
"schema": "pass",
"business_rules": "pass"
}
}
Failure response (422):
{
"success": false,
"status": "validation_failed",
"error": {
"code": "VALIDATION_FAILED",
"message": "...",
"layer": "schema",
"details": [
{ "field": "email", "message": "Invalid email format", "code": "format" }
]
},
"layers": { "schema": "fail", "business_rules": "skipped" }
}
Rate limited (429): Returns retryAfter in seconds.
Runs
Submit Run
POST /api/flow/gates/:gateId/runs
| Field | Type | Required | Description |
|---|---|---|---|
payload | any | Yes | JSON object (variables mode) or string (freetext mode) |
metadata | object | No | Custom metadata stored on the run |
List Runs
GET /api/flow/runs
GET /api/flow/gates/:gateId/runs
| Parameter | Type | Default | Description |
|---|---|---|---|
page | integer | 1 | Page number |
limit | integer | 25 | Results per page (1-100) |
status | string | — | Filter by run status |
source | string | — | mcp or rest |
sortBy | string | createdAt | createdAt or status |
sortOrder | string | desc | asc or desc |
Get Run
GET /api/flow/runs/:id
Returns the full run record including input payload, validation result, render artefact URL, approval status, and delivery status.
Approvals
List Pending Approvals
GET /api/flow/approvals
Returns pending approvals for the authenticated user.
Approve
POST /api/flow/approvals/:id/approve
| Field | Type | Required | Description |
|---|---|---|---|
comment | string | No | Approval comment (max 1000 chars) |
Returns { "success": true, "decision": "approved" }.
Returns 409 if already decided.
Reject
POST /api/flow/approvals/:id/reject
| Field | Type | Required | Description |
|---|---|---|---|
comment | string | No | Rejection reason (max 1000 chars) |
Returns { "success": true, "decision": "rejected" }.
Returns 409 if already decided.
Deliveries
Get Run Deliveries
GET /api/flow/runs/:id/deliveries
Returns all delivery records for a run, including delivery attempts.
Retry Failed Delivery
POST /api/flow/deliveries/:id/retry
Re-enqueues a failed delivery attempt. Returns { "success": true, "message": "Retry enqueued" }.
Returns 404 if delivery not found. Returns 409 if delivery is already completed.
Webhook Payload Format
Delivered webhooks include:
{
"event": "flow.run.completed",
"run": {
"id": "...",
"shortId": "frun_xxx",
"status": "...",
"inputPayload": { ... },
"artefactUrl": "..."
},
"gate": {
"id": "...",
"name": "...",
"slug": "..."
},
"timestamp": "2026-03-04T10:00:00Z"
}
Webhook Headers
| Header | Description |
|---|---|
Content-Type | application/json |
User-Agent | Rynko-Flow/1.0 |
X-Rynko-Signature | v1={HMAC-SHA256 hex} |
X-Rynko-Timestamp | Unix timestamp |
X-Rynko-Event-Id | Run ID |
X-Rynko-Event-Type | flow.run.completed |
Verify the signature: HMAC-SHA256(secret, "{timestamp}.{body}").
Retry Policy
- 4xx responses: Not retried (permanent client error)
- 5xx responses or network errors: Retried up to 3 times
- Retry delays: 30 seconds, 2 minutes, 10 minutes
Review (External Approvers)
These endpoints are public — no API key required. Authentication uses magic link tokens.
Authenticate
POST /api/flow/review/authenticate
| Field | Type | Required | Description |
|---|---|---|---|
token | string | Yes | Magic link token from email |
email | string | Yes | Approver's email (identity challenge) |
Response (200):
{
"reviewToken": "eyJ...",
"expiresIn": 7200
}
Use the reviewToken as Bearer token for subsequent review endpoints.
Review Inbox
GET /api/flow/review/inbox
Auth: Authorization: Bearer REVIEW_TOKEN
Returns pending approvals for the review token holder.
Get Review Approval
GET /api/flow/review/approvals/:id
Auth: Authorization: Bearer REVIEW_TOKEN
Returns approval details with full run context.
Approve (Review)
POST /api/flow/review/approvals/:id/approve
Auth: Authorization: Bearer REVIEW_TOKEN
| Field | Type | Required | Description |
|---|---|---|---|
comment | string | No | Approval comment (max 1000 chars) |
Reject (Review)
POST /api/flow/review/approvals/:id/reject
Auth: Authorization: Bearer REVIEW_TOKEN
| Field | Type | Required | Description |
|---|---|---|---|
comment | string | No | Rejection reason (max 1000 chars) |
Resend Magic Link
POST /api/flow/review/resend
| Field | Type | Required | Description |
|---|---|---|---|
token | string | Yes | Original magic link token |
email | string | Yes | Approver's email address |
Rate limited to prevent abuse.
Analytics
All analytics endpoints require API key authentication and return data scoped to the workspace. See Analytics for detailed response formats.
| Endpoint | Description | Extra Parameters |
|---|---|---|
GET /api/flow/analytics/overview | Workspace summary | period, gateId |
GET /api/flow/analytics/run-outcomes | Run outcome distribution | period, gateId |
GET /api/flow/analytics/throughput | Time-series throughput | period, granularity, gateId |
GET /api/flow/analytics/validation-errors | Failure rates by gate | period, gateId |
GET /api/flow/analytics/approval-metrics | Approval rates and times | period, gateId |
GET /api/flow/analytics/infra-health | Circuit breaker and delivery health | period, gateId |
GET /api/flow/analytics/gate-metrics | Per-gate run counts | period, gateId |
GET /api/flow/analytics/billing-summary | Current period usage | — |
GET /api/flow/analytics/combined-timeline | Combined Flow + Render timeline | period, granularity |
GET /api/flow/analytics/team-overview | Team-level cross-workspace data | period |
GET /api/flow/analytics/plans | Available Flow plans | — |
GET /api/flow/analytics/credit-packs | Available credit packs | — |
Common parameters: period (7d, 30d, 90d), granularity (day, week, month).
Error Codes
| Code | HTTP Status | Description |
|---|---|---|
FLOW.GATE_NOT_FOUND | 404 | Gate not found |
FLOW.GATE_PAUSED | 409 | Gate is not active |
FLOW.GATE_VALIDATION_FAILED | 422 | Schema/rule definitions invalid |
FLOW.RUN_NOT_FOUND | 404 | Run not found |
FLOW.APPROVAL_NOT_FOUND | 404 | Approval record not found |
FLOW.APPROVAL_ALREADY_DECIDED | 409 | Decision already recorded |
FLOW.DELIVERY_NOT_FOUND | 404 | Delivery record not found |
FLOW.DELIVERY_ALREADY_COMPLETED | 409 | Cannot retry completed delivery |
FLOW.TEMPLATE_NOT_FOUND | 404 | Template not found for schema import |
FLOW.TEMPLATE_HAS_NO_VARIABLES | 422 | Template has no variables to import |
ERR_FLOW_RUN_003 | 503 | Circuit breaker open |
ERR_FLOW_RUN_004 | 429 | Rate limit exceeded |
ERR_FLOW_RUN_005 | 413 | Payload exceeds 1 MB |
Plans and Limits
| Free | Starter | Growth | Scale | |
|---|---|---|---|---|
| Monthly price | $0 | $29 | $79 | $149 |
| Runs/month | 500 | 2,000 | 15,000 | 50,000 |
| Max gates | 3 | 10 | 50 | Unlimited |
| Max approvers/gate | 5 | 10 | 25 | Unlimited |
| Artefact retention | 3 days | 5 days | 5 days | 5 days |
| Content limit | 50K chars | 100K chars | 200K chars | 500K chars |
Annual billing saves ~20%. Teams with both Render and Flow subscriptions get an additional 20% bundle discount.
Credit Packs (one-time)
| Pack | Runs | Price | Per Run |
|---|---|---|---|
| Micro | 100 | $10 | $0.10 |
| Small | 500 | $40 | $0.08 |
| Medium | 1,000 | $70 | $0.07 |
| Large | 2,500 | $150 | $0.06 |