Skip to main content

Managing Flows

A Flow is a named, reusable verification configuration — it defines which fields and documents are required, biometric method, age rules, geo-blocking, and per-country overrides for a verification. Every call to POST /v2/idv/verify (or a Web SDK Link) runs against a specific Flow, identified by its flowId.

note

Flows are created only in the Merchant Portal — there is no public endpoint to create one. Once a Flow exists, you can read, update, or delete it programmatically using the endpoints below. See Flows & Groups for how Flows relate to Groups.

Authentication

Same as Managing Groups — HTTP Basic Auth with your merchant API key and secret:

Authorization: Basic base64(apiKey:secret)

Base URL

https://api.cycurid.com/v2/public/flows

The Flow object

{
"flowId": "eb9863fd-bd81-47d6-be5f-e40369c9bffc",
"name": "Standard Onboarding",
"defaultFields": { "dob": true, "phone": true, "email": true },
"defaultDocumentTypes": ["PASSPORT", "DRIVERS"],
"countryOverrides": [],
"geoBlockedCountries": [],
"webhookUrl": null,
"minAge": null,
"maxAge": null,
"createdAt": "2026-01-15T18:32:00.000Z",
"updatedAt": "2026-01-15T18:32:00.000Z"
}
JSON fields are returned as strings, not objects

As of this writing, defaultFields, defaultDocumentTypes, countryOverrides, and geoBlockedCountries come back JSON-encoded as strings rather than parsed JSON (confirmed against the live API) — e.g. "defaultDocumentTypes": "[\"PASSPORT\",\"DRIVERS\"]" instead of "defaultDocumentTypes": ["PASSPORT","DRIVERS"]. Call JSON.parse() on each of these four fields before using them. This is a known quirk of the current API, not something you're doing wrong — the example above shows the intended shape after parsing.

FieldTypeNotes
flowIdstring (UUID)Unique identifier, generated when the Flow is created in the portal.
namestring1-100 characters. Unique within your account.
defaultFieldsobject (as a JSON string)Which optional fields /v2/idv/verify requires by default.
defaultDocumentTypesstring[] (as a JSON string)Accepted document types, e.g. PASSPORT, DRIVERS, ID_CARD, RESIDENCY_CARD.
countryOverridesarray (as a JSON string)Per-country customization of required fields/document types, or a country marked fully restricted for this Flow.
geoBlockedCountriesarray (as a JSON string)Countries blocked for this Flow specifically, in addition to any account-wide restrictions.
webhookUrlstring | nullURL notified on verification events for this Flow, if configured.
minAge / maxAgenumber | nullApplicant age bounds (1-120). null disables that bound.
createdAt / updatedAttimestamp

List Flows

GET /v2/public/flows

Returns all Flows belonging to your merchant account, most recently created first.

curl -X GET https://api.cycurid.com/v2/public/flows \
-H "Authorization: Basic $(echo -n 'YOUR_API_KEY:YOUR_SECRET' | base64)"

Get a Flow

GET /v2/public/flows/:flowId

Returns the Flow object, or 404 if it doesn't exist (or doesn't belong to your account).

Update a Flow

PUT /v2/public/flows/:flowId

All fields are optional — only send the fields you want to change. At least one field must be present, or the request is rejected with 400 { "message": "No fields to update" }.

FieldTypeNotes
namestring1-100 characters. Must remain unique within your account.
defaultFieldsobjectReplaces the default field requirements.
defaultDocumentTypesstring[]Replaces the accepted document types.
countryOverridesarrayReplaces per-country overrides.
geoBlockedCountriesarray of {countryAlpha2, countryName}Replaces the Flow-specific blocked country list.
webhookUrlstring | ""Must be a valid URL, or an empty string to clear it. Max 500 characters.
minAge / maxAgenumber | nullWhole number, 1-120. null removes the bound.

Every field you send fully replaces the existing value for that field — there's no merge/patch semantics within a field (e.g. sending defaultDocumentTypes replaces the whole array).

A document type requires an upload method

If a Flow (via defaultFields/defaultDocumentTypes, or a country override) requires a document type, it must also specify how that document is captured — documentFileUpload: true or documentCapture: true in the relevant fields object. Omitting both returns:

{ "message": "An upload method is required when a document type is selected" }

This is validated against the Flow's effective post-update configuration, so a partial update that only touches one part can still fail this check based on fields you didn't send.

curl -X PUT https://api.cycurid.com/v2/public/flows/eb9863fd-bd81-47d6-be5f-e40369c9bffc \
-H "Authorization: Basic $(echo -n 'YOUR_API_KEY:YOUR_SECRET' | base64)" \
-H "Content-Type: application/json" \
-d '{ "minAge": 18 }'

Delete a Flow

DELETE /v2/public/flows/:flowId

Permanently deletes the Flow.

curl -X DELETE https://api.cycurid.com/v2/public/flows/eb9863fd-bd81-47d6-be5f-e40369c9bffc \
-H "Authorization: Basic $(echo -n 'YOUR_API_KEY:YOUR_SECRET' | base64)"

Returns 200:

{ "message": "Flow deleted successfully" }
caution

Deleting a Flow that's still referenced by a Group or used as a flowId in ongoing integrations will break those references. There's no dependency check before deletion — confirm nothing depends on the Flow first.

Errors

StatusMeaning
400Request body/params failed validation, or (on PUT) the body had no updatable fields, or the effective config is missing a document upload method.
401Missing or malformed Authorization header.
400Invalid API key/secret combination.
403Merchant application is not completed or approved.
404Flow not found (wrong flowId, or it belongs to another account).
409A Flow with that name already exists on your account.

Notes

  • There is no POST (create) endpoint here — create Flows in the Merchant Portal's Configuration page, then manage them programmatically with the endpoints above.
  • Flow names are unique per merchant account, not globally.
  • Your subscription plan may limit the total number of Flows you can create in the portal.