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.

Download OpenAPIImport openapi.json into Postman or Insomnia to generate a client.

List accessible projects

GET/projects

Returns the tenant context for the key owner: account type, organization memberships, and every personal or organization project the key can access (role-scoped).

Request

curl "https://www.flowrelay.it/api/v1/projects" \
  -H "Authorization: Bearer fr_your_api_key"

Response

JSON
{
  "account_type": "business",
  "organizations": [
    {
      "id": "org_3f2a",
      "name": "Acme",
      "slug": "acme",
      "role": "admin",
      "is_temporary_admin": false
    }
  ],
  "projects": [
    {
      "id": "proj_8c1d",
      "name": "Payments",
      "slug": "payments",
      "description": "Billing and checkout",
      "organization_id": "org_3f2a",
      "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"
    }
  ]
}
StatusWhen
200Success
401Missing or invalid API key.
429Rate limit exceeded (60/min/key).

List handoffs

GET/handoffs

Lists handoffs across accessible projects, newest first. Without project_id it spans every project the key can access.

Query parameters

NameTypeDescription
statusoptionalstringFilter by status.One of: active, archived, allDefault: active
limitoptionalintegerMaximum rows to return (1–100).Default: 20
project_idoptionalstringRestrict to a single project.

Request

curl "https://www.flowrelay.it/api/v1/handoffs" \
  -H "Authorization: Bearer fr_your_api_key"

Response

JSON
{
  "handoffs": [
    {
      "id": "ho_1a2b",
      "project_id": "proj_8c1d",
      "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"
      ],
      "related_event_ids": [
        "ev_44ff"
      ],
      "scope_type": "project",
      "project_name": "Payments",
      "created_at": "2026-06-20T14:03:00Z",
      "updated_at": "2026-06-20T14:03:00Z"
    }
  ]
}
StatusWhen
200Success
401Missing or invalid API key.
404Project not found or not accessible by this key.

Generate a handoff

POST/handoffs

Asynchronous – 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

NameTypeDescription
project_idrequiredstringProject to generate the handoff for.
sourcesoptionalstring[]Restrict generation to these sources (e.g. ["github","slack"]).
filtersoptionalSourceFilterPer-source projects / eventTypes / branches / priorities (AND-combined).

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": "proj_8c1d", "sources": [ "github", "linear" ], "filters": { "github": { "branches": [ "main" ] } } }'

Request body

JSON
{
  "project_id": "proj_8c1d",
  "sources": [
    "github",
    "linear"
  ],
  "filters": {
    "github": {
      "branches": [
        "main"
      ]
    }
  }
}

Response

JSON
{
  "jobId": "job_9f3c",
  "status": "pending"
}
StatusWhen
202Job enqueued. Poll GET /jobs/{jobId} for the result.
400project_id is missing.
401Missing or invalid API key.
404Project not found or not accessible by this key.
429Rate limit exceeded (60/min/key).

List selectable filter options

GET/handoffs/filters

Returns the real selectable filter values per connected source for a project: resources (repos / channels / boards), branches, event types, and priorities. Use these to build a valid SourceFilter instead of guessing.

Query parameters

NameTypeDescription
project_idrequiredstringProject 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

JSON
{
  "filters": {
    "github": {
      "projects": [
        {
          "id": "acme/payments",
          "label": "acme/payments"
        }
      ],
      "eventTypes": [
        {
          "value": "push",
          "label": "Push"
        }
      ],
      "priorities": [],
      "branches": [
        {
          "value": "main",
          "label": "main"
        }
      ]
    },
    "linear": {
      "projects": [
        {
          "id": "team_x",
          "label": "Core"
        }
      ],
      "eventTypes": [
        {
          "value": "issue",
          "label": "Issue"
        }
      ],
      "priorities": [
        {
          "value": "high",
          "label": "High"
        }
      ]
    }
  }
}
StatusWhen
200Success
400project_id is missing.
401Missing or invalid API key.
404Project not found or not accessible by this key.

List project insights

GET/projects/{id}/insights

Lists AI insights for a project, newest first. Optionally filter by kind and status.

Path parameters

NameTypeDescription
idrequiredstringProject id.

Query parameters

NameTypeDescription
kindoptionalstringFilter by insight kind.One of: cross_source_correlation, onboarding_brief, architecture_insight
statusoptionalstringFilter by status.One of: active, archived, allDefault: active
limitoptionalintegerMaximum rows to return (1–100).Default: 20

Request

curl "https://www.flowrelay.it/api/v1/projects/PROJECT_ID/insights" \
  -H "Authorization: Bearer fr_your_api_key"

Response

JSON
{
  "insights": [
    {
      "id": "ins_7b2e",
      "project_id": "proj_8c1d",
      "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-2.5-flash",
      "status": "active",
      "related_event_ids": [
        "ev_44ff"
      ],
      "created_at": "2026-06-21T08:00:00Z",
      "updated_at": "2026-06-21T08:00:00Z"
    }
  ]
}
StatusWhen
200Success
401Missing or invalid API key.
404Project not found or not accessible by this key.

Generate an insight

POST/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

NameTypeDescription
idrequiredstringProject id.
kindrequiredstringInsight kind.One of: correlation, onboarding, architecture

Body parameters

NameTypeDescription
lookbackHoursoptionalintegercorrelation only – window in hours (default 168).
lookbackDaysoptionalintegeronboarding / architecture – window in days (30 / 14 default).
newMemberRoleoptionalstringonboarding only – role of the person being onboarded.
focusAreaoptionalstringonboarding only – area to emphasise.
focusQuestionoptionalstringarchitecture only – the question to investigate.
sourcesoptionalstring[]Restrict to these sources.
filtersoptionalSourceFilterPer-source filters (AND-combined).
maxEventsoptionalintegerCap the events fed to the model.

Request

curl "https://www.flowrelay.it/api/v1/projects/PROJECT_ID/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

JSON
{
  "focusQuestion": "Is the pricing engine coupling billing to providers?",
  "lookbackDays": 14
}

Response

JSON
{
  "jobId": "job_2d4a",
  "status": "pending"
}
StatusWhen
202Job enqueued. Poll GET /jobs/{jobId} for the result.
400Unsupported insight kind.
401Missing or invalid API key.
404Project not found or not accessible by this key.
429Rate limit exceeded (60/min/key).

List context events

GET/events

Lists 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

NameTypeDescription
sourceoptionalstringFilter by source (e.g. github, slack, linear).
limitoptionalintegerMaximum rows to return (1–200).Default: 50
project_idoptionalstringRestrict to a project scope.

Request

curl "https://www.flowrelay.it/api/v1/events" \
  -H "Authorization: Bearer fr_your_api_key"

Response

JSON
{
  "events": [
    {
      "id": "ev_44ff",
      "user_id": "usr_1",
      "source": "github",
      "event_type": "push",
      "title": "Push to acme/payments",
      "content": "3 commits on main",
      "created_at": "2026-06-20T13:55:00Z"
    }
  ]
}
StatusWhen
200Success
401Missing or invalid API key.
404Project not found or not accessible by this key.

List integrations

GET/integrations

Lists 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

NameTypeDescription
project_idoptionalstringReturn project-scoped integrations instead of personal ones.

Request

curl "https://www.flowrelay.it/api/v1/integrations" \
  -H "Authorization: Bearer fr_your_api_key"

Response

JSON
{
  "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"
    }
  ]
}
StatusWhen
200Success
401Missing or invalid API key.
404Project not found or not accessible by this key.

List untracked resources

GET/integrations/untracked

Returns 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

JSON
[
  {
    "source": "slack",
    "resource_id": "C0123",
    "resource_name": "#incidents",
    "resource_type": "channel",
    "event_count": 42,
    "last_event_at": "2026-06-20T12:00:00Z"
  }
]
StatusWhen
200Success
401Missing or invalid API key.
500Discovery failed for a connected source.

Poll an async job

GET/jobs/{jobId}

Returns the job record and, once completed, the generated artifact (handoff or insight). Poll this after any 202 response until status is completed or failed.

Path parameters

NameTypeDescription
jobIdrequiredstringJob id from a 202 response.

Request

curl "https://www.flowrelay.it/api/v1/jobs/JOB_ID" \
  -H "Authorization: Bearer fr_your_api_key"

Response

JSON
{
  "job": {
    "id": "job_9f3c",
    "project_id": "proj_8c1d",
    "kind": "project_handoff",
    "status": "completed",
    "result_kind": "handoff",
    "result_id": "ho_1a2b",
    "error": null,
    "error_code": null,
    "created_at": "2026-06-20T14:02:00Z",
    "updated_at": "2026-06-20T14:03:00Z"
  },
  "result": {
    "id": "ho_1a2b",
    "title": "Checkout refactor handoff"
  }
}
StatusWhen
200Success
401Missing or invalid API key.
404Job not found or not accessible.

List Discord channels

GET/discord/channels

Lists 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

JSON
{
  "channels": [
    {
      "id": "987654",
      "name": "general",
      "type": 0
    }
  ]
}
StatusWhen
200Success
401Missing or invalid API key.
404Discord not connected.
400No guild associated with this integration.

Send a Discord message

POST/discord/send

Sends a message to a channel in the connected guild. The channel must belong to that guild (cross-tenant posts are rejected).

Body parameters

NameTypeDescription
channel_idrequiredstringTarget channel id.
contentrequiredstringMessage text.

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": "987654", "content": "Handoff ready" }'

Request body

JSON
{
  "channel_id": "987654",
  "content": "Handoff ready"
}

Response

JSON
{
  "ok": true,
  "message_id": "111222333"
}
StatusWhen
200Success
400channel_id and content are required.
401Missing or invalid API key.
403Channel does not belong to the connected guild.
404Discord not connected.