Organizations API
REST API endpoints for creating and managing organizations, memberships, and invitations.
Organizations API
Organizations group users within a tenant. They have their own roles, permissions, and metadata.
Organization Object
{
"id": "org_01HABCDEF777666",
"tenant_id": "tnt_01HABCDEF654321",
"name": "Acme Corp",
"slug": "acme-corp",
"logo_url": "https://example.com/logo.png",
"member_count": 12,
"public_metadata": {},
"created_at": "2024-01-10T09:00:00Z",
"updated_at": "2024-01-15T10:30:00Z"
}GET /v1/organizations
List all organizations in the tenant.
Query parameters:
| Parameter | Type | Description |
|---|---|---|
q | string | Search by name or slug |
limit | integer | Default 20, max 100 |
cursor | string | Pagination cursor |
curl "https://api.hellojohn.dev/v1/organizations" \
-H "Authorization: Bearer sk_live_abc123" \
-H "X-Tenant-ID: tnt_01HABCDEF654321"POST /v1/organizations
Create a new organization.
Body:
| Field | Type | Required | Description |
|---|---|---|---|
name | string | ✅ | Organization name |
slug | string | — | URL-safe slug (auto-generated if omitted) |
logo_url | string | — | Logo URL |
created_by | string | — | User ID to set as owner |
public_metadata | object | — | Custom public data |
curl -X POST https://api.hellojohn.dev/v1/organizations \
-H "Authorization: Bearer sk_live_abc123" \
-H "X-Tenant-ID: tnt_01HABCDEF654321" \
-H "Content-Type: application/json" \
-d '{
"name": "Acme Corp",
"created_by": "usr_01HABCDEF123456"
}'Response: 201 Created — Returns Organization object.
GET /v1/organizations/:id
Fetch a single organization by ID or slug.
Also supported: GET /v1/organizations/slug/:slug
PATCH /v1/organizations/:id
Update an organization.
Body (all optional):
| Field | Type | Description |
|---|---|---|
name | string | Organization name |
slug | string | URL slug |
logo_url | string | Logo URL |
public_metadata | object | Replaces entire public_metadata |
DELETE /v1/organizations/:id
Delete an organization and remove all memberships.
Response: 204 No Content
GET /v1/organizations/:id/members
List all members of an organization.
Response:
{
"data": [
{
"id": "mem_01HABCDEF333222",
"user_id": "usr_01HABCDEF123456",
"org_id": "org_01HABCDEF777666",
"role": "owner",
"joined_at": "2024-01-10T09:00:00Z",
"user": {
"id": "usr_01HABCDEF123456",
"email": "alice@example.com",
"name": "Alice Smith"
}
}
]
}POST /v1/organizations/:id/members
Add a user directly to an organization (admin action, no invitation email).
Body:
| Field | Type | Required | Description |
|---|---|---|---|
user_id | string | ✅ | User ID to add |
role | string | — | owner, admin, member (default: member) |
curl -X POST https://api.hellojohn.dev/v1/organizations/org_01HABCDEF777666/members \
-H "Authorization: Bearer sk_live_abc123" \
-H "X-Tenant-ID: tnt_01HABCDEF654321" \
-H "Content-Type: application/json" \
-d '{"user_id": "usr_01HABCDEF123456", "role": "admin"}'Response: 201 Created — Returns membership object.
PATCH /v1/organizations/:id/members/:user_id
Update a member's role.
Body:
| Field | Type | Required | Description |
|---|---|---|---|
role | string | ✅ | New role: owner, admin, member |
DELETE /v1/organizations/:id/members/:user_id
Remove a user from the organization.
Response: 204 No Content
POST /v1/organizations/:id/invitations
Send an invitation email to a user.
Body:
| Field | Type | Required | Description |
|---|---|---|---|
email | string | ✅ | Email to invite |
role | string | — | Role after accepting (default: member) |
redirect_url | string | — | URL to redirect after accepting |
expires_in | string | — | Expiry duration (default: 7d) |
curl -X POST https://api.hellojohn.dev/v1/organizations/org_01HABCDEF777666/invitations \
-H "Authorization: Bearer sk_live_abc123" \
-H "X-Tenant-ID: tnt_01HABCDEF654321" \
-H "Content-Type: application/json" \
-d '{
"email": "bob@example.com",
"role": "member",
"redirect_url": "https://app.example.com/join"
}'Response: 201 Created
{
"id": "inv_01HABCDEF444333",
"org_id": "org_01HABCDEF777666",
"email": "bob@example.com",
"role": "member",
"status": "pending",
"expires_at": "2024-01-22T09:00:00Z",
"created_at": "2024-01-15T09:00:00Z"
}GET /v1/organizations/:id/invitations
List pending invitations for an organization.
DELETE /v1/organizations/:id/invitations/:invitation_id
Revoke a pending invitation.
Response: 204 No Content
POST /v1/invitations/:token/accept
Accept an invitation (called by the invited user after clicking the link).
Headers: Authorization: Bearer <access_token> (the invited user must be signed in)
Response: 200 OK — Returns updated membership.