Summary and recommendation
Userflow's REST API (base URL: https://api.userflow.com) authenticates via a Bearer token API key retrieved from Settings → Integrations → API.
All user and group writes use upsert semantics - POST to /users/{user_id} or /groups/{group_id} - with no separate create vs.
update endpoint.
List endpoints use cursor-based pagination (param: starting_after, default page size: 20, max: 100).
Rate limits are enforced per API key but exact per-plan figures are not publicly documented;
no Retry-After header is confirmed, so implement exponential backoff on HTTP 429 responses.
SCIM provisioning is not available.
API quick reference
| Has user API | Yes |
| Auth method | API Key (Bearer token in Authorization header) |
| Base URL | Official docs |
| SCIM available | No |
| SCIM plan required | N/A |
Authentication
Auth method: API Key (Bearer token in Authorization header)
Setup steps
- Log in to the Userflow dashboard.
- Navigate to Settings → Integrations → API.
- Copy the secret API key.
- Include it in every request as: Authorization: Bearer
User object / data model
| Field | Type | Description | On create | On update | Notes |
|---|---|---|---|---|---|
| id | string | Your system's unique user identifier | required | required (path param) | Used as the canonical user ID in Userflow |
| attributes.name | string | Display name of the user | optional | optional | Shown in Userflow dashboard |
| attributes.email | string | User's email address | optional | optional | Used for identification and messaging |
| attributes.signed_up_at | string (ISO 8601) | Timestamp when the user signed up | optional | optional | Used for segmentation |
| attributes.company_id | string | ID of the associated company/group | optional | optional | Links user to a group object |
| attributes.locale | string | User's locale (e.g., en-US) | optional | optional | Used for localized content delivery |
| attributes.role | string | User's role within their organization | optional | optional | Custom attribute for segmentation |
| attributes.plan | string | Subscription plan of the user | optional | optional | Custom attribute for segmentation |
| attributes.* | any | Arbitrary custom attributes | optional | optional | Any key-value pairs under attributes are stored and usable in segments/conditions |
| group_id | string | Group (company) membership | optional | optional | Associates user with a group at upsert time |
| group_attributes | object | Attributes to set on the associated group | optional | optional | Merged into the group object when group_id is provided |
Core endpoints
Upsert user
- Method: POST
- URL:
https://api.userflow.com/users/{user_id} - Watch out for: This is an upsert (create or update). Omitted attributes are NOT deleted; use null to explicitly clear an attribute.
Request example
POST /users/user_123
Authorization: Bearer <API_KEY>
Content-Type: application/json
{"attributes":{"name":"Jane Doe","email":"jane@example.com","plan":"pro"}}
Response example
{"object":"user","id":"user_123","attributes":{"name":"Jane Doe","email":"jane@example.com","plan":"pro"}}
Get user
- Method: GET
- URL:
https://api.userflow.com/users/{user_id} - Watch out for: Returns 404 if the user ID does not exist in Userflow.
Request example
GET /users/user_123
Authorization: Bearer <API_KEY>
Response example
{"object":"user","id":"user_123","attributes":{"name":"Jane Doe","email":"jane@example.com"}}
List users
- Method: GET
- URL:
https://api.userflow.com/users - Watch out for: Cursor-based pagination; use the last returned user's id as starting_after for the next page.
Request example
GET /users?limit=20&starting_after=user_100
Authorization: Bearer <API_KEY>
Response example
{"object":"list","data":[{"object":"user","id":"user_101","attributes":{}}],"has_more":true}
Delete user
- Method: DELETE
- URL:
https://api.userflow.com/users/{user_id} - Watch out for: Deletion is permanent and removes all associated flow state for that user.
Request example
DELETE /users/user_123
Authorization: Bearer <API_KEY>
Response example
{"object":"deleted","id":"user_123","deleted":true}
Track event
- Method: POST
- URL:
https://api.userflow.com/events - Watch out for: Event names are case-sensitive and must match exactly what is configured in Userflow flow triggers.
Request example
POST /events
Authorization: Bearer <API_KEY>
Content-Type: application/json
{"user_id":"user_123","name":"document_created","attributes":{"doc_type":"report"}}
Response example
{"object":"event","id":"evt_abc","name":"document_created","user_id":"user_123"}
Upsert group (company)
- Method: POST
- URL:
https://api.userflow.com/groups/{group_id} - Watch out for: Same upsert semantics as users; omitted attributes are preserved, not deleted.
Request example
POST /groups/company_456
Authorization: Bearer <API_KEY>
Content-Type: application/json
{"attributes":{"name":"Acme Corp","plan":"enterprise"}}
Response example
{"object":"group","id":"company_456","attributes":{"name":"Acme Corp","plan":"enterprise"}}
Add user to group
- Method: POST
- URL:
https://api.userflow.com/group_memberships - Watch out for: A user can belong to multiple groups. Alternatively, pass group_id directly in the user upsert payload.
Request example
POST /group_memberships
Authorization: Bearer <API_KEY>
Content-Type: application/json
{"user_id":"user_123","group_id":"company_456"}
Response example
{"object":"group_membership","user_id":"user_123","group_id":"company_456"}
List groups
- Method: GET
- URL:
https://api.userflow.com/groups - Watch out for: Cursor-based pagination applies; use starting_after with the last group id.
Request example
GET /groups?limit=20
Authorization: Bearer <API_KEY>
Response example
{"object":"list","data":[{"object":"group","id":"company_456","attributes":{"name":"Acme Corp"}}],"has_more":false}
Rate limits, pagination, and events
- Rate limits: Userflow enforces rate limits per API key. The official docs note limits but do not publish exact per-plan request-per-second figures publicly.
- Rate-limit headers: No
- Retry-After header: No
- Rate-limit notes: Official docs do not explicitly document rate-limit response headers or Retry-After behavior. Contact Userflow support for current limits.
- Pagination method: cursor
- Default page size: 20
- Max page size: 100
- Pagination pointer: starting_after
| Plan | Limit | Concurrent |
|---|---|---|
| All plans | Not publicly specified | 0 |
- Webhooks available: No
- Webhook notes: Userflow does not document outbound webhooks for user-management events in its official API reference as of the research date.
- Alternative event strategy: Use Userflow's native integrations (e.g., Segment, Amplitude, HubSpot) or poll the REST API to detect state changes.
SCIM API status
- SCIM available: No
- SCIM version: Not documented
- Plan required: N/A
- Endpoint: Not documented
Limitations:
- No SCIM provisioning support documented in official Userflow docs.
Common scenarios
Three integration patterns cover the primary lifecycle needs.
For new-user sync, POST to /users/{your_user_id} immediately after signup with email, name, signed_up_at, plan, and optionally group_id - the upsert creates or updates in a single call.
For event-driven flow triggers, POST to /events with a user_id and a case-sensitive event name that exactly matches the trigger configured in the Userflow dashboard;
mismatched casing creates a silent no-op.
For historical backfills, iterate your user export and POST each record individually - no bulk-upsert endpoint exists - and monitor for 429s before retrying.
In all three patterns, the user id passed to the API must match the id used in userflow.js identify() calls;
a mismatch silently creates duplicate user records, corrupting the identity graph.
Sync a new user on signup
- After user completes signup in your app, POST to https://api.userflow.com/users/{your_user_id} with Authorization: Bearer
. - Include attributes such as email, name, signed_up_at, and plan in the request body.
- Optionally include group_id and group_attributes to associate the user with their company in the same request.
- Userflow creates the user if new, or updates attributes if the user already exists.
Watch out for: Ensure the user id matches the id passed to userflow.js identify() in the frontend; otherwise two separate user records are created.
Track a product event to trigger a flow
- Configure a flow in the Userflow dashboard with an event-based trigger (e.g., event name 'feature_activated').
- From your backend, POST to https://api.userflow.com/events with user_id and name matching the configured trigger.
- Include relevant event attributes for use in flow conditions.
- Userflow evaluates the event against active flows and triggers the appropriate checklist or tour for that user.
Watch out for: Event names are case-sensitive; 'Feature_Activated' and 'feature_activated' are treated as different events.
Bulk-backfill historical users via list + upsert
- Export users from your database.
- For each user, POST to https://api.userflow.com/users/{user_id} with their attributes.
- Batch requests sequentially; monitor for rate-limit responses (HTTP 429) and back off before retrying.
- After upsert, optionally POST to /events to replay key historical events for segment qualification.
Watch out for: Userflow does not document a bulk-upsert endpoint; each user requires an individual POST request.
Why building this yourself is a trap
The upsert-only write model has a non-obvious attribute deletion behavior: omitting a field on a subsequent POST leaves the existing value intact, while explicitly passing null removes it. Developers who assume a partial update clears unset fields will accumulate stale attribute data that can cause incorrect segment membership and flow targeting.
Custom attributes are schema-less - any key under attributes is accepted - but attribute names used in segments must be consistent in casing across all write paths, or segment qualification will silently fail. Webhooks for user-management events are not documented;
state-change detection requires polling the REST API or routing through a native integration such as Segment, Amplitude, or HubSpot. API keys are environment-scoped, so production and staging keys must be managed separately to avoid cross-environment data contamination.
Automate Userflow workflows without one-off scripts
Stitchflow builds and maintains end-to-end IT automation across your SaaS stack, including apps without APIs. Built for exactly how your company works, with human approvals where they matter.