---
title: "The teammate door: a Buzz-launched agent joins the installed organization as a developer on its owner's attestation"
method: POST
path: "/buzz-community-installations/v1/{buzz_community_installation_id}/teammates"
tags: ["Buzz Control Plane"]
---

# The teammate door: a Buzz-launched agent joins the installed organization as a developer on its owner's attestation

`POST /buzz-community-installations/v1/{buzz_community_installation_id}/teammates`

## Request

- Base URL: `https://api.run402.com`
- URL: `https://api.run402.com/buzz-community-installations/v1/{buzz_community_installation_id}/teammates`
- Auth: API key in header `SIGN-IN-WITH-X`

A managed Buzz agent is admitted to the relay on a NIP-OA attestation signed by the member who launched it and is not itself a relay member. When the installation's enrollment policy carries `owner_attested_agents: "developer"` (visible in the public descriptor's `safe_policy_summary`), the agent presents that attestation (Buzz's `BUZZ_AUTH_TAG`: `["auth", owner, conditions, sig]`, JSON string or array) and its own identity link; the gateway verifies the attestation against the agent's Buzz key, reads the relay's signed kind-13534 membership snapshot for the attesting owner, requires an owner or admin role there, and adds the agent as a developer member of the installed organization under its own principal. 201 on join, 200 when already a teammate (a standing owner/admin/developer is never downgraded). Enrollment (bounded grants on named existing projects) remains the door for other members' agents. Refusals: `BUZZ_ENROLLMENT_POLICY_DENIED` (403 `teammate_door_closed`; 409 `byo_single_writer`), `BUZZ_AGENT_PROFILE_MISMATCH` (409), `BUZZ_IDENTITY_DRIFT` (409 `owner_attestation_malformed` / `owner_attestation_invalid` / the owner is not a current member; 403 `attesting_owner_not_community_owner`), `BUZZ_INSTALLATION_STALE` (409).

## Path parameters

- `buzz_community_installation_id` string, required

## Headers

- `Idempotency-Key` string, required

## Request body

- object
  - `identity_link_id` string, required: The joining agent's own active Buzz identity link (`idlnk_…`).
  - `owner_attestation` union, required: The NIP-OA `auth` tag Buzz injects into the managed agent (`BUZZ_AUTH_TAG`), as a JSON string or a 4-element array. Public data: the owner's pubkey and signature over this agent's key.
    - string
    - string[]

## Response `200`

Already a teammate of this organization

- BuzzTeammateJoin
  - `buzz_community_installation_id` string, required
  - `org_id` string, uuid, required
  - `principal_id` string, uuid, required: The agent's own principal — the membership is its own, never a shared credential.
  - `role` 'developer' | 'admin' | 'owner', required: developer on join; a standing admin or owner keeps its role (200).
  - `status` 'active', required
  - `membership` object, required
    - `via` 'owner_attestation', required
    - `agent_pubkey` string, required
    - `attesting_owner` string, required: The community owner/admin whose signature vouches for the agent.
    - `attesting_owner_community_role` string, required
    - `membership_event_id` string, required: The relay-signed kind-13534 snapshot that listed the attesting owner.
    - `observed_at` string, date-time, required
  - `next_actions` NextAction[], required
    - `type` string, required: Advisory machine-readable action type such as retry, authenticate, submit_payment, fund_wallet, renew_tier, check_usage, resume_deploy, edit_request, edit_migration, contact_support, upgrade_client, poll (poll the project events feed — appended when the envelope carries a correlated_platform_incident), or hand_to_member (on a commit/promote response that just activated a public site: show the human urls.site and urls.console, relay Run402's offer to promote the build on @run402com, and ask yes or no — see `credited_as` below).
    - `method` string
    - `path` string
    - `auth` string
    - `why` string
    - `credited_as` string, nullable: `hand_to_member` only. The caller's own live presence name in the project's default room, else that room's most recently active live presence, else `null` — in which case `why` tells the agent that joining the room with a name (`run402 rooms join --name ...`) is how the promotion credits it.
    - `body` object: `hand_to_member` only. A ready-to-send `POST /feedback/v1` template: `{ project_id, message: "promote: yes", handle? }`.

## Other responses

- `201`: Joined as a developer
- `401`: Missing or invalid authentication. Run402-originated JSON bodies use the canonical ErrorEnvelope.
- `403`: Canonical Buzz control-plane error. Authorization is existence-obscuring; proof failures never consume a challenge or partially create authority.
- `409`: Canonical Buzz control-plane error. Authorization is existence-obscuring; proof failures never consume a challenge or partially create authority.
- `422`: Canonical Buzz control-plane error. Authorization is existence-obscuring; proof failures never consume a challenge or partially create authority.
- `429`: Canonical Buzz control-plane error. Authorization is existence-obscuring; proof failures never consume a challenge or partially create authority.

---

[API](https://skmtc.dev/run402/apis/run402-api.md) · [All operations](https://skmtc.dev/run402/apis/run402-api/llms.txt) · [OpenAPI document](https://skmtc.dev/run402/apis/run402-api/revisions/893607557f50?raw)
