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 <JWT>(required)
Request Body
{
"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)
{
"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 <JWT>(required)
Response (200 OK)
{
"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 <JWT>(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 <JWT>(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 <JWT>(required)
Response (200 OK)
{
"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 <JWT>(required)
Request Body
{
"api_url": "https://reef.example.com"
}
Field constraints
api_url: must start withhttp://orhttps://, max 2048 characters (required)
Response (200 OK)
{
"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 <JWT>(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 <JWT>(required)
Response (200 OK)
{
"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 <JWT>(required)
Request Body
{
"email": "colleague@example.com",
"role": "member"
}
Notes
role:ownerormember.
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 <JWT>(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.