Skip to main content
Fireweave exposes two HTTP planes. They take different keys and they do different work. Mixing them up is the most common integration error.

Two planes

Runtime plane

Your application SDKs call these three paths with a project runtime key (project-api-key_…) or a browser-safe fw_public_… key: These paths are not in the management OpenAPI spec. They are served on a separate runtime-proxy path. This page does not re-document them. See Configuration, Adapters, and the SDK pages.

Management plane

This page. Authenticated with an org API key (fw_org_…) or a CLI user session. Use it to list and manage projects and environments, and to read merge-registered control points. Default base URL: https://app-server.fireweave.ai (same host fw login --cloud uses). Staging: https://staging-app-server.fireweave.ai.
An org key is not a project runtime key. Do not put fw_org_… in an SDK adapter, and do not send FW_PROJECT_API_KEY here. Terraform reads the same org-key family as FIREWEAVE_API_KEY — see Terraform authentication.
org:management can call every route on this page. org:ci-read cannot — that scope exists for fw sync only. Mint the matching scope when you create the key. Missing or invalid Authorization returns 401. Cross-org probes return 404 (or an empty list on control-point reads), not 403.
The request and response shapes below are documented from the server’s route handlers. Fireweave’s published OpenAPI description currently lists paths and summaries only, so treat these pages as the more complete reference until it emits full schemas.

GET /v1/whoami

Return the session implied by the bearer token.

Projects

Org id is always taken from the verified session.

GET /v1/projects

List projects the organisation owns.
List items do not include description or status. Use GET /v1/projects/{projectId} for the full row.

POST /v1/projects

Create a project. 201 on success.
201 body:
409 { "error": { "code": "CONFLICT", "message": "A project with this slug already exists" } } when the slug is taken.

GET /v1/projects/{projectId}

Return one project. 404 { "error": { "code": "NOT_FOUND", "message": "Project not found" } } if the id is missing or belongs to another org. The project object matches the create response: projectId, name, slug, description, status (active | archived), createdAt, updatedAt.

PATCH /v1/projects/{projectId}

Update name, description, and/or status. Slug is not writable here.
All body fields are optional. Returns { "project": { … } }.

DELETE /v1/projects/{projectId}

Environments

A project environment is a named stage in the promotion pipeline (dev, stage, prod, …). Ref-rule object used by branchRules and tagRules:

GET /v1/projects/{projectId}/environments

List environments, favourites first, then by recency / promotion rank. When the registry is empty, the server returns a single synthesised production placeholder.
This list shape is not the same as the create/get/update row. It has no envId and no webhookAliases. It does include readiness, synthesised, and last-seen deploy fields.

POST /v1/projects/{projectId}/environments

Create an environment. 201 on success. Slug is trimmed and lowercased. The first environment in an empty project defaults isDefault to true unless you pass the field.
201 body { "environment": { … } } uses the management row: 409 if the slug already exists. 404 if the project is missing or cross-org.

GET /v1/projects/{projectId}/environments/{envId}

Return one environment as { "environment": { … } }. 404 for a missing project, missing env, or cross-org id.

PATCH /v1/projects/{projectId}/environments/{envId}

Updatable fields: displayName, branchRules, tagRules, webhookAliases, isDefault. Slug is not writable. Returns { "environment": { … } }.

DELETE /v1/projects/{projectId}/environments/{envId}

Control points

These reads return every control point the project’s merges have registered. They are not the SDK evaluate API. Ramps do not read the graph edges — the graph is informational. Org is taken from the session. A project in another organisation reads as empty, not 404. Response envelope: { "success": true, "data": { … } }. orgId is stripped from each row on the wire.

GET /v1/projects/{projectId}/control-points

One row per anchor key, with the merge that introduced it and the latest merge that still anchors it.
Rows exist only after a merge has registered them. An empty list is normal for a project that has never gone through that path.

GET /v1/projects/{projectId}/control-points/graph

Nodes plus every recorded dependency edge.
nodes use the same row shape as the list endpoint. edges:
Nothing that ramps a release reads these edges. Treat the graph as history for later decisions, not as a live dependency lock.

Errors

Management writes use a small envelope:

What this page does not cover

These surfaces exist on the server and are deliberately omitted here: If you need a route that is not listed above, it is not part of the documented external contract.

Next

CLI authentication

fw login and FW_ORG_API_KEY.

Terraform

Manage projects and environments as code with the same org key.

SDK configuration

Runtime keys for evaluate, capture, and register.

Control points

What a control point is in application code.
Last modified on September 11, 2026