---
name: buildspace-api
status: available
description: Buildspace API for managed agents — onboard, authenticate, create/list/update applications — plus an embedded MCP endpoint (`/api/v1/mcp`) for AI clients (Cursor, Claude Desktop, fleet agents).
---

# Buildspace API

Use this when a managed agent needs to work in Buildspace.

For the shared managed-agent identity lifecycle, see `auth/agent/SKILL.md`.
Use the live OpenAPI document for full route schemas:

```bash
curl "$BUILDSPACE_API/api/docs/openapi"
```

## Tokens

- `agentCredential`: persistent managed-agent credential from BIO Authentication.
  Store it securely and reuse it across BIO verticals.
  This is the agent's account key; reuse the same value for future sessions so
  the agent keeps access to its existing Buildspace account and content.
- `AUTH_TOKEN`: fresh upstream token from `id-api`.
- `BUILDSPACE_BEARER`: Buildspace-local bearer returned by
  `/api/v1/auth/authenticate`.

Use `BUILDSPACE_BEARER` for protected Buildspace routes.

## Quickstart

```bash
ID_API=https://api.id.bio.xyz
BUILDSPACE_API=https://api-buildspace.bio.xyz
DISPLAY_NAME="Buildspace Agent"
DESCRIPTION="Agent that works with Buildspace applications."

# 1. Exchange the persistent credential for a fresh upstream token.
AUTH_TOKEN=$(curl -sS -X POST "$ID_API/api/v1/auth/agent/token" \
  -H "Content-Type: application/json" \
  -d '{ "agentCredential": "<stored-agentCredential>" }' | jq -r '.data.token')

# 2. Project the agent into Buildspace.
curl -sS -X POST "$BUILDSPACE_API/api/v1/auth/agent/onboard" \
  -H "Content-Type: application/json" \
  -d '{
    "agentCredential": "<stored-agentCredential>",
    "displayName": "'"$DISPLAY_NAME"'",
    "description": "'"$DESCRIPTION"'"
  }'

# 3. Exchange the upstream token for a Buildspace bearer.
BUILDSPACE_BEARER=$(curl -sS -X POST "$BUILDSPACE_API/api/v1/auth/authenticate" \
  -H "Authorization: Bearer $AUTH_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{}' | jq -r '.access_token')
```

## Work With Applications

```bash
# List accessible applications.
curl -sS "$BUILDSPACE_API/api/v1/application" \
  -H "Authorization: Bearer $BUILDSPACE_BEARER"

# Create a new application.
# `project_type` is required (`AI Agent`, `IPT`, `BioDAO`, or `Other`).
# Do not send remaining admin-only fields (`state`, `final_decision`,
# `launch_date`, `track`, `decision_date`). DB defaults apply
# (`state=building`, `final_decision=submitted`).
curl -sS -X POST "$BUILDSPACE_API/api/v1/application/new" \
  -H "Authorization: Bearer $BUILDSPACE_BEARER" \
  -H "Content-Type: application/json" \
  -d '{
    "project_name": "Agent-created project",
    "project_type": "AI Agent",
    "description": "Created through the managed-agent Buildspace flow.",
    "email": "agent@example.bio"
  }'

# Partially update an application.
curl -sS -X PATCH "$BUILDSPACE_API/api/v1/application/$APPLICATION_ID" \
  -H "Authorization: Bearer $BUILDSPACE_BEARER" \
  -H "Content-Type: application/json" \
  -d '{ "description": "Updated by a managed agent." }'
```

Use `PATCH /api/v1/application/{id}` for small edits. Use `GET
/api/v1/application/{id}` to verify the saved state.

Admin-only application fields (rejected for agents and non-admin users on
PATCH/PUT; `project_type` is required on create, locked afterwards):
- Launch status: `state` (`building`, `pending_launch`, `upcoming`, …)
- Intake decision: `final_decision` (`submitted`, `accepted`, `rejected`,
  `withdrawn`) and `decision_date`
- Schedule / curation: `launch_date`, `track`
- Asset type after create: `project_type` (required on
  `POST /application/new` and MCP `create_application`; PATCH/PUT remain
  admin-only)
- Admin tokenomics keys under `launch_parameters`

Exceptions (do not use generic PATCH/PUT for these):
- Submit for launch review: MCP `submit_launch_request` (same as
  `POST /api/v1/application/{id}/launch-request`)
- Admin intake decision: `PATCH /api/v1/application/{id}/decision`
- Link a Molecule Onchain Lab: `POST /api/v1/application/{id}/molabs` (see
  **Link A Molecule Onchain Lab**). `launch_parameters.ocl_id` is not writable
  through PATCH.
- UI onboarding create: `POST /api/v1/signup` (also requires `project_type`)
- Take write fields from the request schemas in
  `$BUILDSPACE_API/api/docs/openapi` or
  `@bio-xyz/buildspace-api-contract` — both withhold the admin-only fields.
  Never copy write fields from a response body or example: responses carry the
  admin fields you cannot send.

## Link A Molecule Onchain Lab

The **Set Up Lab** task starts when an application has
`molabs_setup.pending_ocl_id` (lab chosen or minted for registration) and
completes when registration persists `launch_parameters.ocl_id`. Agents can skip
the pending step and go straight to `POST /molabs` — `ocl_id` alone completes the
task and counts toward 100% launch readiness. Linking proves the agent's wallet
owns the LabNFT, so it needs a wallet signature — not just a bearer token.

`WALLET_ADDRESS` must be a wallet linked to the agent's own Privy identity;
every route below rejects an address the caller does not control.

```bash
APPLICATION_ID=<application-id>
WALLET_ADDRESS=<0x-address-linked-to-this-agent>

# 1. Discover which labs the wallet owns and which of them can be linked.
curl -sS "$BUILDSPACE_API/api/v1/application/$APPLICATION_ID/molabs/owned-labs?walletAddress=$WALLET_ADDRESS" \
  -H "Authorization: Bearer $BUILDSPACE_BEARER"

# 2. Fetch a challenge and sign it with the wallet (EIP-191 personal_sign).
MESSAGE=$(curl -sS "$BUILDSPACE_API/api/v1/application/$APPLICATION_ID/molabs/sign-in-message?walletAddress=$WALLET_ADDRESS" \
  -H "Authorization: Bearer $BUILDSPACE_BEARER" | jq -r '.data.message')

# 3. Link the lab.
curl -sS -X POST "$BUILDSPACE_API/api/v1/application/$APPLICATION_ID/molabs" \
  -H "Authorization: Bearer $BUILDSPACE_BEARER" \
  -H "Content-Type: application/json" \
  -d '{
    "oclId": "<0x-64-hex-lowercase>",
    "walletAddress": "'"$WALLET_ADDRESS"'",
    "messageSignature": "<signature-of-$MESSAGE>"
  }'
```

Pick a lab from step 1 using the annotations on each entry rather than guessing:

- `isLinkable` — safe to send to step 3.
- `blockedReason` — `agreement_not_signed` or `linked_to_other_application`.
- `agreementState` — `signed`, `needs_signature`, or `unknown`; use with `blockedReason` to decide whether signing is required before linking.
- `labUrl` — Molecule Labs page; where the owner signs the assignment agreement.
- `isLinkedToThisApplication` — already done, nothing to do.

Agents cannot mint a new lab through this API: minting is a user-paid onchain
transaction. When the wallet owns no labs, hand off to a human with `labUrl`
from Molecule Labs instead of retrying.

Responses to expect from step 3:

- `201` — linked. `data.oclId`, `data.labShortname`, `data.labUrl`.
- `200` with `data.alreadyLinked: true` — this lab was already linked here. The
  call is idempotent, so a retry after a timeout is safe.
- `403` with `agreementState: "needs_signature"` — the owner must sign the
  assignment agreement at `labUrl` first, then retry.
- `403` — the wallet does not own the lab, or is not linked to this agent.
- `409` — another application already claims the lab. A lab backs one launch;
  pick a different lab.
- `400` — the signature did not yield a Molecule service token. Fetch a fresh
  message from step 2 and sign again; messages are short-lived.
- `502` — Molecule upstream failure. Retry with backoff.

## Reporting

Buildspace owns reporting for all Bio verticals. Use the Buildspace bearer
for `/api/v1/reporting/*`; machine credentials need `reporting:read` or
`reporting:write` for the requested operation. Human and agent access follows
entity membership. Buildspace application reporting also uses the existing
`/api/v1/application/{id}/reports` routes.

Use the live OpenAPI document for report, roadmap, activity and source
projection payloads. Keep existing report/entity IDs when updating records.

## MCP endpoint (fleet / Cursor / Claude)

Buildspace speaks the **Model Context Protocol** at
`POST/GET/DELETE https://api-buildspace.bio.xyz/api/v1/mcp` (Streamable HTTP, JSON responses —
not SSE). Same in-process product logic as REST; no separate MCP service.

| | |
| --- | --- |
| **URL** | `https://api-buildspace.bio.xyz/api/v1/mcp` |
| **Auth header** | `Authorization: Bearer <BUILDSPACE_BEARER>` **or** machine service token **or** MCP OAuth access token |
| **Discovery** | `https://api-buildspace.bio.xyz/.well-known/oauth-protected-resource/api/v1/mcp` |
| **Authorization server** | `https://api-buildspace.bio.xyz/.well-known/oauth-authorization-server` |
| **Transport** | Stateless Streamable HTTP (fresh server per request; no session pinning) |
| **Accept (POST)** | `application/json, text/event-stream` — both, or **406** |
| **Protocol** | Negotiated at `initialize`; not a fixed server version |
| **OpenAPI** | Intentionally **absent** — JSON-RPC is not in `openapi.json` |
| **OAuth scope** | `buildspace` (presence-only; distinct from the machine-token scopes such as `applications:read`) |

Unauthenticated MCP calls return HTTP 401 with
`WWW-Authenticate: Bearer resource_metadata="<discovery URL>"`.
**OAuth 2.1 (DCR + PKCE) is the primary path for stock clients.**
Paste-bearer (session JWT or machine token as a static `Authorization`
header) remains a supported fallback.

### OAuth mode (no bearer to mint)

Give an OAuth-capable client the URL with **no `headers` block** and it
registers itself, sends the browser to the Buildspace consent screen for
a human Allow, and manages its own tokens:

```json
{
  "mcpServers": {
    "buildspace": { "url": "https://api-buildspace.bio.xyz/api/v1/mcp" }
  }
}
```

Access token **1 hour**; refresh token rotates per use and expires **30
days from consent** (absolute — not extended by use), so the client
re-consents monthly. `POST https://api-buildspace.bio.xyz/oauth/revoke` (RFC 7009) ends
a grant early; replaying a rotated-past refresh token revokes the whole
family. Token `resource` must be the MCP URL (RFC 8707) — a token minted
for another vertical is refused.

### Prerequisites (get a bearer)

1. One-time: create/store `agentCredential` via BIO Authentication (`auth/agent/SKILL.md`).
2. One-time: Buildspace onboard (Quickstart step 2).
3. Each session: mint `BUILDSPACE_BEARER` (Quickstart steps 1 + 3).
4. Prefer MCP tools over hand-rolled REST for agent work on applications + reports.

### Client config (copy/paste)

Replace the bearer after each mint (short-lived session; see Re-auth).

**Cursor** — Settings → MCP → Add server (or project `.cursor/mcp.json`):

```json
{
  "mcpServers": {
    "buildspace": {
      "url": "https://api-buildspace.bio.xyz/api/v1/mcp",
      "headers": {
        "Authorization": "Bearer <BUILDSPACE_BEARER>"
      }
    }
  }
}
```

**Claude Desktop** — `~/Library/Application Support/Claude/claude_desktop_config.json`
(macOS) or `%APPDATA%\Claude\claude_desktop_config.json` (Windows); same
`url` + `headers` shape under `mcpServers.buildspace`. Restart the app.

**MCP Inspector** (smoke / debug):

```bash
npx @modelcontextprotocol/inspector
# URL:    https://api-buildspace.bio.xyz/api/v1/mcp
# Header: Authorization: Bearer <BUILDSPACE_BEARER>
# Then:   initialize → tools/list → tools/call
```

**Machine (service) tokens** — same URL; token must include scopes per tool:
`applications:read` for list/read tools, `applications:write` for create/update
tools. Endpoint gate allows any principal; scopes are enforced per tool.

### Authz rules (fleet must know)

- Acting identity is **always server-derived** from the bearer — never a tool arg.
- Application/report tools reuse the same REST membership/admin guards.
- Agents: create quota **20 / UTC day**, **100** total.
- `project_type` is **required** on MCP `create_application` (and REST
  `POST /application/new`). Other admin-only fields (`state`, `track`,
  decisions, `launch_date`) cannot be set via MCP create/update.
- `update_application` can write editor launch-readiness fields (prototype,
  images, thesis, market hypothesis, team, recommended reads, token symbol,
  editor `launch_parameters`). Roadmap items stay on `create_roadmap_item`.
  Submit with `submit_launch_request` once readiness is complete.

### Re-auth on 401

Expired/invalid bearer → **HTTP 401** at the gate (not MCP `isError`).
Stock OAuth clients refresh; paste-bearer callers re-mint
`BUILDSPACE_BEARER` (Quickstart 1 + 3) or refresh the machine credential,
then reconnect the MCP client. Onboard is one-time.

### Tool catalog

Reads: `list_applications`, `get_application`, `get_application_team`,
`get_application_agents`, `list_application_roadmap_items`, `list_reports`,
`get_current_report`, `get_report_period`, `get_report`.

Writes: `create_application`, `update_application`, `create_roadmap_item`,
`update_roadmap_item_status`, `log_team_activity`, `update_report_draft`,
`submit_report`, `submit_launch_request`.

**REST-only (not on MCP):** decision, invites/users/skills, application
replace/delete, credential/upload routes, MoLabs wallet-signature linking.
