API reference
Every endpoint is authenticated with a bearer API key and lives under https://www.flowrelay.it/api/v1. Rate limit: 60 requests / minute / key.
Finding IDs
Every id is a UUID you discover from a list endpoint – you never need to know one up front.
| You need | Get it from |
|---|---|
| project_id (and {id} in the path) | GET /projects |
| handoff_id | GET /handoffs |
| insight_id | GET /projects/{id}/insights |
| digest_id | GET /projects/{id}/digests |
| channel_id | GET /discord/channels |
| filter values (repos, branches, etc.) | GET /handoffs/filters?project_id=... |
| jobId | returned in the 202 response when you start a generation |
| work item ref (key such as FR-12, or id) | GET /projects/{id}/work-items or GET /my-work |
| importId | returned by POST /projects/{id}/imports, or GET /projects/{id}/imports |
| suggestionId | GET /projects/{id}/suggestions |
List accessible projects
/projectsReturns the tenant context for the key owner: account type, organization memberships and every personal or organization project the key can access (role-scoped). `key` is the prefix of the work item keys of the project (`PAY` in `PAY-12`).
Request
curl "https://www.flowrelay.it/api/v1/projects" \
-H "Authorization: Bearer fr_your_api_key"Response
{
"account_type": "business",
"organizations": [
{
"id": "8c2b1a90-1234-4abc-9def-0123456789ab",
"name": "Acme",
"slug": "acme",
"role": "admin",
"is_temporary_admin": false
}
],
"projects": [
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"name": "Payments",
"slug": "payments",
"key": "PAY",
"description": "Billing and checkout",
"organization_id": "8c2b1a90-1234-4abc-9def-0123456789ab",
"organization_name": "Acme",
"organization_slug": "acme",
"project_type": "organization",
"access_role": "admin",
"created_at": "2026-05-01T09:12:00Z",
"updated_at": "2026-06-20T14:03:00Z"
}
]
}| Status | When |
|---|---|
| 200 | Success |
| 401 | Missing or invalid API key. |
| 429 | Rate limit exceeded (60/min/key). |
List handoffs
/handoffsLists handoffs across accessible projects, newest first. Without project_id it spans every project the key can access.
Query parameters
| Name | Type | Description |
|---|---|---|
statusoptional | string | Filter by status.One of: active, archived, allDefault: active |
limitoptional | integer | Maximum rows to return (1–100).Default: 20 |
project_idoptional | string | Restrict to a single project. |
Request
curl "https://www.flowrelay.it/api/v1/handoffs" \
-H "Authorization: Bearer fr_your_api_key"Response
{
"handoffs": [
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"project_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"kind": "project",
"title": "Checkout refactor handoff",
"summary": "Migrated the checkout flow to the new pricing engine.",
"status": "active",
"sources": [
"github",
"linear"
],
"key_changes": [
"Replaced legacy tax calc"
],
"decisions": [
"Use flat per-artifact pricing"
],
"open_questions": [
"Backfill historical invoices?"
],
"next_steps": [
"Wire the new webhook"
],
"completion_percentage": null,
"related_event_ids": [
"d4e5f6a7-b8c9-0123-def4-23456789013a"
],
"scope_type": "project",
"project_name": "Payments",
"created_at": "2026-06-20T14:03:00Z",
"updated_at": "2026-06-20T14:03:00Z",
"markdown": "# Checkout refactor handoff\n\n> Migrated the checkout flow…"
}
]
}| Status | When |
|---|---|
| 200 | Success |
| 400 | The body or a query parameter is invalid: an unknown field, an unknown source, an unsupported filter dimension or an out-of-range number. The response names the offending field and lists the allowed values. |
| 401 | Missing or invalid API key. |
| 404 | Project not found or not accessible by this key. |
Generate a handoff
/handoffsAsynchronous – returns 202 with a jobId. Poll GET /jobs/{jobId} until the job completes.
Enqueues a project handoff generation and returns a job id. Poll GET /jobs/{jobId} until status is completed. When sources/filters are omitted the project saved scope preferences are used.
Body parameters
| Name | Type | Description |
|---|---|---|
project_idrequired | string | Project UUID to generate the handoff for (from GET /projects). |
sourcesoptional | string[] | Restrict generation to these sources. Each must be a known source id; an unknown value is rejected with 400 (not silently ignored). Omit to use every connected source.One of: github, slack, discord, linear, notion, jira, gitlab, bitbucket, azure_devops, figma, confluence, microsoft_outlook, microsoft_teams, sentry, datadog, pagerduty, asana, gmail, buildkite, circleci, vercel, incident_io, netlify, render, railway, cloudflare_pages, clickup, monday_com, shortcut, intercom, zendesk, snyk, fireflies, zoom, grafana, google_calendar, google_drive, launchdarkly, hcp_terraform, sonarqube, miro, new_relic, jira_service_management, posthog, hubspot, salesforce, heroku, alertmanager, pulumi, google_meet, microsoft_teams_meetings, fathom |
filtersoptional | SourceFilter | Per-source projects / eventTypes / branches / priorities (AND-combined). Keys must be source ids (unknown keys are rejected with 400); the values are provider-driven and matched leniently – an unmatched value simply returns no events. Fetch GET /handoffs/filters for the set selectable on a project. |
Request
curl "https://www.flowrelay.it/api/v1/handoffs" \
-H "Authorization: Bearer fr_your_api_key" \
-X POST \
-H "Content-Type: application/json" \
-d '{ "project_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "sources": [ "github", "linear" ], "filters": { "github": { "branches": [ "main" ] } } }'Request body
{
"project_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"sources": [
"github",
"linear"
],
"filters": {
"github": {
"branches": [
"main"
]
}
}
}Response
{
"jobId": "c3d4e5f6-a7b8-9012-cdef-123456789012",
"status": "pending"
}| Status | When |
|---|---|
| 202 | Job enqueued. Poll GET /jobs/{jobId} for the result. |
| 400 | project_id is missing or invalid, or the body failed validation (unknown field / source / filter value). The response names the field and lists allowed values. |
| 401 | Missing or invalid API key. |
| 404 | Project not found or not accessible by this key. |
| 429 | Rate limit exceeded (60/min/key). |
List selectable filter options
/handoffs/filtersReturns the real selectable filter values per connected source for a project: resources (repos / channels / boards / Figma files), branches, event types, and priorities. Use these to build a valid SourceFilter instead of guessing. The response also carries a "figma" availability block: Figma can be selected only on projects in the Global processing region, and selecting it attaches visual context (frame renders) at a flat 1-credit surcharge.
Query parameters
| Name | Type | Description |
|---|---|---|
project_idrequired | string | Project UUID (from GET /projects) to resolve filter options for. |
Request
curl "https://www.flowrelay.it/api/v1/handoffs/filters?project_id=PROJECT_ID" \
-H "Authorization: Bearer fr_your_api_key"Response
{
"filters": {
"github": {
"projects": [
{
"id": "acme/payments",
"label": "acme/payments"
}
],
"eventTypes": [
{
"value": "push",
"label": "Push"
}
],
"priorities": [],
"branches": [
{
"value": "main",
"label": "main"
}
]
},
"linear": {
"projects": [
{
"id": "f1e2d3c4-b5a6-7890-1234-567890abcdef",
"label": "Core"
}
],
"eventTypes": [
{
"value": "issue",
"label": "Issue"
}
],
"priorities": [
{
"value": "high",
"label": "High"
}
]
}
},
"figma": {
"selectable": true,
"region": "default",
"scope": "personal",
"canManageResidency": true,
"residencyHref": "/projects/3fa85f64-5717-4562-b3fc-2c963f66afa6#data-residency"
}
}| Status | When |
|---|---|
| 200 | Success |
| 400 | project_id is missing or not a valid UUID. |
| 401 | Missing or invalid API key. |
| 404 | Project not found or not accessible by this key. |
List project insights
/projects/{id}/insightsLists AI insights for a project, newest first. Release notes and plan reviews are stored as insights too, so they show up here alongside the three analysis kinds. Optionally filter by kind and status.
Path parameters
| Name | Type | Description |
|---|---|---|
idrequired | string | Project UUID (from GET /projects). |
Query parameters
| Name | Type | Description |
|---|---|---|
kindoptional | string | Filter by insight kind.One of: cross_source_correlation, onboarding_brief, architecture_insight, release_notes, plan_review |
statusoptional | string | Filter by status.One of: active, archived, allDefault: active |
limitoptional | integer | Maximum rows to return (1–100).Default: 20 |
Request
curl "https://www.flowrelay.it/api/v1/projects/3fa85f64-5717-4562-b3fc-2c963f66afa6/insights" \
-H "Authorization: Bearer fr_your_api_key"Response
{
"insights": [
{
"id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"project_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"kind": "architecture_insight",
"title": "Pricing engine trade-offs",
"summary": "Flat per-artifact pricing simplifies billing at the cost of margin variance.",
"data": {
"tradeOffs": [],
"risks": [],
"patterns": [],
"recommendations": []
},
"model_used": "gemini-3.8-flash",
"status": "active",
"related_event_ids": [
"d4e5f6a7-b8c9-0123-def4-23456789013a"
],
"sources": [
"github"
],
"created_at": "2026-06-21T08:00:00Z",
"updated_at": "2026-06-21T08:00:00Z",
"markdown": "# Pricing engine trade-offs\n\n> Flat per-artifact pricing…"
}
]
}| Status | When |
|---|---|
| 200 | Success |
| 400 | The body or a query parameter is invalid: an unknown field, an unknown source, an unsupported filter dimension or an out-of-range number. The response names the offending field and lists the allowed values. |
| 401 | Missing or invalid API key. |
| 404 | Project not found or not accessible by this key. |
Generate an insight
/projects/{id}/insights/{kind}Asynchronous – returns 202 with a jobId. Poll GET /jobs/{jobId} until the job completes.
Enqueues an insight generation for the project and returns a job id. The accepted body fields depend on kind. Poll GET /jobs/{jobId} for the result.
Path parameters
| Name | Type | Description |
|---|---|---|
idrequired | string | Project UUID (from GET /projects). |
kindrequired | string | Insight kind. `plan_review` writes a status report from the numbers of the plan (5 credits) and needs a project role that can write.One of: correlation, onboarding, architecture, release_notes, plan_review |
Body parameters
| Name | Type | Description |
|---|---|---|
lookbackHoursoptional | integer | correlation only – window in hours (1–2160, default 168). Rejected on other kinds. |
lookbackDaysoptional | integer | onboarding / architecture – window in days (1–365, default 30 / 14). Rejected on correlation and on release_notes, which always covers the last 14 days. |
newMemberRoleoptional | string | onboarding only – role of the person being onboarded. |
focusAreaoptional | string | onboarding only – area to emphasise. |
focusQuestionoptional | string | architecture only – the question to investigate. |
sourceoptional | string | release_notes only – the code source to read (default github).One of: github, gitlab, bitbucket, azure_devops |
repooptional | string | release_notes only – restrict to one repository, matched against the events' repository name. Defaults to every repository the project tracks. |
styleoptional | string | release_notes only – output shape (default release_notes).One of: release_notes, pr_description |
sourcesoptional | string[] | Restrict to these sources. Unknown values are rejected with 400. On release_notes it widens the scope past the code source named by `source` (a build source alongside the repository, say); omit it to read that source alone.One of: github, slack, discord, linear, notion, jira, gitlab, bitbucket, azure_devops, figma, confluence, microsoft_outlook, microsoft_teams, sentry, datadog, pagerduty, asana, gmail, buildkite, circleci, vercel, incident_io, netlify, render, railway, cloudflare_pages, clickup, monday_com, shortcut, intercom, zendesk, snyk, fireflies, zoom, grafana, google_calendar, google_drive, launchdarkly, hcp_terraform, sonarqube, miro, new_relic, jira_service_management, posthog, hubspot, salesforce, heroku, alertmanager, pulumi, google_meet, microsoft_teams_meetings, fathom |
filtersoptional | SourceFilter | Per-source filters (AND-combined). Keys must be source ids (unknown keys are rejected with 400); values are matched leniently (see GET /handoffs/filters). |
maxEventsoptional | integer | Cap the events fed to the model (1–1000). Rejected on release_notes. |
Request
curl "https://www.flowrelay.it/api/v1/projects/3fa85f64-5717-4562-b3fc-2c963f66afa6/insights/architecture" \
-H "Authorization: Bearer fr_your_api_key" \
-X POST \
-H "Content-Type: application/json" \
-d '{ "focusQuestion": "Is the pricing engine coupling billing to providers?", "lookbackDays": 14 }'Request body
{
"focusQuestion": "Is the pricing engine coupling billing to providers?",
"lookbackDays": 14
}Response
{
"jobId": "e7f8a9b0-1c2d-3e4f-5a6b-7c8d9e0f1a2b",
"status": "pending"
}| Status | When |
|---|---|
| 202 | Job enqueued. Poll GET /jobs/{jobId} for the result. |
| 400 | Unsupported insight kind, or the body failed validation (unknown field / source / filter value, or a field that does not apply to this kind). The response names the field and lists allowed values. |
| 401 | Missing or invalid API key. |
| 404 | Project not found or not accessible by this key. |
| 429 | Rate limit exceeded (60/min/key). |
Ask a question about a project
/projects/{id}/qaAnswers one question grounded in the project context: the indexed codebase, connected baselines and the last 14 days of scoped activity. Synchronous – the answer comes back in the response, there is no job to poll. The answer cites the events it relied on as `ev:` plus the first 8 characters of the event id. Costs 2 credits.
Path parameters
| Name | Type | Description |
|---|---|---|
idrequired | string | Project UUID (from GET /projects). |
Body parameters
| Name | Type | Description |
|---|---|---|
questionrequired | string | The question, 1 to 2000 characters. |
filtersoptional | SourceFilter | Per-source filters (AND-combined) narrowing the activity considered. |
Request
curl "https://www.flowrelay.it/api/v1/projects/3fa85f64-5717-4562-b3fc-2c963f66afa6/qa" \
-H "Authorization: Bearer fr_your_api_key" \
-X POST \
-H "Content-Type: application/json" \
-d '{ "question": "Why did we move checkout off the legacy queue?" }'Request body
{
"question": "Why did we move checkout off the legacy queue?"
}Response
{
"answer": "Checkout moved off the legacy queue because the retry semantics could double-charge on a partial failure…",
"citations": [
"ev:a1b2c3d4",
"ev:9f8e7d6c"
]
}| Status | When |
|---|---|
| 200 | Answer produced. |
| 400 | question missing, empty, longer than 2000 characters, or an unknown body field was sent. |
| 401 | Missing or invalid API key. |
| 402 | The plan does not allow this flow. |
| 404 | Project not found or not accessible by this key. |
| 429 | Rate limit exceeded (60/min/key). |
| 504 | The answer took longer than 60s. Narrow the question. |
List context events
/eventsLists recent context events, newest first. With project_id it spans the project members and scoped sources; without it returns the key owner personal-stream events.
Query parameters
| Name | Type | Description |
|---|---|---|
sourceoptional | string | Filter by source. Unknown values are rejected with 400.One of: github, slack, discord, linear, notion, jira, gitlab, bitbucket, azure_devops, figma, confluence, microsoft_outlook, microsoft_teams, sentry, datadog, pagerduty, asana, gmail, buildkite, circleci, vercel, incident_io, netlify, render, railway, cloudflare_pages, clickup, monday_com, shortcut, intercom, zendesk, snyk, fireflies, zoom, grafana, google_calendar, google_drive, launchdarkly, hcp_terraform, sonarqube, miro, new_relic, jira_service_management, posthog, hubspot, salesforce, heroku, alertmanager, pulumi, google_meet, microsoft_teams_meetings, fathom |
limitoptional | integer | Maximum rows to return (1–200).Default: 50 |
project_idoptional | string | Restrict to a project scope. |
Request
curl "https://www.flowrelay.it/api/v1/events" \
-H "Authorization: Bearer fr_your_api_key"Response
{
"events": [
{
"id": "d4e5f6a7-b8c9-0123-def4-23456789013a",
"user_id": "0a9b8c7d-6e5f-4a3b-2c1d-0e9f8a7b6c5d",
"source": "github",
"event_type": "push",
"title": "Push to acme/payments",
"content": "3 commits on main",
"created_at": "2026-06-20T13:55:00Z"
}
]
}| Status | When |
|---|---|
| 200 | Success |
| 400 | The body or a query parameter is invalid: an unknown field, an unknown source, an unsupported filter dimension or an out-of-range number. The response names the offending field and lists the allowed values. |
| 401 | Missing or invalid API key. |
| 404 | Project not found or not accessible by this key. |
List integrations
/integrationsLists connected integrations. With project_id it returns the project-scoped resources with health and provider coverage; without it returns the key owner connected sources.
Query parameters
| Name | Type | Description |
|---|---|---|
project_idoptional | string | Return project-scoped integrations instead of personal ones. |
Request
curl "https://www.flowrelay.it/api/v1/integrations" \
-H "Authorization: Bearer fr_your_api_key"Response
{
"integrations": [
{
"source": "github",
"workspace_id": "acme",
"workspace_name": "Acme",
"connected_at": "2026-05-01T09:00:00Z",
"scope": "project",
"resource_type": "repository",
"connection_status": "active",
"providers_connected": 2,
"last_validated_at": "2026-06-20T10:00:00Z"
}
]
}| Status | When |
|---|---|
| 200 | Success |
| 401 | Missing or invalid API key. |
| 404 | Project not found or not accessible by this key. |
List untracked resources
/integrations/untrackedReturns active resources (last 30 days) that produced events but are not yet assigned to any project. The response is a bare array, sorted by most recent activity.
Request
curl "https://www.flowrelay.it/api/v1/integrations/untracked" \
-H "Authorization: Bearer fr_your_api_key"Response
[
{
"source": "slack",
"resource_id": "C0123",
"resource_name": "#incidents",
"resource_type": "channel",
"event_count": 42,
"last_event_at": "2026-06-20T12:00:00Z"
}
]| Status | When |
|---|---|
| 200 | Success |
| 401 | Missing or invalid API key. |
| 500 | Discovery failed for a connected source. |
Poll an async job
/jobs/{jobId}Returns the job record and, once completed, the generated artifact. `kind` names the generation (`project_handoff`, `cross_source_correlation`, `onboarding_brief`, `architecture_insight`, `release_notes`, `project_digest`) and `result_kind` tells you where the artifact lives (`handoff`, `insight` – release notes included – or `digest`). The artifact carries a `markdown` field with the canonical rendering – identical to the dashboard copy button. Poll this after any 202 response until status is completed or failed. While the job runs, `progress.phase` reports the stage the worker actually reached (`loading_context`, `retrieving`, `generating`, `saving`); it is null until the first phase is written.
Path parameters
| Name | Type | Description |
|---|---|---|
jobIdrequired | string | UUID of the job returned in a prior 202 (POST /handoffs or POST /projects/{id}/insights/{kind}). Project-scoped: only readable if you can access the job's project. |
Request
curl "https://www.flowrelay.it/api/v1/jobs/c3d4e5f6-a7b8-9012-cdef-123456789012" \
-H "Authorization: Bearer fr_your_api_key"Response
{
"job": {
"id": "c3d4e5f6-a7b8-9012-cdef-123456789012",
"project_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"kind": "project_handoff",
"status": "completed",
"result_kind": "handoff",
"result_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"error": null,
"error_code": null,
"progress": {
"phase": "saving",
"at": "2026-06-20T14:02:55Z"
},
"created_at": "2026-06-20T14:02:00Z",
"updated_at": "2026-06-20T14:03:00Z"
},
"result": {
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"title": "Checkout refactor handoff",
"markdown": "# Checkout refactor handoff\n\n> Migrated the checkout flow…"
}
}| Status | When |
|---|---|
| 200 | Success |
| 400 | jobId is not a valid UUID. |
| 401 | Missing or invalid API key. |
| 404 | Job not found or not accessible. |
List Discord channels
/discord/channelsLists the text channels in the Discord guild connected to the key owner.
Request
curl "https://www.flowrelay.it/api/v1/discord/channels" \
-H "Authorization: Bearer fr_your_api_key"Response
{
"channels": [
{
"id": "987654",
"name": "general",
"type": 0
}
]
}| Status | When |
|---|---|
| 200 | Success |
| 401 | Missing or invalid API key. |
| 404 | Discord not connected. |
| 400 | No guild associated with this integration. |
Send a Discord message
/discord/sendSends to a channel in the connected guild. Provide exactly one of: content (inline text); handoff_id or insight_id (renders that artifact to Markdown and attaches it as a .md file); or artifact (last_handoff / last_correlation / last_onboarding / last_architecture / last_release_notes, with project_id) to send the latest active artifact of that kind. Rendered artifacts use the same Markdown as the dashboard copy button and are always delivered as a .md attachment. The channel must belong to the connected guild (cross-tenant posts are rejected).
Body parameters
| Name | Type | Description |
|---|---|---|
channel_idrequired | string | Target channel id – a Discord snowflake from GET /discord/channels. |
contentoptional | string | Inline message text. Mutually exclusive with handoff_id / insight_id / artifact. |
handoff_idoptional | string | UUID of a handoff (from GET /handoffs). Rendered to Markdown and sent as a .md attachment. |
insight_idoptional | string | UUID of an insight (from GET /projects/{id}/insights). Sent as a .md attachment. |
artifactoptional | string | Send the latest active artifact of a kind. Requires project_id.One of: last_handoff, last_correlation, last_onboarding, last_architecture, last_release_notes |
project_idoptional | string | Project UUID. Required only when artifact is set. |
Request
curl "https://www.flowrelay.it/api/v1/discord/send" \
-H "Authorization: Bearer fr_your_api_key" \
-X POST \
-H "Content-Type: application/json" \
-d '{ "channel_id": "987654321098765432", "artifact": "last_handoff", "project_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6" }'Request body
{
"channel_id": "987654321098765432",
"artifact": "last_handoff",
"project_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
}Response
{
"ok": true,
"message_id": "111222333444555666"
}| Status | When |
|---|---|
| 200 | Success |
| 400 | channel_id missing, or no content / artifact provided. |
| 401 | Missing or invalid API key. |
| 403 | Channel does not belong to the connected guild. |
| 404 | Discord not connected, or the requested artifact does not exist / is not accessible. |
| 502 | Discord rejected the message. |
List my work
/my-workLists the work items assigned to the key owner across every accessible project: open items plus the ones finished in the last 7 days. Dates are wall-clock times in the time zone of each item project, named on the project.
Request
curl "https://www.flowrelay.it/api/v1/my-work" \
-H "Authorization: Bearer fr_your_api_key"Response
{
"items": [
{
"id": "4b8e2f1a-9c3d-4e5f-8a7b-6c5d4e3f2a10",
"key": "FR-12",
"title": "Move invoices to Paddle",
"status": "in_progress",
"blocked": false,
"priority": 3,
"kind": "task",
"percentComplete": 40,
"start": "2026-09-28T08:00",
"finish": "2026-10-02T17:00",
"deadline": "2026-10-09T17:00",
"updatedAt": "2026-09-28T09:14:03Z",
"url": "https://www.flowrelay.it/projects/3fa85f64-5717-4562-b3fc-2c963f66afa6/work?item=FR-12",
"project": {
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"name": "Billing",
"timezone": "Europe/Rome"
}
}
]
}| Status | When |
|---|---|
| 200 | Success |
| 401 | Missing or invalid API key. |
| 429 | Rate limit exceeded (60/min/key). |
List work items
/projects/{id}/work-itemsLists the tasks and milestones of a project plan ordered by item number, with the dates computed by the scheduler. Dates are wall-clock times (`YYYY-MM-DDTHH:mm`) in the plan time zone returned as `timezone`. Pass `nextCursor` back as `cursor` to read the next page.
Path parameters
| Name | Type | Description |
|---|---|---|
idrequired | string | Project UUID (from GET /projects). |
Query parameters
| Name | Type | Description |
|---|---|---|
statusoptional | string | Comma-separated statuses to keep (for example `todo,in_progress`). Omit for every status.One of: backlog, todo, in_progress, in_review, done, cancelled |
assigneeoptional | string | Only `me` is accepted: the items assigned to the key owner.One of: me |
limitoptional | integer | Items per page (1-200, default 100).Default: 100 |
cursoroptional | integer | The `nextCursor` of the previous page. |
Request
curl "https://www.flowrelay.it/api/v1/projects/3fa85f64-5717-4562-b3fc-2c963f66afa6/work-items" \
-H "Authorization: Bearer fr_your_api_key"Response
{
"timezone": "Europe/Rome",
"items": [
{
"id": "4b8e2f1a-9c3d-4e5f-8a7b-6c5d4e3f2a10",
"key": "FR-12",
"number": 12,
"title": "Move invoices to Paddle",
"kind": "task",
"status": "in_progress",
"blocked": false,
"priority": 3,
"isSummary": false,
"parentId": "9d8c7b6a-5f4e-4d3c-8b2a-1f0e9d8c7b6a",
"percentComplete": 40,
"start": "2026-09-28T08:00",
"finish": "2026-10-02T17:00",
"deadline": "2026-10-09T17:00",
"durationMinutes": 2400,
"critical": true,
"assignees": [
{
"userId": "0a9b8c7d-6e5f-4a3b-2c1d-0e9f8a7b6c5d",
"name": "Ada Rossi"
}
],
"version": 57,
"updatedAt": "2026-09-28T09:14:03Z",
"url": "https://www.flowrelay.it/projects/3fa85f64-5717-4562-b3fc-2c963f66afa6/work?item=FR-12"
}
],
"nextCursor": 12
}| Status | When |
|---|---|
| 200 | Success |
| 400 | The body or a query parameter is invalid: an unknown field, an unknown source, an unsupported filter dimension or an out-of-range number. The response names the offending field and lists the allowed values. |
| 401 | Missing or invalid API key. |
| 404 | Project not found or not accessible by this key. |
| 429 | Rate limit exceeded (60/min/key). |
Create a work item
/projects/{id}/work-itemsCreates a task or milestone and schedules it. The item gets the next number of the project and a key such as `FR-12`. Contributors can create items when the project allows it and can assign only themselves. Costs no credits.
Path parameters
| Name | Type | Description |
|---|---|---|
idrequired | string | Project UUID (from GET /projects). |
Body parameters
| Name | Type | Description |
|---|---|---|
titlerequired | string | Title, 1 to 500 characters. |
descriptionoptional | string | Plain text or Markdown, up to 50000 characters. |
parentoptional | string | Key or id of the parent item to nest under. |
kindoptional | string | Task or milestone.One of: task, milestoneDefault: task |
statusoptional | string | Initial status.One of: backlog, todo, in_progress, in_review, done, cancelledDefault: todo |
priorityoptional | integer | 0 lowest to 4 urgent.Default: 2 |
durationoptional | string | Working duration such as `4h`, `3d` or `2w` (the plan decides how long a day is), `3ed` for elapsed days, a trailing `?` for an estimate. |
deadlineoptional | string | `YYYY-MM-DD` or `YYYY-MM-DDTHH:mm` in the plan time zone. |
assigneeoptional | string | `me`, or the user id of a project member (managers only). |
Request
curl "https://www.flowrelay.it/api/v1/projects/3fa85f64-5717-4562-b3fc-2c963f66afa6/work-items" \
-H "Authorization: Bearer fr_your_api_key" \
-X POST \
-H "Content-Type: application/json" \
-d '{ "title": "Move invoices to Paddle", "parent": "FR-3", "duration": "3d", "deadline": "2026-10-09", "assignee": "me" }'Request body
{
"title": "Move invoices to Paddle",
"parent": "FR-3",
"duration": "3d",
"deadline": "2026-10-09",
"assignee": "me"
}Response
{
"item": {
"id": "4b8e2f1a-9c3d-4e5f-8a7b-6c5d4e3f2a10",
"key": "FR-12",
"number": 12,
"title": "Move invoices to Paddle",
"kind": "task",
"status": "in_progress",
"blocked": false,
"priority": 3,
"isSummary": false,
"parentId": "9d8c7b6a-5f4e-4d3c-8b2a-1f0e9d8c7b6a",
"percentComplete": 40,
"start": "2026-09-28T08:00",
"finish": "2026-10-02T17:00",
"deadline": "2026-10-09T17:00",
"durationMinutes": 2400,
"critical": true,
"assignees": [
{
"userId": "0a9b8c7d-6e5f-4a3b-2c1d-0e9f8a7b6c5d",
"name": "Ada Rossi"
}
],
"version": 57,
"updatedAt": "2026-09-28T09:14:03Z",
"url": "https://www.flowrelay.it/projects/3fa85f64-5717-4562-b3fc-2c963f66afa6/work?item=FR-12",
"description": "Replace the legacy invoice job with Paddle transactions.",
"predecessors": [
{
"key": "FR-3",
"type": "fs",
"lagMinutes": 0
}
],
"successors": [
{
"key": "FR-15",
"type": "fs",
"lagMinutes": 0
}
],
"evidence": [
{
"source": "github",
"kind": "commit",
"title": "FR-12 switch invoice webhook to Paddle",
"url": "https://github.com/acme/billing/commit/4f2a9c1",
"occurredAt": "2026-09-28T08:42:11Z"
}
],
"commentCount": 2
},
"warnings": []
}| Status | When |
|---|---|
| 201 | Item created and scheduled. |
| 400 | The body or a query parameter is invalid: an unknown field, an unknown source, an unsupported filter dimension or an out-of-range number. The response names the offending field and lists the allowed values. |
| 401 | Missing or invalid API key. |
| 402 | Work management is not part of the plan, or the project reached its item limit. |
| 403 | The project role of the key owner cannot create items or assign other people. |
| 404 | Project or parent item not found or not accessible by this key. |
| 409 | The plan kept changing while the item was saved. Retry. |
| 429 | Rate limit exceeded (60/min/key). |
Get a work item
/projects/{id}/work-items/{ref}Returns one work item by key or id with its description, scheduled dates, assignees, dependencies, the ten most recent accepted evidence links and the comment count.
Path parameters
| Name | Type | Description |
|---|---|---|
idrequired | string | Project UUID (from GET /projects). |
refrequired | string | Item key such as `FR-12`, or the item id. |
Request
curl "https://www.flowrelay.it/api/v1/projects/3fa85f64-5717-4562-b3fc-2c963f66afa6/work-items/FR-12" \
-H "Authorization: Bearer fr_your_api_key"Response
{
"timezone": "Europe/Rome",
"item": {
"id": "4b8e2f1a-9c3d-4e5f-8a7b-6c5d4e3f2a10",
"key": "FR-12",
"number": 12,
"title": "Move invoices to Paddle",
"kind": "task",
"status": "in_progress",
"blocked": false,
"priority": 3,
"isSummary": false,
"parentId": "9d8c7b6a-5f4e-4d3c-8b2a-1f0e9d8c7b6a",
"percentComplete": 40,
"start": "2026-09-28T08:00",
"finish": "2026-10-02T17:00",
"deadline": "2026-10-09T17:00",
"durationMinutes": 2400,
"critical": true,
"assignees": [
{
"userId": "0a9b8c7d-6e5f-4a3b-2c1d-0e9f8a7b6c5d",
"name": "Ada Rossi"
}
],
"version": 57,
"updatedAt": "2026-09-28T09:14:03Z",
"url": "https://www.flowrelay.it/projects/3fa85f64-5717-4562-b3fc-2c963f66afa6/work?item=FR-12",
"description": "Replace the legacy invoice job with Paddle transactions.",
"predecessors": [
{
"key": "FR-3",
"type": "fs",
"lagMinutes": 0
}
],
"successors": [
{
"key": "FR-15",
"type": "fs",
"lagMinutes": 0
}
],
"evidence": [
{
"source": "github",
"kind": "commit",
"title": "FR-12 switch invoice webhook to Paddle",
"url": "https://github.com/acme/billing/commit/4f2a9c1",
"occurredAt": "2026-09-28T08:42:11Z"
}
],
"commentCount": 2
}
}| Status | When |
|---|---|
| 200 | Success |
| 401 | Missing or invalid API key. |
| 404 | Project or item not found or not accessible by this key. |
| 429 | Rate limit exceeded (60/min/key). |
Update a work item
/projects/{id}/work-items/{ref}Changes the fields you send and reschedules the plan. Sending the same values again leaves the item unchanged. Contributors can update the items assigned to them or created by them; dates and durations may need a project manager. Pass `ifVersion` (the `version` you read) to refuse the change when someone edited the item in the meantime. Costs no credits.
Path parameters
| Name | Type | Description |
|---|---|---|
idrequired | string | Project UUID (from GET /projects). |
refrequired | string | Item key such as `FR-12`, or the item id. |
Body parameters
| Name | Type | Description |
|---|---|---|
statusoptional | string | New status. `done` sets progress to 100.One of: backlog, todo, in_progress, in_review, done, cancelled |
percentCompleteoptional | integer | Progress 0 to 100. 100 marks the item done. |
titleoptional | string | Title, 1 to 500 characters. |
descriptionoptional | string | Plain text or Markdown, up to 50000 characters. |
priorityoptional | integer | 0 lowest to 4 urgent. |
blockedoptional | boolean | Flag or unflag the item as blocked. A flag, not a status. |
durationoptional | string | Working duration such as `4h`, `3d` or `2w`. |
deadlineoptional | string | `YYYY-MM-DD` or `YYYY-MM-DDTHH:mm` in the plan time zone, or null to clear it. |
ifVersionoptional | integer | Apply only if the item still has this `version`. |
Request
curl "https://www.flowrelay.it/api/v1/projects/3fa85f64-5717-4562-b3fc-2c963f66afa6/work-items/FR-12" \
-H "Authorization: Bearer fr_your_api_key" \
-X PATCH \
-H "Content-Type: application/json" \
-d '{ "status": "done", "ifVersion": 57 }'Request body
{
"status": "done",
"ifVersion": 57
}Response
{
"item": {
"id": "4b8e2f1a-9c3d-4e5f-8a7b-6c5d4e3f2a10",
"key": "FR-12",
"number": 12,
"title": "Move invoices to Paddle",
"kind": "task",
"status": "done",
"blocked": false,
"priority": 3,
"isSummary": false,
"parentId": "9d8c7b6a-5f4e-4d3c-8b2a-1f0e9d8c7b6a",
"percentComplete": 100,
"start": "2026-09-28T08:00",
"finish": "2026-10-02T17:00",
"deadline": "2026-10-09T17:00",
"durationMinutes": 2400,
"critical": true,
"assignees": [
{
"userId": "0a9b8c7d-6e5f-4a3b-2c1d-0e9f8a7b6c5d",
"name": "Ada Rossi"
}
],
"version": 58,
"updatedAt": "2026-09-28T09:14:03Z",
"url": "https://www.flowrelay.it/projects/3fa85f64-5717-4562-b3fc-2c963f66afa6/work?item=FR-12",
"description": "Replace the legacy invoice job with Paddle transactions.",
"predecessors": [
{
"key": "FR-3",
"type": "fs",
"lagMinutes": 0
}
],
"successors": [
{
"key": "FR-15",
"type": "fs",
"lagMinutes": 0
}
],
"evidence": [
{
"source": "github",
"kind": "commit",
"title": "FR-12 switch invoice webhook to Paddle",
"url": "https://github.com/acme/billing/commit/4f2a9c1",
"occurredAt": "2026-09-28T08:42:11Z"
}
],
"commentCount": 2
},
"warnings": []
}| Status | When |
|---|---|
| 200 | Item updated and the plan rescheduled. |
| 400 | The body or a query parameter is invalid: an unknown field, an unknown source, an unsupported filter dimension or an out-of-range number. The response names the offending field and lists the allowed values. |
| 401 | Missing or invalid API key. |
| 402 | Work management is not part of the plan. |
| 403 | The project role of the key owner cannot change these fields on this item. |
| 404 | Project or item not found or not accessible by this key. |
| 409 | `ifVersion` no longer matches: the item changed since you read it. |
| 422 | The plan cannot be scheduled with this change (no working time left on the calendar). |
| 429 | Rate limit exceeded (60/min/key). |
Delete a work item
/projects/{id}/work-items/{ref}Soft-deletes the item and its sub-items, removes their dependencies and assignments from the plan and reschedules it. The deletion is recorded as one batch in the change history, so a project manager can restore it. Contributors can delete only the items they created. Costs no credits.
Path parameters
| Name | Type | Description |
|---|---|---|
idrequired | string | Project UUID (from GET /projects). |
refrequired | string | Item key such as `FR-12`, or the item id. |
Request
curl "https://www.flowrelay.it/api/v1/projects/3fa85f64-5717-4562-b3fc-2c963f66afa6/work-items/FR-12" \
-H "Authorization: Bearer fr_your_api_key" \
-X DELETEResponse
Returns 204 with no body.
| Status | When |
|---|---|
| 204 | Item deleted and the plan rescheduled. |
| 401 | Missing or invalid API key. |
| 402 | Work management is not part of the plan. |
| 403 | The project role of the key owner cannot delete this item. |
| 404 | Project or item not found or not accessible by this key. |
| 422 | The plan cannot be scheduled after the change. |
| 429 | Rate limit exceeded (60/min/key). |
List the evidence of a work item
/projects/{id}/work-items/{ref}/evidenceReturns the activity linked to one work item, newest first: accepted evidence (commits, pull requests, builds, deploys, incidents, meetings, documents and manual links) plus the suggested evidence routed to the key owner. Project owners and managers also see the suggestions that name no author. `author` is a name only when the activity is attributed through a confirmed linked account and the organization allows named authors, otherwise null. `ref` also accepts a former project key and the key a tracker gave a mirrored item.
Path parameters
| Name | Type | Description |
|---|---|---|
idrequired | string | Project UUID (from GET /projects). |
refrequired | string | Item key such as `FR-12`, the tracker key of a mirrored item such as `PAY-123`, or the item id. |
Request
curl "https://www.flowrelay.it/api/v1/projects/3fa85f64-5717-4562-b3fc-2c963f66afa6/work-items/FR-12/evidence" \
-H "Authorization: Bearer fr_your_api_key"Response
{
"evidence": [
{
"id": "9e8d7c6b-5a4f-4e3d-8c2b-1a0f9e8d7c6b",
"source": "github",
"kind": "pull_request",
"reference": "acme/billing#41",
"url": "https://github.com/acme/billing/pull/41",
"title": "FR-12 switch invoice webhook",
"occurredAt": "2026-09-28T08:30:00Z",
"origin": "key_reference",
"status": "accepted",
"confidence": 1,
"author": "Ada Rossi"
}
]
}| Status | When |
|---|---|
| 200 | Success |
| 401 | Missing or invalid API key. |
| 404 | Project or item not found or not accessible by this key. |
| 429 | Rate limit exceeded (60/min/key). |
Link evidence to a work item
/projects/{id}/work-items/{ref}/evidenceAttaches an https link (a pull request, commit, build, deploy, incident, document or anything else) to a work item as accepted evidence. It joins the activity trail of the item and its evidence coverage. Sending the same link again updates its title, kind and time and creates no duplicate. Viewers cannot link. Costs no credits.
Path parameters
| Name | Type | Description |
|---|---|---|
idrequired | string | Project UUID (from GET /projects). |
refrequired | string | Item key such as `FR-12`, or the item id. |
Body parameters
| Name | Type | Description |
|---|---|---|
urlrequired | string | The https link, up to 500 characters. |
titleoptional | string | Title, 1 to 300 characters. Defaults to the link itself. |
kindoptional | string | What the link points to.One of: commit, branch, pull_request, review, build, deploy, incident, ticket, message, meeting, document, otherDefault: other |
occurredAtoptional | string | When the work happened, ISO 8601. Defaults to now. |
Request
curl "https://www.flowrelay.it/api/v1/projects/3fa85f64-5717-4562-b3fc-2c963f66afa6/work-items/FR-12/evidence" \
-H "Authorization: Bearer fr_your_api_key" \
-X POST \
-H "Content-Type: application/json" \
-d '{ "url": "https://github.com/acme/billing/pull/41", "kind": "pull_request", "occurredAt": "2026-09-28T08:30:00Z" }'Request body
{
"url": "https://github.com/acme/billing/pull/41",
"kind": "pull_request",
"occurredAt": "2026-09-28T08:30:00Z"
}Response
{
"linked": true,
"url": "https://github.com/acme/billing/pull/41"
}| Status | When |
|---|---|
| 201 | Link attached. |
| 400 | The body or a query parameter is invalid: an unknown field, an unknown source, an unsupported filter dimension or an out-of-range number. The response names the offending field and lists the allowed values. |
| 401 | Missing or invalid API key. |
| 402 | Work management is not part of the plan. |
| 403 | The key owner is a viewer of this project. |
| 404 | Project or item not found or not accessible by this key. |
| 429 | Rate limit exceeded (60/min/key). |
List pending suggestions
/projects/{id}/suggestionsReturns the pending suggestions of a plan that the key owner can act on: `status_change` (a status proposed from linked activity, first offered to the assignee and shown to managers after three working days), `create_item` (an action item from a meeting transcript), `dependency` (a blocking link found in a mirrored tracker) and `evidence` (activity that looks related to an item). `forYou` marks the ones routed to the key owner. Nothing changes until a suggestion is accepted.
Path parameters
| Name | Type | Description |
|---|---|---|
idrequired | string | Project UUID (from GET /projects). |
Request
curl "https://www.flowrelay.it/api/v1/projects/3fa85f64-5717-4562-b3fc-2c963f66afa6/suggestions" \
-H "Authorization: Bearer fr_your_api_key"Response
{
"suggestions": [
{
"id": "0f3e1d2c-4b5a-4987-8a6b-5c4d3e2f1a09",
"type": "status_change",
"item": "FR-12",
"payload": {
"from": "in_progress",
"to": "in_review",
"reason": "Pull request opened: acme/billing#41"
},
"origin": "evidence_rule",
"forYou": true,
"createdAt": "2026-09-28T10:00:00Z"
},
{
"id": "1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
"type": "create_item",
"item": null,
"payload": {
"title": "Send the revised invoice template to finance",
"description": null,
"parent": null,
"reason": "From the meeting \"Billing sync\" of 2026-09-27"
},
"origin": "meeting",
"forYou": false,
"createdAt": "2026-09-27T16:10:00Z"
}
]
}| Status | When |
|---|---|
| 200 | Success |
| 401 | Missing or invalid API key. |
| 404 | Project not found or not accessible by this key. |
| 429 | Rate limit exceeded (60/min/key). |
Accept or dismiss a suggestion
/projects/{id}/suggestions/{suggestionId}`accept` applies the suggestion with the permissions of the key owner: the status change, the new item, the dependency or the evidence link. `dismiss` closes it. A status change whose item moved on in the meantime expires instead of overwriting the newer status. Costs no credits.
Path parameters
| Name | Type | Description |
|---|---|---|
idrequired | string | Project UUID (from GET /projects). |
suggestionIdrequired | string | Suggestion UUID (from GET /projects/{id}/suggestions). |
Body parameters
| Name | Type | Description |
|---|---|---|
actionrequired | string | What to do with the suggestion.One of: accept, dismiss |
Request
curl "https://www.flowrelay.it/api/v1/projects/3fa85f64-5717-4562-b3fc-2c963f66afa6/suggestions/0f3e1d2c-4b5a-4987-8a6b-5c4d3e2f1a09" \
-H "Authorization: Bearer fr_your_api_key" \
-X POST \
-H "Content-Type: application/json" \
-d '{ "action": "accept" }'Request body
{
"action": "accept"
}Response
{
"status": "accepted",
"numbers": {},
"version": 58
}| Status | When |
|---|---|
| 200 | Accepted or dismissed. |
| 400 | The body or a query parameter is invalid: an unknown field, an unknown source, an unsupported filter dimension or an out-of-range number. The response names the offending field and lists the allowed values. |
| 401 | Missing or invalid API key. |
| 403 | The project role of the key owner cannot make this change. |
| 404 | Project or suggestion not found, or the suggestion is not visible to this key. |
| 409 | The suggestion was already decided, or the item changed since it was made. |
| 422 | The suggestion no longer describes a change that can be applied. |
| 429 | Rate limit exceeded (60/min/key). |
Start a plan import
/projects/{id}/importsStarts importing an MS Project XML file (MSPDI, from Project desktop Save As > XML), an Oracle Primavera P6 file (.xer), or a CSV file and returns a signed upload URL. Upload the file with `PUT` to `upload.signedUrl` within 2 hours, sending `Content-Type: application/xml`, `text/plain` or `text/csv` and no Authorization header (50 MB at most), then call `POST /projects/{id}/imports/{importId}` with `{"action": "parse"}`. Project managers only. Costs no credits.
Path parameters
| Name | Type | Description |
|---|---|---|
idrequired | string | Project UUID (from GET /projects). |
Body parameters
| Name | Type | Description |
|---|---|---|
kindrequired | string | `mspdi` for an MS Project XML file, `xer` for an Oracle Primavera P6 export, `csv` for a spreadsheet export.One of: mspdi, csv, xer |
fileNamerequired | string | Name of the file, up to 255 characters. Shown in the import history. |
Request
curl "https://www.flowrelay.it/api/v1/projects/3fa85f64-5717-4562-b3fc-2c963f66afa6/imports" \
-H "Authorization: Bearer fr_your_api_key" \
-X POST \
-H "Content-Type: application/json" \
-d '{ "kind": "mspdi", "fileName": "launch-plan.xml" }'Request body
{
"kind": "mspdi",
"fileName": "launch-plan.xml"
}Response
{
"importId": "6d1f0c2a-8b3e-4f5a-9c7d-2e1f0a9b8c7d",
"upload": {
"bucket": "plan-imports",
"path": "3fa85f64-5717-4562-b3fc-2c963f66afa6/6d1f0c2a-8b3e-4f5a-9c7d-2e1f0a9b8c7d/launch-plan.xml",
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1cmwiOiJwbGFuLWltcG9ydHMvLi4uIn0.signature",
"signedUrl": "https://xyzcompany.supabase.co/storage/v1/object/upload/sign/plan-imports/3fa85f64-5717-4562-b3fc-2c963f66afa6/6d1f0c2a-8b3e-4f5a-9c7d-2e1f0a9b8c7d/launch-plan.xml?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1cmwiOiJwbGFuLWltcG9ydHMvLi4uIn0.signature"
}
}| Status | When |
|---|---|
| 201 | Import created. Upload the file to `upload.signedUrl`. |
| 400 | The body or a query parameter is invalid: an unknown field, an unknown source, an unsupported filter dimension or an out-of-range number. The response names the offending field and lists the allowed values. |
| 401 | Missing or invalid API key. |
| 402 | Importing plans is not part of the plan (Starter and above). |
| 403 | The key owner is not a manager of this project. |
| 404 | Project not found or not accessible by this key. |
| 429 | Rate limit exceeded (60/min/key, and 10 imports per hour per user). |
List plan imports
/projects/{id}/importsLists the ten most recent imports of a project, newest first, with their status, preview, warnings and results.
Path parameters
| Name | Type | Description |
|---|---|---|
idrequired | string | Project UUID (from GET /projects). |
Request
curl "https://www.flowrelay.it/api/v1/projects/3fa85f64-5717-4562-b3fc-2c963f66afa6/imports" \
-H "Authorization: Bearer fr_your_api_key"Response
{
"imports": [
{
"id": "6d1f0c2a-8b3e-4f5a-9c7d-2e1f0a9b8c7d",
"kind": "mspdi",
"status": "preview",
"file_name": "launch-plan.xml",
"preview": {
"name": "Launch plan",
"counts": {
"tasks": 312,
"summaries": 41,
"milestones": 9,
"links": 356,
"assignments": 288,
"calendars": 2
},
"baselines": [
0
],
"customFields": [
{
"key": "workstream",
"label": "Workstream",
"type": "text"
}
],
"resources": [
{
"ref": "3",
"name": "Ada Rossi",
"email": "ada@acme.dev",
"suggested": "f3a2b1c0-9d8e-4f7a-8b6c-5d4e3f2a1b0c"
},
{
"ref": "7",
"name": "Contractor",
"email": null,
"suggested": null
}
],
"settings": {
"projectStart": "2026-10-05T08:00",
"statusDate": null,
"minutesPerDay": 480,
"minutesPerWeek": 2400,
"daysPerMonth": 20,
"calendar": "Standard"
},
"sample": [
{
"ref": "1",
"level": 1,
"name": "Discovery",
"durationMinutes": 4800,
"start": "2026-10-05T08:00",
"finish": "2026-10-16T17:00"
}
],
"existingItems": 0,
"csv": null
},
"warnings": [
{
"code": "split_task",
"message": "2 split tasks were imported as one continuous bar.",
"refs": [
"58",
"61"
]
}
],
"stats": {},
"error": null,
"created_at": "2026-09-28T09:20:11Z",
"applied_at": null
}
]
}| Status | When |
|---|---|
| 200 | Success |
| 401 | Missing or invalid API key. |
| 404 | Project not found or not accessible by this key. |
| 429 | Rate limit exceeded (60/min/key). |
Get a plan import
/projects/{id}/imports/{importId}Returns one import. `status` moves from `uploading` to `parsing`, then `preview` (read the counts, the resources to map and the `warnings`) and, after `apply`, to `applying` and `applied` with the results in `stats`. `failed` carries the reason in `error`. The `preview` is dropped once the import is applied or discarded. Poll every few seconds while it is `parsing` or `applying`.
Path parameters
| Name | Type | Description |
|---|---|---|
idrequired | string | Project UUID (from GET /projects). |
importIdrequired | string | Import UUID (from POST /projects/{id}/imports). |
Request
curl "https://www.flowrelay.it/api/v1/projects/3fa85f64-5717-4562-b3fc-2c963f66afa6/imports/6d1f0c2a-8b3e-4f5a-9c7d-2e1f0a9b8c7d" \
-H "Authorization: Bearer fr_your_api_key"Response
{
"import": {
"id": "6d1f0c2a-8b3e-4f5a-9c7d-2e1f0a9b8c7d",
"kind": "mspdi",
"status": "preview",
"file_name": "launch-plan.xml",
"preview": {
"name": "Launch plan",
"counts": {
"tasks": 312,
"summaries": 41,
"milestones": 9,
"links": 356,
"assignments": 288,
"calendars": 2
},
"baselines": [
0
],
"customFields": [
{
"key": "workstream",
"label": "Workstream",
"type": "text"
}
],
"resources": [
{
"ref": "3",
"name": "Ada Rossi",
"email": "ada@acme.dev",
"suggested": "f3a2b1c0-9d8e-4f7a-8b6c-5d4e3f2a1b0c"
},
{
"ref": "7",
"name": "Contractor",
"email": null,
"suggested": null
}
],
"settings": {
"projectStart": "2026-10-05T08:00",
"statusDate": null,
"minutesPerDay": 480,
"minutesPerWeek": 2400,
"daysPerMonth": 20,
"calendar": "Standard"
},
"sample": [
{
"ref": "1",
"level": 1,
"name": "Discovery",
"durationMinutes": 4800,
"start": "2026-10-05T08:00",
"finish": "2026-10-16T17:00"
}
],
"existingItems": 0,
"csv": null
},
"warnings": [
{
"code": "split_task",
"message": "2 split tasks were imported as one continuous bar.",
"refs": [
"58",
"61"
]
}
],
"stats": {},
"error": null,
"created_at": "2026-09-28T09:20:11Z",
"applied_at": null
}
}| Status | When |
|---|---|
| 200 | Success |
| 401 | Missing or invalid API key. |
| 404 | Project or import not found or not accessible by this key. |
| 429 | Rate limit exceeded (60/min/key). |
Parse, apply or discard an import
/projects/{id}/imports/{importId}`parse` reads the uploaded file and builds the preview (for a CSV file you can pass the column `mapping` and the `dateOrder`, otherwise both are guessed). `apply` creates the items, links, assignments, calendars, baselines and custom fields in one batch: `append` adds them after the existing items, `replace` deletes the existing items first. `resourceMap` maps each resource of the file to a project member (`resourceId` from the preview suggestions) or to nobody. `discard` deletes the uploaded file. Project managers only.
Path parameters
| Name | Type | Description |
|---|---|---|
idrequired | string | Project UUID (from GET /projects). |
importIdrequired | string | Import UUID (from POST /projects/{id}/imports). |
Body parameters
| Name | Type | Description |
|---|---|---|
actionrequired | string | What to do with the import.One of: parse, apply, discard |
mappingoptional | object | CSV only, with `parse`: field name to zero-based column index, for example `{"name": 0, "duration": 2}`. Fields: `id`, `name`, `outline_level`, `wbs`, `duration`, `start`, `finish`, `predecessors`, `percent_complete`, `status`, `notes`, `resources`, `milestone`, `deadline`, `priority`. |
dateOrderoptional | string | CSV only, with `parse`: how dates are written.One of: ymd, dmy, mdy |
modeoptional | string | With `apply`: add to the plan or replace it.One of: append, replaceDefault: append |
applySettingsoptional | boolean | With `apply`: also take the project start, status date, day length and calendars from the file.Default: true |
resourceMapoptional | object | With `apply`: resource `ref` of the preview to a project member `resourceId`, or null for nobody. Unmapped resources are not assigned. |
Request
curl "https://www.flowrelay.it/api/v1/projects/3fa85f64-5717-4562-b3fc-2c963f66afa6/imports/6d1f0c2a-8b3e-4f5a-9c7d-2e1f0a9b8c7d" \
-H "Authorization: Bearer fr_your_api_key" \
-X POST \
-H "Content-Type: application/json" \
-d '{ "action": "apply", "mode": "append", "resourceMap": { "3": "f3a2b1c0-9d8e-4f7a-8b6c-5d4e3f2a1b0c", "7": null } }'Request body
{
"action": "apply",
"mode": "append",
"resourceMap": {
"3": "f3a2b1c0-9d8e-4f7a-8b6c-5d4e3f2a1b0c",
"7": null
}
}Response
{
"status": "applying"
}| Status | When |
|---|---|
| 200 | `discard` done. |
| 202 | `parse` or `apply` started. Poll GET /projects/{id}/imports/{importId}. |
| 400 | The body or a query parameter is invalid: an unknown field, an unknown source, an unsupported filter dimension or an out-of-range number. The response names the offending field and lists the allowed values. |
| 401 | Missing or invalid API key. |
| 403 | The key owner is not a manager of this project. |
| 404 | Project or import not found or not accessible by this key. |
| 409 | The import is not in a state that allows this action (apply needs a preview; a running import cannot be discarded). |
| 429 | Rate limit exceeded (60/min/key). |
Export a plan
/projects/{id}/exportDownloads the project plan as an MS Project XML file (tasks, outline, dependencies, constraints, deadlines, progress, calendars, resources, assignments and saved baselines) that Project desktop opens with File > Open, or as a CSV file with one row per item. Dates are wall-clock times in the plan time zone.
Path parameters
| Name | Type | Description |
|---|---|---|
idrequired | string | Project UUID (from GET /projects). |
Query parameters
| Name | Type | Description |
|---|---|---|
formatrequired | string | `mspdi` for MS Project XML, `csv` for a spreadsheet.One of: mspdi, csv |
Request
curl "https://www.flowrelay.it/api/v1/projects/3fa85f64-5717-4562-b3fc-2c963f66afa6/export?format=mspdi" \
-H "Authorization: Bearer fr_your_api_key" \
-o plan.xmlResponse
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Project xmlns="http://schemas.microsoft.com/project">
<SaveVersion>14</SaveVersion>
<Name>Billing.xml</Name>
<Title>Billing</Title>
<StartDate>2026-09-28T08:00:00</StartDate>
<Tasks>
<Task>
<UID>12</UID>
<Name>Move invoices to Paddle</Name>
<Start>2026-09-28T08:00:00</Start>
<Finish>2026-10-02T17:00:00</Finish>
<Duration>PT40H0M0S</Duration>
<PercentComplete>40</PercentComplete>
</Task>
</Tasks>
</Project>| Status | When |
|---|---|
| 200 | The file, with a `Content-Disposition: attachment` header. |
| 400 | The body or a query parameter is invalid: an unknown field, an unknown source, an unsupported filter dimension or an out-of-range number. The response names the offending field and lists the allowed values. |
| 401 | Missing or invalid API key. |
| 402 | Exporting plans is not part of the plan (Starter and above). |
| 404 | Project not found or not accessible by this key. |
| 429 | Rate limit exceeded (60/min/key). |
List your logged time
/time-entriesReturns the hours the key owner logged between two dates, oldest first, with the status of the weekly timesheet each entry belongs to. Only the key owner's own time: there is no way to read someone else's entries through this endpoint.
Query parameters
| Name | Type | Description |
|---|---|---|
fromrequired | string | First day, YYYY-MM-DD. |
torequired | string | Last day, YYYY-MM-DD, at most 92 days after `from`. |
Request
curl "https://www.flowrelay.it/api/v1/time-entries?from=2026-09-28&to=2026-10-04" \
-H "Authorization: Bearer fr_your_api_key"Response
{
"entries": [
{
"id": "5e4d3c2b-1a09-4f8e-9d7c-6b5a4f3e2d1c",
"projectId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"item": "FR-12",
"date": "2026-09-29",
"minutes": 90,
"note": "Pairing on the retry logic",
"source": "manual",
"status": "draft"
}
]
}| Status | When |
|---|---|
| 200 | Success |
| 400 | The body or a query parameter is invalid: an unknown field, an unknown source, an unsupported filter dimension or an out-of-range number. The response names the offending field and lists the allowed values. |
| 401 | Missing or invalid API key. |
| 429 | Rate limit exceeded (60/min/key). |
Log time
/time-entriesAdds time to the key owner's own timesheet for the week of `date`. Logging again on the same item and day adds up and never overwrites. Organization projects accept time only while the organization has time tracking turned on, and a submitted or approved week can no longer change. Costs no credits.
Body parameters
| Name | Type | Description |
|---|---|---|
projectIdrequired | string | Project UUID (from GET /projects). |
refoptional | string | Item key such as `FR-12`, or the item id. Without it the time counts on the project as a whole. |
daterequired | string | Day worked, YYYY-MM-DD. |
minutesrequired | integer | Whole minutes, 1 to 1440. A day never holds more than 24 hours. |
noteoptional | string | Up to 500 characters. |
Request
curl "https://www.flowrelay.it/api/v1/time-entries" \
-H "Authorization: Bearer fr_your_api_key" \
-X POST \
-H "Content-Type: application/json" \
-d '{ "projectId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "ref": "FR-12", "date": "2026-09-29", "minutes": 90 }'Request body
{
"projectId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"ref": "FR-12",
"date": "2026-09-29",
"minutes": 90
}Response
{
"logged": 90,
"date": "2026-09-29",
"week": "2026-09-28"
}| Status | When |
|---|---|
| 201 | Time logged. |
| 400 | The body or a query parameter is invalid: an unknown field, an unknown source, an unsupported filter dimension or an out-of-range number. The response names the offending field and lists the allowed values. |
| 401 | Missing or invalid API key. |
| 403 | The organization has not turned time tracking on. |
| 404 | Project or item not found or not accessible by this key. |
| 409 | The week is submitted or approved. |
| 429 | Rate limit exceeded (60/min/key). |
Get earned value and costs
/projects/{id}/evmReturns the cost picture of a plan at its status date: planned and actual cost, and the earned value figures (planned value, earned value, variances, SPI, CPI, TCPI and the three estimates at completion) measured against a baseline. Amounts are whole cents in the currency of the organization. Actual cost comes from logged hours at the rate in force that day when any were logged, otherwise from progress. Project managers only, on plans that include costs. Costs no credits.
Path parameters
| Name | Type | Description |
|---|---|---|
idrequired | string | Project UUID (from GET /projects). |
Query parameters
| Name | Type | Description |
|---|---|---|
baselineoptional | integer | Baseline slot to measure against, 0 to 10.Default: 0 |
Request
curl "https://www.flowrelay.it/api/v1/projects/3fa85f64-5717-4562-b3fc-2c963f66afa6/evm" \
-H "Authorization: Bearer fr_your_api_key"Response
{
"currency": "EUR",
"statusDate": "2026-09-29",
"baseline": 0,
"actualsFrom": "timesheets",
"plannedCostCents": 4820000,
"actualCostCents": 2130000,
"budgetCents": 5000000,
"earnedValue": {
"budgetAtCompletionCents": 4800000,
"plannedValueCents": 2400000,
"earnedValueCents": 2160000,
"actualCostCents": 2130000,
"scheduleVarianceCents": -240000,
"costVarianceCents": 30000,
"spi": 0.9,
"cpi": 1.01,
"tcpi": 0.99,
"estimateAtCompletionCents": {
"cpi": 4733000,
"budgetRate": 4770000,
"cpiSpi": 4818000
},
"estimateToCompleteCents": 2603000,
"varianceAtCompletionCents": 67000
},
"curve": [
{
"weekEnding": "2026-10-04",
"baselineCents": 2500000,
"currentCents": 2300000
}
],
"generatedFor": "2026-09-29"
}| Status | When |
|---|---|
| 200 | Success |
| 400 | The body or a query parameter is invalid: an unknown field, an unknown source, an unsupported filter dimension or an out-of-range number. The response names the offending field and lists the allowed values. |
| 401 | Missing or invalid API key. |
| 402 | Costs and earned value are not part of the plan (Business and above). |
| 403 | The key owner is not a manager of this project. |
| 404 | Project not found or not accessible by this key. |
| 429 | Rate limit exceeded (60/min/key). |
Forecast the finish of a plan
/projects/{id}/forecastSimulates the plan thousands of times and returns, for the project and for each open milestone, the dates by which half, four out of five and nineteen out of twenty of the runs are done, the chance of meeting the target finish or a milestone deadline and the items most often on the critical path. mode=schedule (default) varies the durations of the open tasks (uncertainty low, medium or high; tasks marked as estimates vary one step wider); mode=throughput uses how many items the team finished each week over the last twelve weeks and needs at least four weeks of history. The same plan version always gives the same forecast. Dates are wall-clock times in the plan time zone. Included from the Business plan. Costs no credits.
Path parameters
| Name | Type | Description |
|---|---|---|
idrequired | string | Project UUID (from GET /projects). |
Query parameters
| Name | Type | Description |
|---|---|---|
modeoptional | string | What to simulate.One of: schedule, throughputDefault: schedule |
uncertaintyoptional | string | How far durations may vary in schedule mode.One of: low, medium, highDefault: medium |
Request
curl "https://www.flowrelay.it/api/v1/projects/3fa85f64-5717-4562-b3fc-2c963f66afa6/forecast" \
-H "Authorization: Bearer fr_your_api_key"Response
{
"mode": "schedule",
"uncertainty": "medium",
"iterations": 2000,
"planVersion": 41,
"project": {
"plan": "2026-12-18T17:00",
"target": "2026-12-11T17:00",
"p50": "2026-12-22T17:00",
"p80": "2027-01-08T17:00",
"p95": "2027-01-20T17:00",
"chance": 0.18
},
"milestones": [
{
"id": "5f2d6a10-0e3b-4c7a-9d18-2b6c4e8f1a30",
"ref": "WEB-14",
"title": "Design freeze",
"plan": "2026-10-09T17:00",
"deadline": null,
"p50": "2026-10-12T17:00",
"p80": "2026-10-16T17:00",
"p95": "2026-10-23T17:00",
"chance": 0.31
}
],
"critical": [
{
"id": "8a1c3e5f-7b9d-4f20-8c41-6d5e4f3a2b10",
"ref": "WEB-7",
"title": "Payment webhook",
"index": 0.92
}
],
"histogram": [
{
"from": "2026-12-15",
"to": "2026-12-19",
"count": 240
}
]
}| Status | When |
|---|---|
| 200 | Success |
| 400 | The body or a query parameter is invalid: an unknown field, an unknown source, an unsupported filter dimension or an out-of-range number. The response names the offending field and lists the allowed values. |
| 401 | Missing or invalid API key. |
| 402 | Forecasts are not part of the plan (Business and above). |
| 404 | Project not found or not accessible by this key. |
| 429 | Rate limit exceeded (60/min/key). |
Ask a what-if question about a plan
/projects/{id}/whatifTurns a what-if question written in words into changes to the work (set a duration, delay a start, cancel an item, add a link) and lets the scheduler compute the result: the new finish of the project and of each milestone, how many items move and what becomes critical. The model only maps the words to changes using the keys of the plan; every date comes from the scheduler. Whatever cannot be expressed is listed in left_out. Nothing is saved and the plan is not changed. Viewers cannot ask. Included from the Business plan. Costs 5 credits.
Path parameters
| Name | Type | Description |
|---|---|---|
idrequired | string | Project UUID (from GET /projects). |
Body parameters
| Name | Type | Description |
|---|---|---|
questionrequired | string | The what-if question, 5 to 500 characters. |
Request
curl "https://www.flowrelay.it/api/v1/projects/3fa85f64-5717-4562-b3fc-2c963f66afa6/whatif" \
-H "Authorization: Bearer fr_your_api_key" \
-X POST \
-H "Content-Type: application/json" \
-d '{ "question": "What if the payment integration takes three weeks longer?" }'Request body
{
"question": "What if the payment integration takes three weeks longer?"
}Response
{
"explanation": "Made WEB-7 three weeks long, assuming the current dependencies.",
"changes": [
"Set WEB-7 to 3w"
],
"left_out": [],
"comparison": {
"projectFinish": {
"now": "2026-12-18T17:00",
"scenario": "2027-01-08T17:00",
"deltaWorkingDays": 15
},
"milestones": [
{
"ref": "WEB-14",
"title": "Design freeze",
"now": "2026-10-09T17:00",
"scenario": "2026-10-30T17:00",
"deltaWorkingDays": 15
}
],
"moved": 4,
"criticalBecame": 1,
"criticalLeft": 0,
"warnings": 0
},
"errors": []
}| Status | When |
|---|---|
| 200 | Success |
| 400 | The body or a query parameter is invalid: an unknown field, an unknown source, an unsupported filter dimension or an out-of-range number. The response names the offending field and lists the allowed values. |
| 401 | Missing or invalid API key. |
| 402 | Scenarios are not part of the plan (Business and above), or the plan is out of credits. |
| 403 | The key owner is a viewer of this project. |
| 404 | Project not found or not accessible by this key. |
| 504 | The answer took longer than 60 seconds. |
| 429 | Rate limit exceeded (60/min/key). |
Get the portfolio of an organization
/portfolioReturns the projects of an organization that the key owner can open, each with its progress, forecast finish, next milestone, open risks and health. Health is a verdict (green, amber or red) computed every night from the plan: schedule slip against the baseline or the target finish, overdue items, scope added since the baseline and the latest build, deploy and incident signals. A project manager can set the verdict by hand, and then overridden is true with the comment. Costs are not included here: use GET /projects/{id}/evm. Included from the Business plan. Costs no credits.
Query parameters
| Name | Type | Description |
|---|---|---|
organization_idrequired | string | Organization UUID (from GET /projects, the organizationId of a project). |
Request
curl "https://www.flowrelay.it/api/v1/portfolio?organization_id=ORGANIZATION_ID" \
-H "Authorization: Bearer fr_your_api_key"Response
{
"organizationId": "4b1f0c6e-2a3d-4e5f-8a9b-0c1d2e3f4a5b",
"projects": [
{
"id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"key": "WEB",
"name": "Website relaunch",
"status": "active",
"programId": null,
"percentComplete": 62,
"projectStart": "2026-08-03T08:00",
"scheduledFinish": "2026-12-18T17:00",
"targetFinish": "2026-12-11T17:00",
"openRisks": 3,
"nextMilestone": {
"ref": "WEB-14",
"title": "Design freeze",
"finish": "2026-10-09T17:00"
},
"health": {
"verdict": "amber",
"overridden": false,
"comment": null,
"schedule": "amber",
"cost": null,
"scope": "green",
"delivery": "green",
"computedOn": "2026-09-29",
"slipWorkingDays": 5,
"overdueItems": 2,
"openItems": 31
}
}
],
"programs": [
{
"id": "2f6b1d0e-9a8b-4c7d-8e6f-5a4b3c2d1e0f",
"name": "Growth"
}
],
"dependencies": [
{
"from": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"to": "0d3b5a7c-1e2f-4a6b-9c8d-7e6f5a4b3c2d",
"count": 2
}
]
}| Status | When |
|---|---|
| 200 | Success |
| 400 | The body or a query parameter is invalid: an unknown field, an unknown source, an unsupported filter dimension or an out-of-range number. The response names the offending field and lists the allowed values. |
| 401 | Missing or invalid API key. |
| 402 | The organization plan does not include portfolio management (Business and above). |
| 404 | Organization not found or the key owner is not a member. |
| 429 | Rate limit exceeded (60/min/key). |
List the RAID register
/projects/{id}/raidReturns the risks, assumptions, issues, decisions and dependencies of a project, highest number first. Entries that are not closed by default. The score is probability times impact, present on risks and issues.
Path parameters
| Name | Type | Description |
|---|---|---|
idrequired | string | Project UUID (from GET /projects). |
Query parameters
| Name | Type | Description |
|---|---|---|
kindoptional | string | Filter by type.One of: risk, assumption, issue, decision, dependency |
statusoptional | string | Filter by status. Omit for every entry that is not closed.One of: open, monitoring, closed, all |
limitoptional | integer | Max records to return (1-200, default 50).Default: 50 |
Request
curl "https://www.flowrelay.it/api/v1/projects/3fa85f64-5717-4562-b3fc-2c963f66afa6/raid" \
-H "Authorization: Bearer fr_your_api_key"Response
{
"entries": [
{
"id": "9d8c7b6a-5f4e-4d3c-8b2a-1f0e9d8c7b6a",
"number": 4,
"type": "risk",
"title": "Payment provider certification may slip",
"description": "",
"status": "open",
"probability": 3,
"impact": 5,
"score": 15,
"response": "Book the certification slot now.",
"ownerId": null,
"dueOn": "2026-10-16",
"item": "FR-12",
"createdAt": "2026-09-28T09:10:00Z"
}
]
}| Status | When |
|---|---|
| 200 | Success |
| 400 | The body or a query parameter is invalid: an unknown field, an unknown source, an unsupported filter dimension or an out-of-range number. The response names the offending field and lists the allowed values. |
| 401 | Missing or invalid API key. |
| 404 | Project not found or not accessible by this key. |
| 429 | Rate limit exceeded (60/min/key). |
List the automation rules of a project
/projects/{id}/automationsReturns the automation rules of a project: each with a plain sentence that says what starts it, what it checks and what it does, its trigger, conditions and actions as stored, how many times it ran and how the last run went. Read only: rules are changed in the app. Available from the Team plan. Costs no credits.
Path parameters
| Name | Type | Description |
|---|---|---|
idrequired | string | Project UUID (from GET /projects). |
Request
curl "https://www.flowrelay.it/api/v1/projects/3fa85f64-5717-4562-b3fc-2c963f66afa6/automations" \
-H "Authorization: Bearer fr_your_api_key"Response
{
"automations": [
{
"id": "5c4b3a29-1807-4f6e-9d5c-4b3a2918f7e6",
"name": "Close out",
"enabled": true,
"summary": "When an item moves to Done, and priority is at least High: notify the assignees.",
"trigger": {
"type": "status_changed",
"to": "done"
},
"conditions": [
{
"field": "priority",
"op": "gte",
"value": 3
}
],
"actions": [
{
"type": "notify",
"to": "assignees",
"message": "{{key}} is done"
}
],
"runCount": 12,
"lastRunAt": "2026-10-08T14:20:00Z",
"lastStatus": "ok"
}
]
}| Status | When |
|---|---|
| 200 | Success |
| 401 | Missing or invalid API key. |
| 404 | Project not found or not accessible by this key. |
| 429 | Rate limit exceeded (60/min/key). |
List the plan templates of a project
/projects/{id}/templatesReturns the templates saved for the project: those of its organization, or your own on a personal project. A template is a whole plan or one item with its subtasks, kept as names, notes, durations and links, never people or dates. Costs no credits.
Path parameters
| Name | Type | Description |
|---|---|---|
idrequired | string | Project UUID (from GET /projects). |
Request
curl "https://www.flowrelay.it/api/v1/projects/3fa85f64-5717-4562-b3fc-2c963f66afa6/templates" \
-H "Authorization: Bearer fr_your_api_key"Response
{
"templates": [
{
"id": "7e6d5c4b-3a29-4180-b6f5-e4d3c2b1a098",
"kind": "item",
"name": "Release checklist",
"description": "Steps before a release",
"itemCount": 6,
"createdAt": "2026-09-20T09:00:00Z"
}
]
}| Status | When |
|---|---|
| 200 | Success |
| 401 | Missing or invalid API key. |
| 404 | Project not found or not accessible by this key. |
| 429 | Rate limit exceeded (60/min/key). |
Add a template to a plan
/projects/{id}/templates/{templateId}/applyAdds the items of a template to the plan, at the top level or under an existing item, as one change that the history can undo. Only project managers can. Costs no credits.
Path parameters
| Name | Type | Description |
|---|---|---|
idrequired | string | Project UUID (from GET /projects). |
templateIdrequired | string | Template UUID (from GET /projects/{id}/templates). |
Body parameters
| Name | Type | Description |
|---|---|---|
parentoptional | string | Key or id of the item to add the template under. Omit for the top level. |
Request
curl "https://www.flowrelay.it/api/v1/projects/3fa85f64-5717-4562-b3fc-2c963f66afa6/templates/7e6d5c4b-3a29-4180-b6f5-e4d3c2b1a098/apply" \
-H "Authorization: Bearer fr_your_api_key" \
-X POST \
-H "Content-Type: application/json" \
-d '{ "parent": "FR-12" }'Request body
{
"parent": "FR-12"
}Response
{
"created": 6,
"version": 42
}| Status | When |
|---|---|
| 201 | Items created and scheduled. |
| 400 | The body or a query parameter is invalid: an unknown field, an unknown source, an unsupported filter dimension or an out-of-range number. The response names the offending field and lists the allowed values. |
| 401 | Missing or invalid API key. |
| 402 | Work management is not part of the plan, or the project reached its item limit. |
| 403 | The key owner is not a manager of the project. |
| 404 | Project, template or parent item not found or not accessible by this key. |
| 409 | The plan kept changing while the items were saved. Retry. |
| 429 | Rate limit exceeded (60/min/key). |
List the change requests of a project
/projects/{id}/approvalsReturns the last 50 change requests of an organization project: what was asked in plain language, who asked, who decided and when. Change requests are included from the Business plan; on a personal project or a plan without them the list is empty. Costs no credits.
Path parameters
| Name | Type | Description |
|---|---|---|
idrequired | string | Project UUID (from GET /projects). |
Query parameters
| Name | Type | Description |
|---|---|---|
statusoptional | string | Use pending to list only the requests waiting for a decision.One of: pending |
Request
curl "https://www.flowrelay.it/api/v1/projects/3fa85f64-5717-4562-b3fc-2c963f66afa6/approvals" \
-H "Authorization: Bearer fr_your_api_key"Response
{
"approvals": [
{
"id": "2c1b0a9f-8e7d-4c6b-9a5f-4e3d2c1b0a9f",
"kind": "scope",
"title": "Move the launch by one week",
"note": "The vendor needs another week.",
"summary": [
"Change duration of FR-12 \"Launch\""
],
"status": "pending",
"requestedBy": "Ada Lovelace",
"decidedBy": null,
"decidedAt": null,
"decisionNote": null,
"createdAt": "2026-09-28T09:00:00Z"
}
]
}| Status | When |
|---|---|
| 200 | Success |
| 401 | Missing or invalid API key. |
| 404 | Project not found or not accessible by this key. |
| 429 | Rate limit exceeded (60/min/key). |
Ask for a change to a work item
/projects/{id}/approvalsCreates a change request for one work item. A second person decides it in the plan, and approving applies the change as the approver. Use it when the key owner may not make the change directly, or wants it reviewed. Changes use the same fields as PATCH on a work item. Organization projects on the Business plan or above only. Costs no credits.
Path parameters
| Name | Type | Description |
|---|---|---|
idrequired | string | Project UUID (from GET /projects). |
Body parameters
| Name | Type | Description |
|---|---|---|
itemrequired | string | Key such as FR-12 or id of the work item. |
titlerequired | string | What you want changed, 1 to 200 characters. |
noteoptional | string | Why, up to 2,000 characters. |
changesrequired | object | The fields to change: title, description, status, priority, blocked, percentComplete, duration or deadline. |
Request
curl "https://www.flowrelay.it/api/v1/projects/3fa85f64-5717-4562-b3fc-2c963f66afa6/approvals" \
-H "Authorization: Bearer fr_your_api_key" \
-X POST \
-H "Content-Type: application/json" \
-d '{ "item": "FR-12", "title": "Move the launch by one week", "note": "The vendor needs another week.", "changes": { "duration": "6d" } }'Request body
{
"item": "FR-12",
"title": "Move the launch by one week",
"note": "The vendor needs another week.",
"changes": {
"duration": "6d"
}
}Response
{
"id": "2c1b0a9f-8e7d-4c6b-9a5f-4e3d2c1b0a9f",
"status": "pending"
}| Status | When |
|---|---|
| 201 | Request created and the approvers notified. |
| 400 | The body or a query parameter is invalid: an unknown field, an unknown source, an unsupported filter dimension or an out-of-range number. The response names the offending field and lists the allowed values. |
| 401 | Missing or invalid API key. |
| 402 | Change approvals are not part of the plan. |
| 403 | The key owner cannot change this plan, or the change touches a field the key owner may not see. |
| 404 | Project or item not found or not accessible by this key. |
| 409 | The key owner has too many requests waiting for a decision. |
| 429 | Rate limit exceeded (60/min/key). |
Decide a change request
/projects/{id}/approvals/{approvalId}Approves or rejects a pending change request, or withdraws one you made. Approving applies the change as the approver and reschedules the plan. A request needs a second person: the key owner cannot approve or reject a request they made. Costs no credits.
Path parameters
| Name | Type | Description |
|---|---|---|
idrequired | string | Project UUID (from GET /projects). |
approvalIdrequired | string | Change request UUID (from GET /projects/{id}/approvals). |
Body parameters
| Name | Type | Description |
|---|---|---|
decisionrequired | string | What to do with the request. Only the person who asked can withdraw.One of: approve, reject, withdraw |
noteoptional | string | Why, up to 1,000 characters. |
Request
curl "https://www.flowrelay.it/api/v1/projects/3fa85f64-5717-4562-b3fc-2c963f66afa6/approvals/approvalId" \
-H "Authorization: Bearer fr_your_api_key" \
-X PATCH \
-H "Content-Type: application/json" \
-d '{ "decision": "approve", "note": "Fine by me." }'Request body
{
"decision": "approve",
"note": "Fine by me."
}Response
{
"status": "approved",
"batchId": "5d4c3b2a-1f0e-4d9c-8b7a-6f5e4d3c2b1a"
}| Status | When |
|---|---|
| 200 | Request decided. `status` is approved, rejected or withdrawn. |
| 400 | The body or a query parameter is invalid: an unknown field, an unknown source, an unsupported filter dimension or an out-of-range number. The response names the offending field and lists the allowed values. |
| 401 | Missing or invalid API key. |
| 402 | Change approvals are not part of the plan. |
| 403 | The key owner cannot decide change requests, asked for this one, or tried to withdraw a request made by someone else. |
| 404 | Project or request not found or not accessible by this key. |
| 409 | The request is no longer pending, was decided in the meantime, or applying it failed (`status` is failed). |
| 429 | Rate limit exceeded (60/min/key). |
Add a RAID entry
/projects/{id}/raidAdds a risk, assumption, issue, decision or dependency to the register of a project. Viewers cannot add. Probability and impact are 1 to 5. Costs no credits.
Path parameters
| Name | Type | Description |
|---|---|---|
idrequired | string | Project UUID (from GET /projects). |
Body parameters
| Name | Type | Description |
|---|---|---|
kindrequired | string | Type of the entry.One of: risk, assumption, issue, decision, dependency |
titlerequired | string | 1 to 300 characters. |
descriptionoptional | string | Up to 10,000 characters. |
probabilityoptional | integer | 1 to 5, for risks and issues. |
impactoptional | integer | 1 to 5, for risks and issues. |
responseoptional | string | The planned response, or for a decision what was decided and why. |
statusoptional | string | Defaults to open.One of: open, monitoring, closed |
dueOnoptional | string | YYYY-MM-DD. |
Request
curl "https://www.flowrelay.it/api/v1/projects/3fa85f64-5717-4562-b3fc-2c963f66afa6/raid" \
-H "Authorization: Bearer fr_your_api_key" \
-X POST \
-H "Content-Type: application/json" \
-d '{ "kind": "risk", "title": "Payment provider certification may slip", "probability": 3, "impact": 5, "dueOn": "2026-10-16" }'Request body
{
"kind": "risk",
"title": "Payment provider certification may slip",
"probability": 3,
"impact": 5,
"dueOn": "2026-10-16"
}Response
{
"id": "9d8c7b6a-5f4e-4d3c-8b2a-1f0e9d8c7b6a",
"number": 4
}| Status | When |
|---|---|
| 201 | Entry added. |
| 400 | The body or a query parameter is invalid: an unknown field, an unknown source, an unsupported filter dimension or an out-of-range number. The response names the offending field and lists the allowed values. |
| 401 | Missing or invalid API key. |
| 403 | The key owner is a viewer of this project. |
| 404 | Project not found or not accessible by this key. |
| 429 | Rate limit exceeded (60/min/key). |
List project digests
/projects/{id}/digestsLists past scheduled activity digests for a project, newest first.
Path parameters
| Name | Type | Description |
|---|---|---|
idrequired | string | Project UUID. |
Query parameters
| Name | Type | Description |
|---|---|---|
limitoptional | integer | Max records to return (1-50, default 10).Default: 10 |
Request
curl "https://www.flowrelay.it/api/v1/projects/3fa85f64-5717-4562-b3fc-2c963f66afa6/digests" \
-H "Authorization: Bearer fr_your_api_key"Response
{
"digests": [
{
"id": "7c9e3b12-4567-89ab-cdef-0123456789ab",
"projectId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"generatedBy": "11111111-2222-3333-4444-555555555555",
"periodStart": "2026-07-17T00:00:00Z",
"periodEnd": "2026-07-24T00:00:00Z",
"content": {
"title": "Weekly Digest",
"summary": "Major progress on API v1 and checkout flow."
},
"markdown": "# Weekly Digest\n...",
"createdAt": "2026-07-24T00:00:05Z"
}
]
}| Status | When |
|---|---|
| 200 | Success |
| 401 | Missing or invalid API key. |
| 429 | Rate limit exceeded (60/min/key). |
| 404 | Project not found or not accessible by this key. |