Use Case

Organization Management

Create and manage organizations with teams, roles, permissions, and centralized billing

Organization Structure

ParrotRouter provides a comprehensive organization management system that supports complex team structures, role-based access control, and centralized resource management. Perfect for enterprises and growing teams.

Multi-Tenant

Isolated environments for each organization

Team Management

Create teams with specific permissions

RBAC

Fine-grained role-based access control

Creating an Organization

Set up your organization with teams, roles, and billing configuration:

Organization Setuppython
import requests

# Create organization
org_response = requests.post(
    "https://api.parrotrouter.com/v1/organizations",
    headers={
        "Authorization": "Bearer your-admin-key",
        "Content-Type": "application/json"
    },
    json={
        "name": "Acme Corporation",
        "slug": "acme-corp",  # Unique identifier
        "description": "AI-powered solutions for business",
        "settings": {
            "billing": {
                "type": "consolidated",  # or "per_team"
                "payment_method_id": "pm_1234567890",
                "billing_email": "finance@acme.com",
                "tax_id": "US123456789",
                "invoice_settings": {
                    "footer": "Acme Corp - Tax ID: US123456789",
                    "send_to": ["finance@acme.com", "accounting@acme.com"]
                }
            },
            "security": {
                "require_2fa": True,
                "sso_enabled": True,
                "sso_provider": "okta",
                "ip_allowlist": ["203.0.113.0/24"],
                "session_timeout_minutes": 60
            },
            "defaults": {
                "timezone": "America/New_York",
                "language": "en",
                "date_format": "MM/DD/YYYY"
            }
        },
        "metadata": {
            "industry": "technology",
            "size": "enterprise",
            "founded": "2020"
        }
    }
)

org = org_response.json()
print(f"Organization created: {org['id']}")

# Create organization roles
roles = [
    {
        "name": "Organization Admin",
        "slug": "org_admin",
        "description": "Full administrative access",
        "permissions": ["*"],  # All permissions
        "is_system": True
    },
    {
        "name": "Team Lead",
        "slug": "team_lead",
        "description": "Manage team members and resources",
        "permissions": [
            "teams.read", "teams.update",
            "members.read", "members.invite", "members.remove",
            "api_keys.create", "api_keys.read", "api_keys.update",
            "usage.read", "billing.read"
        ]
    },
    {
        "name": "Developer",
        "slug": "developer",
        "description": "Use AI APIs and view usage",
        "permissions": [
            "api_keys.use",
            "models.read", "models.use",
            "usage.read:own",  # Only own usage
            "teams.read:own"   # Only own team
        ]
    },
    {
        "name": "Finance",
        "slug": "finance",
        "description": "View billing and usage data",
        "permissions": [
            "billing.*",
            "usage.read",
            "invoices.*",
            "payment_methods.read"
        ]
    },
    {
        "name": "Viewer",
        "slug": "viewer",
        "description": "Read-only access",
        "permissions": [
            "*.read"  # All read permissions
        ]
    }
]

for role in roles:
    requests.post(
        f"https://api.parrotrouter.com/v1/organizations/{org['id']}/roles",
        headers={"Authorization": "Bearer your-admin-key"},
        json=role
    )

Team Management

Create teams within your organization with specific access controls and budgets:

Creating Teams

# Create teams with different configurations
teams_config = [
    {
        "name": "Engineering",
        "slug": "engineering",
        "description": "Product development team",
        "settings": {
            "budget": {
                "monthly_limit": 5000.00,
                "alert_threshold": 0.8,
                "hard_limit": True,  # Stop at limit
                "rollover": False    # Don't carry unused budget
            },
            "models": {
                "allowed": [
                    "gpt-4-turbo-preview",
                    "gpt-3.5-turbo",
                    "claude-3-opus-20240229",
                    "claude-3-sonnet-20240229"
                ],
                "blocked": ["dall-e-*"],  # No image generation
                "require_approval": ["gpt-4-32k"]  # Expensive models
            },
            "features": {
                "function_calling": True,
                "vision": True,
                "web_search": True,
                "fine_tuning": False
            },
            "notifications": {
                "usage_alerts": ["eng-leads@acme.com"],
                "approval_requests": ["cto@acme.com"]
            }
        }
    },
    {
        "name": "Marketing",
        "slug": "marketing",
        "description": "Content and marketing team",
        "settings": {
            "budget": {
                "monthly_limit": 2000.00,
                "alert_threshold": 0.9
            },
            "models": {
                "allowed": [
                    "gpt-3.5-turbo",
                    "claude-3-sonnet-20240229",
                    "dall-e-3"  # Allow image generation
                ],
                "rate_limits": {
                    "dall-e-3": {
                        "requests_per_day": 100,
                        "requests_per_hour": 20
                    }
                }
            }
        }
    },
    {
        "name": "Data Science",
        "slug": "data-science",
        "description": "ML and analytics team",
        "settings": {
            "budget": {
                "monthly_limit": 10000.00,
                "require_project_tag": True
            },
            "models": {
                "allowed": ["*"],  # All models
                "preferred_providers": ["openai", "anthropic"],
                "allow_fine_tuning": True,
                "allow_embeddings": True
            },
            "resources": {
                "max_parallel_requests": 50,
                "priority_queue": True,
                "dedicated_capacity": True
            }
        }
    }
]

# Create teams
for team_config in teams_config:
    team_response = requests.post(
        f"https://api.parrotrouter.com/v1/organizations/{org['id']}/teams",
        headers={"Authorization": "Bearer your-admin-key"},
        json=team_config
    )
    
    team = team_response.json()
    print(f"Created team: {team['name']} (ID: {team['id']})")
    
    # Set team-specific roles and permissions
    team_roles = [
        {
            "role": "team_lead",
            "permissions_override": {
                "add": ["budget.modify", "members.approve_requests"],
                "remove": []
            }
        },
        {
            "role": "developer",
            "permissions_override": {
                "add": [],
                "remove": ["api_keys.create"]  # Only leads can create keys
            }
        }
    ]
    
    for role_config in team_roles:
        requests.post(
            f"https://api.parrotrouter.com/v1/teams/{team['id']}/roles",
            headers={"Authorization": "Bearer your-admin-key"},
            json=role_config
        )

Managing Team Members

# Invite users to teams
def invite_team_members(team_id, members):
    invitations = []
    
    for member in members:
        response = requests.post(
            f"https://api.parrotrouter.com/v1/teams/{team_id}/invitations",
            headers={"Authorization": "Bearer your-admin-key"},
            json={
                "email": member["email"],
                "role": member["role"],
                "message": f"You're invited to join the {member['team_name']} team at Acme Corp",
                "permissions": member.get("custom_permissions", {}),
                "expires_in_days": 7,
                "send_email": True
            }
        )
        
        invitations.append(response.json())
    
    return invitations

# Bulk invite members
engineering_members = [
    {"email": "alice@acme.com", "role": "team_lead", "team_name": "Engineering"},
    {"email": "bob@acme.com", "role": "developer", "team_name": "Engineering"},
    {"email": "carol@acme.com", "role": "developer", "team_name": "Engineering"},
    {"email": "dave@acme.com", "role": "developer", "team_name": "Engineering",
     "custom_permissions": {"add": ["deployments.manage"]}}
]

invites = invite_team_members(engineering_team_id, engineering_members)

# Accept invitation (from user's perspective)
def accept_invitation(invitation_token):
    response = requests.post(
        "https://api.parrotrouter.com/v1/invitations/accept",
        headers={"Authorization": "Bearer user-token"},
        json={
            "token": invitation_token,
            "accept": True
        }
    )
    
    return response.json()

# Manage existing members
def update_member_role(team_id, user_id, new_role, custom_permissions=None):
    response = requests.patch(
        f"https://api.parrotrouter.com/v1/teams/{team_id}/members/{user_id}",
        headers={"Authorization": "Bearer your-admin-key"},
        json={
            "role": new_role,
            "permissions": custom_permissions,
            "reason": "Promotion to team lead"
        }
    )
    
    return response.json()

# Remove member from team
def remove_member(team_id, user_id, reassign_to=None):
    response = requests.delete(
        f"https://api.parrotrouter.com/v1/teams/{team_id}/members/{user_id}",
        headers={"Authorization": "Bearer your-admin-key"},
        json={
            "reassign_resources_to": reassign_to,  # Optional: reassign their resources
            "revoke_access_immediately": True,
            "reason": "Team restructuring"
        }
    )
    
    return response.json()

Access Control & Permissions

Permission System

# Define custom permission policies
permission_policy = {
    "name": "Engineering Policy",
    "description": "Standard permissions for engineering team",
    "statements": [
        {
            "effect": "allow",
            "actions": [
                "models:use",
                "models:list",
                "api_keys:use",
                "usage:read"
            ],
            "resources": [
                "model:gpt-4-turbo-preview",
                "model:gpt-3.5-turbo",
                "model:claude-3-*"
            ],
            "conditions": {
                "ip_address": {
                    "type": "ip_in_range",
                    "value": "10.0.0.0/8"  # Internal network only
                },
                "time": {
                    "type": "business_hours",
                    "timezone": "America/New_York",
                    "days": ["mon", "tue", "wed", "thu", "fri"],
                    "hours": {"start": "09:00", "end": "18:00"}
                },
                "mfa": {
                    "type": "required",
                    "max_age_minutes": 480  # 8 hours
                }
            }
        },
        {
            "effect": "allow",
            "actions": ["models:use"],
            "resources": ["model:gpt-4-32k"],
            "conditions": {
                "approval": {
                    "type": "required",
                    "approvers": ["team_lead", "org_admin"],
                    "reason_required": True
                },
                "cost_limit": {
                    "type": "per_request",
                    "max_amount": 10.00
                }
            }
        },
        {
            "effect": "deny",
            "actions": ["*"],
            "resources": ["*"],
            "conditions": {
                "anomaly_score": {
                    "type": "greater_than",
                    "value": 0.8  # Deny if anomaly detected
                }
            }
        }
    ]
}

# Apply policy to team
requests.post(
    f"https://api.parrotrouter.com/v1/teams/{team_id}/policies",
    headers={"Authorization": "Bearer your-admin-key"},
    json=permission_policy
)

# Create API key with team context
team_api_key = requests.post(
    "https://api.parrotrouter.com/v1/api-keys",
    headers={"Authorization": "Bearer team-lead-token"},
    json={
        "name": "Engineering Team API Key",
        "team_id": engineering_team_id,
        "inherit_team_permissions": True,
        "additional_restrictions": {
            "allowed_ips": ["10.0.1.0/24"],  # Engineering subnet
            "max_requests_per_minute": 100
        }
    }
).json()

# Check permissions for a user
permissions = requests.get(
    f"https://api.parrotrouter.com/v1/users/{user_id}/permissions",
    headers={"Authorization": "Bearer your-admin-key"},
    params={
        "team_id": team_id,
        "resource": "model:gpt-4-turbo-preview",
        "action": "use"
    }
).json()

print(f"Can use GPT-4? {permissions['allowed']}")
print(f"Conditions: {permissions['conditions']}")

SSO & SCIM Integration

# Configure SSO with SAML
sso_config = {
    "provider": "okta",
    "enabled": True,
    "settings": {
        "sso_url": "https://acme.okta.com/app/parrotrouter/sso/saml",
        "issuer": "http://www.okta.com/exk1fxpiewvjfH0h7",
        "x509_cert": "-----BEGIN CERTIFICATE-----
MIID...
-----END CERTIFICATE-----",
        "attribute_mapping": {
            "email": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress",
            "name": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name",
            "groups": "http://schemas.xmlsoap.org/claims/Group"
        },
        "role_mapping": {
            "Engineering": "developer",
            "Engineering-Leads": "team_lead",
            "IT-Admins": "org_admin"
        }
    },
    "provisioning": {
        "scim_enabled": True,
        "scim_base_url": "https://api.parrotrouter.com/scim/v2",
        "scim_bearer_token": "scim_token_secure_123",
        "auto_provision_users": True,
        "auto_deprovision_users": True,
        "sync_groups": True
    }
}

# Apply SSO configuration
requests.put(
    f"https://api.parrotrouter.com/v1/organizations/{org_id}/sso",
    headers={"Authorization": "Bearer your-admin-key"},
    json=sso_config
)

# SCIM user provisioning webhook handler
@app.post("/scim/v2/Users")
def scim_create_user(request):
    scim_user = request.json
    
    # Map SCIM attributes to ParrotRouter user
    user = {
        "email": scim_user["emails"][0]["value"],
        "name": f"{scim_user['name']['givenName']} {scim_user['name']['familyName']}",
        "external_id": scim_user["externalId"],
        "active": scim_user["active"],
        "groups": [g["value"] for g in scim_user.get("groups", [])]
    }
    
    # Create user in ParrotRouter
    created_user = create_user_with_sso(user)
    
    # Return SCIM response
    return {
        "schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
        "id": created_user["id"],
        "externalId": scim_user["externalId"],
        "meta": {
            "resourceType": "User",
            "created": created_user["created_at"],
            "location": f"/scim/v2/Users/{created_user['id']}"
        }
    }

Billing & Cost Management

Consolidated Billing

# Configure organization billing
billing_config = {
    "payment_methods": [
        {
            "type": "credit_card",
            "is_default": True,
            "details": {
                "stripe_payment_method_id": "pm_1234567890"
            }
        },
        {
            "type": "invoice",
            "is_default": False,
            "details": {
                "net_terms": 30,
                "purchase_order_required": True,
                "billing_address": {
                    "line1": "123 Main St",
                    "city": "New York",
                    "state": "NY",
                    "postal_code": "10001",
                    "country": "US"
                }
            }
        }
    ],
    "billing_alerts": [
        {
            "type": "threshold",
            "amount": 5000.00,
            "period": "monthly",
            "notify": ["finance@acme.com", "cfo@acme.com"]
        },
        {
            "type": "anomaly",
            "sensitivity": "high",
            "notify": ["security@acme.com"]
        },
        {
            "type": "budget_exceeded",
            "action": "notify",  # or "suspend"
            "notify": ["finance@acme.com", "team_leads"]
        }
    ],
    "cost_allocation": {
        "strategy": "tag_based",
        "required_tags": ["project", "environment", "team"],
        "cost_centers": {
            "engineering": "CC-001",
            "marketing": "CC-002",
            "data_science": "CC-003"
        }
    }
}

# Apply billing configuration
requests.put(
    f"https://api.parrotrouter.com/v1/organizations/{org_id}/billing",
    headers={"Authorization": "Bearer your-admin-key"},
    json=billing_config
)

Usage Tracking & Reporting

# Get organization-wide usage analytics
usage_analytics = requests.get(
    f"https://api.parrotrouter.com/v1/organizations/{org_id}/analytics",
    headers={"Authorization": "Bearer your-admin-key"},
    params={
        "period": "last_30_days",
        "metrics": [
            "total_requests",
            "total_tokens",
            "total_cost",
            "active_users",
            "model_distribution",
            "team_usage",
            "error_rate",
            "average_latency"
        ]
    }
).json()

# Generate usage report
report = requests.post(
    f"https://api.parrotrouter.com/v1/organizations/{org_id}/reports",
    headers={"Authorization": "Bearer your-admin-key"},
    json={
        "type": "usage_summary",
        "period": {
            "start": "2024-01-01",
            "end": "2024-01-31"
        },
        "format": "pdf",  # or "csv", "json"
        "sections": [
            "executive_summary",
            "team_breakdown",
            "model_usage",
            "cost_analysis",
            "user_activity",
            "api_performance",
            "security_events"
        ],
        "filters": {
            "teams": ["engineering", "data_science"],
            "min_cost": 0.01  # Exclude trivial usage
        },
        "delivery": {
            "email": ["cfo@acme.com", "cto@acme.com"],
            "webhook": "https://acme.com/webhooks/reports"
        }
    }
).json()

print(f"Report generated: {report['url']}")

# Set up automated reporting
requests.post(
    f"https://api.parrotrouter.com/v1/organizations/{org_id}/reports/schedule",
    headers={"Authorization": "Bearer your-admin-key"},
    json={
        "name": "Monthly Executive Report",
        "schedule": "0 8 1 * *",  # 8 AM on 1st of month
        "report_config": {
            "type": "executive_summary",
            "period": "previous_month",
            "format": "pdf"
        },
        "recipients": ["executives@acme.com"],
        "enabled": True
    }
)

Compliance & Auditing

Audit Logging

# Configure audit logging
audit_config = {
    "enabled": True,
    "retention_days": 365,  # 1 year retention
    "events_to_log": [
        "authentication.*",
        "authorization.*",
        "api_key.*",
        "team.*",
        "member.*",
        "billing.*",
        "settings.*",
        "data_access.*",
        "security.*"
    ],
    "export_destinations": [
        {
            "type": "s3",
            "bucket": "acme-audit-logs",
            "prefix": "parrotrouter/",
            "encryption": "AES256"
        },
        {
            "type": "siem",
            "endpoint": "https://siem.acme.com/api/logs",
            "api_key": "siem_key_123",
            "format": "json"
        }
    ],
    "compliance": {
        "standards": ["SOC2", "ISO27001", "HIPAA"],
        "data_residency": "US",
        "encryption_at_rest": True,
        "encryption_in_transit": True
    }
}

# Apply audit configuration
requests.put(
    f"https://api.parrotrouter.com/v1/organizations/{org_id}/audit",
    headers={"Authorization": "Bearer your-admin-key"},
    json=audit_config
)

# Query audit logs
audit_logs = requests.get(
    f"https://api.parrotrouter.com/v1/organizations/{org_id}/audit/logs",
    headers={"Authorization": "Bearer your-admin-key"},
    params={
        "start_time": "2024-01-01T00:00:00Z",
        "end_time": "2024-01-31T23:59:59Z",
        "event_types": ["api_key.created", "member.role_changed"],
        "actors": ["user:alice@acme.com"],
        "resources": ["team:engineering"],
        "limit": 100
    }
).json()

# Generate compliance report
compliance_report = requests.post(
    f"https://api.parrotrouter.com/v1/organizations/{org_id}/compliance/report",
    headers={"Authorization": "Bearer your-admin-key"},
    json={
        "type": "SOC2_Type2",
        "period": {
            "start": "2023-01-01",
            "end": "2023-12-31"
        },
        "include_evidence": True,
        "auditor_access": {
            "email": "auditor@compliance-firm.com",
            "expires_in_days": 30
        }
    }
).json()

print(f"Compliance report ready: {compliance_report['secure_url']}")

Best Practices

  • 1.
    Principle of Least Privilege

    Grant minimum necessary permissions to users and teams

  • 2.
    Regular Access Reviews

    Audit and review user access quarterly

  • 3.
    Enable SSO & 2FA

    Use single sign-on and enforce two-factor authentication

  • 4.
    Budget Controls

    Set and monitor budgets for all teams

  • 5.
    Audit Everything

    Enable comprehensive audit logging for compliance

Related Documentation