Organizations & Teams
Collaborate with your team under a single organization. Share API keys, sessions, and credit balances while controlling access with role-based permissions.
Dashboard Available
How Organizations Work
Create
Create an organization and become its owner. A unique slug is generated automatically from the name.
Invite
Send email invitations to team members. Each invitation includes a role and expires after 7 days. Invitees receive a link to accept or decline.
Collaborate
Members share the organization's credit balance, API keys, and browser sessions. All usage is tracked per-member in the audit log.
Roles & Permissions
Organizations have three roles arranged in a hierarchy. Higher roles inherit all permissions of lower roles.
| Permission | Member | Admin | Owner |
|---|---|---|---|
| Use shared API keys & sessions | Yes | Yes | Yes |
| View organization details | Yes | Yes | Yes |
| View member list & audit logs | Yes | Yes | Yes |
| Invite & remove members | No | Yes | Yes |
| Update organization settings | No | Yes | Yes |
| Change member roles | No | Members only | Yes |
| Promote to admin | No | No | Yes |
| Transfer ownership | No | No | Yes |
| Delete organization | No | No | Yes |
Owner Restrictions
Creating an Organization
/api/v1/organizationsCreate a new organization. You are automatically assigned the owner role. A URL-safe slug is generated from the name.
curl -X POST https://alterlab.io/api/v1/organizations \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Acme Scraping Team",
"description": "Our production scraping infrastructure"
}'Response
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Acme Scraping Team",
"slug": "acme-scraping-team-a1b2c3d4",
"description": "Our production scraping infrastructure",
"is_personal": false,
"role": "owner",
"member_count": 1,
"created_at": "2026-03-24T10:00:00Z"
}Inviting Members
/api/v1/organizations/{org_id}/invitationsSend an email invitation to a new team member. Requires admin or owner role. Invitations expire after 7 days and can be resent or cancelled.
curl -X POST https://alterlab.io/api/v1/organizations/{org_id}/invitations \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"email": "[email protected]",
"role": "member"
}'Invitation Lifecycle
Pending
Invitation sent, waiting for the invitee to accept or decline. Valid for 7 days.
Accepted
Invitee clicked the link and joined the organization with the assigned role.
Declined
Invitee explicitly declined the invitation. You can send a new one if needed.
Expired
Invitation was not acted upon within 7 days. Use the resend endpoint to issue a fresh invitation.
List Pending Invitations
/api/v1/organizations/{org_id}/invitationscurl https://alterlab.io/api/v1/organizations/{org_id}/invitations \
-H "Authorization: Bearer YOUR_TOKEN"Resend an Invitation
/api/v1/organizations/{org_id}/invitations/{invitation_id}/resendGenerates a new token and resets the 7-day expiry. The old link becomes invalid.
Cancel an Invitation
/api/v1/organizations/{org_id}/invitations/{invitation_id}Managing Members
/api/v1/organizations/{org_id}/membersList all members of an organization. Results are sorted by role (owners first, then admins, then members) and paginated.
curl https://alterlab.io/api/v1/organizations/{org_id}/members \
-H "Authorization: Bearer YOUR_TOKEN"{
"members": [
{
"id": "member-uuid",
"user": {
"id": "user-uuid",
"email": "[email protected]",
"name": "Jane Smith"
},
"role": "owner",
"joined_at": "2026-03-01T10:00:00Z"
},
{
"id": "member-uuid-2",
"user": {
"id": "user-uuid-2",
"email": "[email protected]",
"name": "John Doe"
},
"role": "member",
"joined_at": "2026-03-15T14:30:00Z"
}
],
"total": 2
}Update a Member's Role
/api/v1/organizations/{org_id}/members/{user_id}curl -X PATCH https://alterlab.io/api/v1/organizations/{org_id}/members/{user_id} \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"role": "admin"}'Promotion Rules
Remove a Member
/api/v1/organizations/{org_id}/members/{user_id}Remove a member from the organization. Requires admin or owner role. The organization owner cannot be removed.
curl -X DELETE https://alterlab.io/api/v1/organizations/{org_id}/members/{user_id} \
-H "Authorization: Bearer YOUR_TOKEN"Leave an Organization
/api/v1/organizations/{org_id}/leaveVoluntarily leave an organization. Owners must transfer ownership before leaving.
curl -X POST https://alterlab.io/api/v1/organizations/{org_id}/leave \
-H "Authorization: Bearer YOUR_TOKEN"Owner Cannot Leave
Shared Resources
When you switch to an organization context, all API activity is billed to the organization's credit balance. Members share:
API Keys
Organization-scoped API keys are accessible to all members. Create keys from the dashboard or API.
Browser Sessions
Authenticated sessions (cookies, headers) are shared across the organization for collaborative scraping.
Credit Balance
A single credit pool shared by all members. Usage is tracked per-member in the audit log.
Webhooks
Organization-level webhooks receive events for all scraping jobs within the organization.
Set Default Organization
Set which organization context is active by default when you authenticate:
curl -X POST https://alterlab.io/api/v1/organizations/default \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"organization_id": "550e8400-e29b-41d4-a716-446655440000"}'Transfer Ownership
/api/v1/organizations/{org_id}/transfer-ownershipTransfer organization ownership to another member. Only the current owner can perform this action. The previous owner is demoted to admin.
curl -X POST https://alterlab.io/api/v1/organizations/{org_id}/transfer-ownership \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"new_owner_id": "user-uuid-of-new-owner"}'Irreversible Action
Audit Logs
/api/v1/organizations/{org_id}/audit-logsView a chronological record of all significant actions within the organization. Audit logs track member changes, role updates, invitation activity, and ownership transfers.
curl "https://alterlab.io/api/v1/organizations/{org_id}/audit-logs?page=1&page_size=25" \
-H "Authorization: Bearer YOUR_TOKEN"{
"entries": [
{
"id": "log-uuid",
"action": "member.role_updated",
"actor": {
"id": "user-uuid",
"email": "[email protected]",
"name": "Jane Smith"
},
"details": {
"target_user": "[email protected]",
"old_role": "member",
"new_role": "admin"
},
"created_at": "2026-03-20T16:45:00Z"
}
],
"total": 42,
"page": 1,
"page_size": 25
}Retention
page and page_size query parameters to paginate through results.Organization Stats
/api/v1/organizations/{org_id}/statsGet usage statistics and billing information for the organization, including member count, total credits used, and active API keys.
curl https://alterlab.io/api/v1/organizations/{org_id}/stats \
-H "Authorization: Bearer YOUR_TOKEN"Best Practices
Use the Least Privilege Principle
Assign the member role by default. Only promote to admin when a team member needs to manage invitations or settings.
Set Up a Backup Owner
If the owner leaves the company, the organization becomes unmanageable. Keep at least one admin who can receive ownership transfer.
Monitor with Audit Logs
Regularly review audit logs to track who joined, who was removed, and what role changes occurred. This is essential for compliance and security.
Use Organization-Scoped API Keys
Create API keys scoped to the organization rather than using personal keys. This ensures usage is billed to the organization and keys can be rotated without affecting individual accounts.