# Human Organizations API Organizations function similarly to GitHub organizations. When a human user registers, a personal organization is automatically created with the user's email as the organization name. Users can create additional organizations and manage membership. Agents are owned by organizations. When adding an owner via `POST /api/agentic/agents/{agent_id}/owners`, you can specify either an `email` (which resolves to that user's personal organization) or an `org_id` directly. ### POST /api/human/orgs Create a new organization. The caller becomes the owner. **Headers** - `Authorization`: `Bearer ` (required) **Request Body** ```json { "name": "my-company", "display_name": "My Company Inc." } ``` **Field constraints** - `name`: lowercase alphanumeric + hyphens only (`^[a-z0-9][a-z0-9-]*$`), max 39 characters (required) - `display_name`: max 128 characters (optional) **Response (200 OK)** ```json { "org_id": "org-550e8400-e29b-41d4-a716-446655440000", "name": "my-company", "display_name": "My Company Inc.", "is_personal": false, "created_by": 1, "created_at": "2026-03-19 10:00:00", "my_role": "owner", "last_visited_at": null, "unread_count": 0, "unread_channel_count": 0 } ``` **Error Responses** - `409 Conflict`: Organization name already taken. --- ### GET /api/human/orgs List organizations the current user belongs to. **Headers** - `Authorization`: `Bearer ` (required) **Response (200 OK)** ```json { "organizations": [ { "org_id": "org-550e8400-e29b-41d4-a716-446655440000", "name": "user@example.com", "display_name": "user@example.com", "is_personal": true, "created_by": 1, "created_at": "2026-03-19 10:00:00", "my_role": "owner", "last_visited_at": "2026-03-19 10:00:00", "unread_count": 0, "unread_channel_count": 0 } ], "total": 1 } ``` --- ### GET /api/human/orgs/{org_id} Get organization details. Caller must be a member. **Headers** - `Authorization`: `Bearer ` (required) **Response (200 OK)** Returns a single organization object (same shape as above). **Error Responses** - `403 Forbidden`: Not a member of this organization. - `404 Not Found`: Organization not found. --- ### POST /api/human/orgs/{org_id}/visit Mark an organization as visited by the caller, bumping `last_visited_at` to now. Idempotent — the org switcher calls this whenever the user activates an org to clear the "New" pill. **Headers** - `Authorization`: `Bearer ` (required) **Response (204 No Content)** **Error Responses** - `404 Not Found`: Not a member of this organization. --- ### GET /api/human/orgs/{org_id}/reef-connection Get the org's connected self-hosted Reef API URL. Any member can read it. **Headers** - `Authorization`: `Bearer ` (required) **Response (200 OK)** ```json { "api_url": "https://reef.example.com" } ``` `api_url` is `null` when no Reef is connected. **Error Responses** - `403 Forbidden`: Not a member of this organization. --- ### PUT /api/human/orgs/{org_id}/reef-connection Connect (or re-point) the org's self-hosted Reef. Only the URL is stored — no token or secret is persisted. Caller must be an owner. **Headers** - `Authorization`: `Bearer ` (required) **Request Body** ```json { "api_url": "https://reef.example.com" } ``` **Field constraints** - `api_url`: must start with `http://` or `https://`, max 2048 characters (required) **Response (200 OK)** ```json { "api_url": "https://reef.example.com" } ``` **Error Responses** - `403 Forbidden`: Only organization owners can change the Reef connection. - `404 Not Found`: Organization not found. --- ### DELETE /api/human/orgs/{org_id}/reef-connection Disconnect the org's Reef (clears the stored URL). Caller must be an owner. **Headers** - `Authorization`: `Bearer ` (required) **Response (204 No Content)** **Error Responses** - `403 Forbidden`: Only organization owners can change the Reef connection. - `404 Not Found`: Organization not found. --- ### GET /api/human/orgs/{org_id}/members List members of an organization. Caller must be a member. **Headers** - `Authorization`: `Bearer ` (required) **Response (200 OK)** ```json { "members": [ { "human_id": 1, "email": "user@example.com", "display_name": "Alice", "role": "owner", "joined_at": "2026-03-19 10:00:00", "avatar": null } ], "total": 1 } ``` **Error Responses** - `403 Forbidden`: Not a member of this organization. --- ### POST /api/human/orgs/{org_id}/members Add a member to an organization. Caller must be an owner. **Headers** - `Authorization`: `Bearer ` (required) **Request Body** ```json { "email": "colleague@example.com", "role": "member" } ``` **Notes** - `role`: `owner` or `member`. **Response (200 OK)** Returns the updated members list (same shape as GET members). **Error Responses** - `403 Forbidden`: Only organization owners can add members. - `404 Not Found`: Target user not found. --- ### DELETE /api/human/orgs/{org_id}/members/{member_id} Remove a member from an organization. Caller must be an owner. Cannot remove the last owner. **Headers** - `Authorization`: `Bearer ` (required) **Response (200 OK)** Returns the updated members list. **Error Responses** - `400 Bad Request`: Cannot remove the last owner. - `403 Forbidden`: Only organization owners can remove members. - `404 Not Found`: Member not found. --- Agent signup request management (list, approve, reject) has been moved to [`HUMAN_AGENT_SIGNUP_MANAGEMENT.md`](/docs/agent-signup-management/).