15 KiB
title, description, icon
| title | description | icon |
|---|---|---|
| Organizations API | Create and manage organizations and their members | users |
Organizations API
Manage organizations, members, and roles for collaborative repository management.
Overview
Organizations allow multiple users to collaborate on repositories. Members can have different roles:
- visitor: Read-only access
- member: Can create repositories, read all org repos
- admin: Can manage members and settings
- super-admin: Full control (creator role)
Endpoints
Create Organization
Create a new organization with default quotas.
Endpoint: POST /api/organizations/create
Request Body:
{
"name": "myorg",
"description": "Machine Learning Research"
}
| Field | Type | Required | Description |
|---|---|---|---|
name |
string | Yes | Organization name (alphanumeric, hyphens, underscores) |
description |
string | No | Organization description |
Authentication: Required
Response:
{
"success": true,
"name": "myorg"
}
Notes:
- Creator is automatically added as
super-admin - Default quotas are applied from server configuration
- Organization name must not be reserved (e.g.,
admin,api,models, etc.) - Name is validated and normalized
Error Responses:
| Status | Description |
|---|---|
| 400 | Organization name already exists or is reserved |
| 401 | Authentication required |
| 422 | Invalid request body |
Example:
import requests
response = requests.post(
"http://localhost:28080/api/organizations/create",
headers={"Authorization": "Bearer YOUR_TOKEN"},
json={
"name": "myorg",
"description": "Machine Learning Research"
}
)
result = response.json()
print(f"Organization created: {result['name']}")
Get Organization Info
Get basic organization information.
Endpoint: GET /api/organizations/{org_name}
Parameters:
| Parameter | Type | Location | Required | Description |
|---|---|---|---|---|
org_name |
string | path | Yes | Organization name |
fallback |
boolean | query | No | Enable fallback to external sources (default: true) |
Authentication: Optional
Response:
{
"name": "myorg",
"description": "Machine Learning Research",
"created_at": "2025-01-01T00:00:00Z",
"_source": "local"
}
Example:
response = requests.get("http://localhost:28080/api/organizations/myorg")
org = response.json()
Add Member
Add a member to an organization (admin only).
Endpoint: POST /api/organizations/{org_name}/members
Parameters:
| Parameter | Type | Location | Required | Description |
|---|---|---|---|---|
org_name |
string | path | Yes | Organization name |
Request Body:
{
"username": "alice",
"role": "member"
}
| Field | Type | Required | Description |
|---|---|---|---|
username |
string | Yes | Username to add |
role |
string | Yes | Member role: visitor, member, admin |
Authentication: Required (admin or super-admin)
Response:
{
"success": true,
"message": "Member added successfully"
}
Error Responses:
| Status | Description |
|---|---|
| 400 | User is already a member |
| 403 | Not authorized to add members |
| 404 | Organization or user not found |
Example:
response = requests.post(
"http://localhost:28080/api/organizations/myorg/members",
headers={"Authorization": "Bearer YOUR_TOKEN"},
json={
"username": "alice",
"role": "member"
}
)
Remove Member
Remove a member from an organization (admin only).
Endpoint: DELETE /api/organizations/{org_name}/members/{username}
Parameters:
| Parameter | Type | Location | Required | Description |
|---|---|---|---|---|
org_name |
string | path | Yes | Organization name |
username |
string | path | Yes | Username to remove |
Authentication: Required (admin or super-admin)
Response:
{
"success": true,
"message": "Member removed successfully"
}
Error Responses:
| Status | Description |
|---|---|
| 403 | Not authorized to remove members |
| 404 | Organization, user, or membership not found |
Example:
response = requests.delete(
"http://localhost:28080/api/organizations/myorg/members/alice",
headers={"Authorization": "Bearer YOUR_TOKEN"}
)
Update Member Role
Change a member's role in an organization (admin only).
Endpoint: PUT /api/organizations/{org_name}/members/{username}
Parameters:
| Parameter | Type | Location | Required | Description |
|---|---|---|---|---|
org_name |
string | path | Yes | Organization name |
username |
string | path | Yes | Username to update |
Request Body:
{
"role": "admin"
}
| Field | Type | Required | Description |
|---|---|---|---|
role |
string | Yes | New role: visitor, member, or admin |
Authentication: Required (admin or super-admin)
Response:
{
"success": true,
"message": "Member role updated successfully"
}
Error Responses:
| Status | Description |
|---|---|
| 403 | Not authorized to update member roles |
| 404 | Organization, user, or membership not found |
Example:
# Promote member to admin
response = requests.put(
"http://localhost:28080/api/organizations/myorg/members/alice",
headers={"Authorization": "Bearer YOUR_TOKEN"},
json={"role": "admin"}
)
# Demote admin to member
response = requests.put(
"http://localhost:28080/api/organizations/myorg/members/bob",
headers={"Authorization": "Bearer YOUR_TOKEN"},
json={"role": "member"}
)
List Organization Members
Get list of all organization members.
Endpoint: GET /api/organizations/{org_name}/members
Parameters:
| Parameter | Type | Location | Required | Description |
|---|---|---|---|---|
org_name |
string | path | Yes | Organization name |
Authentication: Optional (public information)
Response:
{
"members": [
{
"user": "alice",
"role": "super-admin"
},
{
"user": "bob",
"role": "admin"
},
{
"user": "charlie",
"role": "member"
}
]
}
Example:
response = requests.get(
"http://localhost:28080/api/organizations/myorg/members"
)
members = response.json()["members"]
for member in members:
print(f"{member['user']}: {member['role']}")
List User Organizations
Get organizations a user belongs to.
Endpoint: GET /api/users/{username}/orgs
Parameters:
| Parameter | Type | Location | Required | Description |
|---|---|---|---|---|
username |
string | path | Yes | Username to query |
Authentication: Optional (public information)
Response:
{
"organizations": [
{
"name": "myorg",
"description": "Machine Learning Research",
"role": "admin"
},
{
"name": "anotherorg",
"description": "Data Science Projects",
"role": "member"
}
]
}
Example:
response = requests.get(
"http://localhost:28080/api/users/alice/orgs"
)
orgs = response.json()["organizations"]
for org in orgs:
print(f"{org['name']} ({org['role']})")
Role Permissions
Visitor
- View public repositories
- View organization profile
- No write access
Member
- All visitor permissions
- Create repositories under organization
- Write to organization repositories they created
- View all organization repositories (public and private)
Admin
- All member permissions
- Manage organization members (add, remove, update roles)
- Update organization settings and avatar
- Manage organization quotas
- Delete organization repositories
Super-Admin
- All admin permissions
- Cannot be removed by other admins
- Transfer ownership capabilities
- Full organization control
Note: Only the organization creator gets super-admin role automatically. Admins cannot promote members to super-admin.
Usage Examples
Create and Set Up Organization
import requests
BASE_URL = "http://localhost:28080"
TOKEN = "YOUR_TOKEN"
headers = {"Authorization": f"Bearer {TOKEN}"}
# 1. Create organization
response = requests.post(
f"{BASE_URL}/api/organizations/create",
headers=headers,
json={
"name": "ml-research",
"description": "Machine Learning Research Lab"
}
)
print(f"Created: {response.json()['name']}")
# 2. Update organization settings
requests.put(
f"{BASE_URL}/api/organizations/ml-research/settings",
headers=headers,
json={
"bio": "Advancing AI through open research",
"website": "https://ml-research.example.com",
"social_media": {
"twitter_x": "ml_research",
"github": "ml-research"
}
}
)
# 3. Upload organization logo
with open("logo.png", "rb") as f:
requests.post(
f"{BASE_URL}/api/organizations/ml-research/avatar",
headers=headers,
files={"file": f}
)
# 4. Add team members
members = [
("alice", "admin"),
("bob", "member"),
("charlie", "member")
]
for username, role in members:
requests.post(
f"{BASE_URL}/api/organizations/ml-research/members",
headers=headers,
json={"username": username, "role": role}
)
print(f"Added {username} as {role}")
Manage Organization Members
# List all members
response = requests.get(
f"{BASE_URL}/api/organizations/ml-research/members"
)
members = response.json()["members"]
# Find members by role
admins = [m for m in members if m["role"] in ["admin", "super-admin"]]
regular_members = [m for m in members if m["role"] == "member"]
print(f"Admins: {len(admins)}")
print(f"Members: {len(regular_members)}")
# Promote member to admin
requests.put(
f"{BASE_URL}/api/organizations/ml-research/members/alice",
headers=headers,
json={"role": "admin"}
)
# Remove inactive member
requests.delete(
f"{BASE_URL}/api/organizations/ml-research/members/bob",
headers=headers
)
Check User's Organizations
# Get all organizations for a user
response = requests.get(
f"{BASE_URL}/api/users/alice/orgs"
)
orgs = response.json()["organizations"]
# Filter by role
admin_orgs = [o for o in orgs if o["role"] in ["admin", "super-admin"]]
member_orgs = [o for o in orgs if o["role"] == "member"]
print(f"Alice is admin of: {[o['name'] for o in admin_orgs]}")
print(f"Alice is member of: {[o['name'] for o in member_orgs]}")
Python Helper Class
class OrganizationManager:
def __init__(self, base_url: str, token: str):
self.base_url = base_url
self.headers = {"Authorization": f"Bearer {token}"}
def create_org(self, name: str, description: str = None):
response = requests.post(
f"{self.base_url}/api/organizations/create",
headers=self.headers,
json={"name": name, "description": description}
)
response.raise_for_status()
return response.json()
def add_member(self, org_name: str, username: str, role: str = "member"):
response = requests.post(
f"{self.base_url}/api/organizations/{org_name}/members",
headers=self.headers,
json={"username": username, "role": role}
)
response.raise_for_status()
return response.json()
def list_members(self, org_name: str):
response = requests.get(
f"{self.base_url}/api/organizations/{org_name}/members"
)
response.raise_for_status()
return response.json()["members"]
def update_role(self, org_name: str, username: str, new_role: str):
response = requests.put(
f"{self.base_url}/api/organizations/{org_name}/members/{username}",
headers=self.headers,
json={"role": new_role}
)
response.raise_for_status()
return response.json()
def remove_member(self, org_name: str, username: str):
response = requests.delete(
f"{self.base_url}/api/organizations/{org_name}/members/{username}",
headers=self.headers
)
response.raise_for_status()
return response.json()
# Usage
org_mgr = OrganizationManager("http://localhost:28080", "YOUR_TOKEN")
# Create and setup
org_mgr.create_org("ml-team", "ML Research Team")
org_mgr.add_member("ml-team", "alice", "admin")
org_mgr.add_member("ml-team", "bob", "member")
# List and manage
members = org_mgr.list_members("ml-team")
org_mgr.update_role("ml-team", "bob", "admin")
org_mgr.remove_member("ml-team", "charlie")
JavaScript/TypeScript Example
class OrganizationAPI {
constructor(baseURL, token) {
this.baseURL = baseURL;
this.headers = {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
};
}
async createOrg(name, description) {
const response = await fetch(`${this.baseURL}/api/organizations/create`, {
method: 'POST',
headers: this.headers,
body: JSON.stringify({ name, description })
});
return await response.json();
}
async addMember(orgName, username, role = 'member') {
const response = await fetch(
`${this.baseURL}/api/organizations/${orgName}/members`,
{
method: 'POST',
headers: this.headers,
body: JSON.stringify({ username, role })
}
);
return await response.json();
}
async listMembers(orgName) {
const response = await fetch(
`${this.baseURL}/api/organizations/${orgName}/members`
);
const data = await response.json();
return data.members;
}
async updateRole(orgName, username, newRole) {
const response = await fetch(
`${this.baseURL}/api/organizations/${orgName}/members/${username}`,
{
method: 'PUT',
headers: this.headers,
body: JSON.stringify({ role: newRole })
}
);
return await response.json();
}
async removeMember(orgName, username) {
const response = await fetch(
`${this.baseURL}/api/organizations/${orgName}/members/${username}`,
{
method: 'DELETE',
headers: this.headers
}
);
return await response.json();
}
}
// Usage
const orgAPI = new OrganizationAPI('http://localhost:28080', 'YOUR_TOKEN');
await orgAPI.createOrg('ml-team', 'ML Research Team');
await orgAPI.addMember('ml-team', 'alice', 'admin');
const members = await orgAPI.listMembers('ml-team');
CLI Usage
See CLI Documentation for command-line interface:
# Create organization
kohub-cli org create myorg --description "ML Research"
# Add member
kohub-cli org add-member myorg alice --role member
# List members
kohub-cli org list-members myorg
# Update role
kohub-cli org update-role myorg alice --role admin
# Remove member
kohub-cli org remove-member myorg bob
Next Steps
- Invitation API - Invite users to organizations
- Quota Management API - Manage organization storage quotas
- Settings API - Update organization profile and avatar
- Repository API - Create repositories under organizations