AgentPost
Guides

Managing Organizations

Team access, roles, environments, tiers, and governance

An organization is the top-level container for all AgentPost resources. This guide covers organization management: team roles, member invitations, environment setup, tier limits, governance policies, and audit logging.

Organization structure

Organization (AcmeCo)
  |-- Owner: [email protected]
  |-- Admin: [email protected]
  |-- Member: [email protected]
  |
  |-- Environments
  |     |-- Production (default)
  |     +-- Staging
  |
  |-- API Keys
  |-- Inboxes, Messages, Threads...
  |-- Webhook Endpoints
  |-- Custom Domains
  |-- Governance Policies
  |-- Audit Log

Roles

RolePermissions
OwnerFull access. Can transfer ownership, manage billing, delete the org. Only one owner per org.
AdminFull resource access. Can manage members, environments, domains, and governance policies. Cannot transfer ownership or delete the org.
MemberStandard resource access. Can use inboxes, send/read messages, manage labels. Cannot manage members or governance.

Inviting members

import AgentPost from 'agentpost';

const client = new AgentPost({ apiKey: 'ap_sk_...' });

// Invite a new team member
const invitation = await client.org.invite({
  email: '[email protected]',
  role: 'member',
});

console.log(`Invitation sent: ${invitation.id}`);
console.log(`Status: ${invitation.status}`); // "pending"
from agentpost import AgentPost

client = AgentPost(api_key="ap_sk_...")

invitation = client.org.invite(
    email="[email protected]",
    role="member",
)

print(f"Invitation sent: {invitation.id}")
curl -X POST https://api.agent-post.dev/api/v1/org/invitations \
  -H "Authorization: Bearer $AGENTPOST_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"email": "[email protected]", "role": "member"}'

Managing invitations

// List pending invitations
const invitations = await client.org.listInvitations();

// Revoke an invitation
await client.org.revokeInvitation('inv_abc123');
invitations = client.org.list_invitations()
client.org.revoke_invitation("inv_abc123")
# List invitations
curl "https://api.agent-post.dev/api/v1/org/invitations" \
  -H "Authorization: Bearer $AGENTPOST_API_KEY"

# Revoke an invitation
curl -X POST "https://api.agent-post.dev/api/v1/org/invitations/inv_abc123/revoke" \
  -H "Authorization: Bearer $AGENTPOST_API_KEY"

Managing members

// List all members
const members = await client.org.listMembers();

// Update a member's role
await client.org.updateMember('mem_abc123', { role: 'admin' });

// Remove a member
await client.org.removeMember('mem_abc123');
members = client.org.list_members()
client.org.update_member("mem_abc123", role="admin")
client.org.remove_member("mem_abc123")
# List members
curl "https://api.agent-post.dev/api/v1/org/members" \
  -H "Authorization: Bearer $AGENTPOST_API_KEY"

# Update role
curl -X PATCH "https://api.agent-post.dev/api/v1/org/members/mem_abc123" \
  -H "Authorization: Bearer $AGENTPOST_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"role": "admin"}'

# Remove member
curl -X DELETE "https://api.agent-post.dev/api/v1/org/members/mem_abc123" \
  -H "Authorization: Bearer $AGENTPOST_API_KEY"

Tier limits

Organizations have tiers that determine resource limits:

ResourceFreeStarterTeamEnterprise
Inboxes525100Unlimited
Domains1520Unlimited
Members21050Unlimited
Environments1310Unlimited
Webhook endpoints31050Unlimited
Daily sends1001,00010,000Unlimited

Checking usage

const usage = await client.org.getUsage();

console.log(`Inboxes: ${usage.inboxes.used}/${usage.inboxes.limit}`);
console.log(`Daily sends: ${usage.daily_sends.used}/${usage.daily_sends.limit}`);
console.log(`Members: ${usage.members.used}/${usage.members.limit}`);
usage = client.org.get_usage()

print(f"Inboxes: {usage.inboxes['used']}/{usage.inboxes['limit']}")
print(f"Daily sends: {usage.daily_sends['used']}/{usage.daily_sends['limit']}")
curl "https://api.agent-post.dev/api/v1/org/usage" \
  -H "Authorization: Bearer $AGENTPOST_API_KEY"

Requesting a tier upgrade

await client.org.requestUpgrade({
  requested_tier: 'team',
  reason: 'Growing team needs more inboxes and higher send limits',
});
client.org.request_upgrade(
    requested_tier="team",
    reason="Growing team needs more inboxes and higher send limits",
)
curl -X POST "https://api.agent-post.dev/api/v1/org/upgrade-request" \
  -H "Authorization: Bearer $AGENTPOST_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"requested_tier": "team", "reason": "Growing team needs more inboxes"}'

Governance policies

Configure organization-wide policies for security and compliance:

// Get current policies
const policies = await client.org.getPolicies();

// Update policies
await client.org.updatePolicies({
  require_mfa: true,
  session_timeout_hours: 8,
  api_key_max_age_days: 90,
  ip_allowlist_enabled: true,
});
policies = client.org.get_policies()

client.org.update_policies(
    require_mfa=True,
    session_timeout_hours=8,
    api_key_max_age_days=90,
    ip_allowlist_enabled=True,
)
# Get policies
curl "https://api.agent-post.dev/api/v1/org/policies" \
  -H "Authorization: Bearer $AGENTPOST_API_KEY"

# Update policies
curl -X PATCH "https://api.agent-post.dev/api/v1/org/policies" \
  -H "Authorization: Bearer $AGENTPOST_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"require_mfa": true, "session_timeout_hours": 8}'

IP allowlist

Restrict API access to specific IP addresses or CIDR ranges:

// Add an IP to the allowlist
await client.org.addIpAllowlistEntry({
  cidr: '203.0.113.0/24',
  description: 'Office network',
});

// List allowlist entries
const entries = await client.org.listIpAllowlist();
client.org.add_ip_allowlist_entry(
    cidr="203.0.113.0/24",
    description="Office network",
)

entries = client.org.list_ip_allowlist()
curl -X POST "https://api.agent-post.dev/api/v1/org/ip-allowlist" \
  -H "Authorization: Bearer $AGENTPOST_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"cidr": "203.0.113.0/24", "description": "Office network"}'

Audit log

View a record of all actions performed within your organization:

const auditLog = await client.org.getAuditLog({
  limit: 50,
});

for (const entry of auditLog.data) {
  console.log(`${entry.created_at} | ${entry.actor_email} | ${entry.action} | ${entry.resource_type}`);
}
audit_log = client.org.get_audit_log(limit=50)

for entry in audit_log.data:
    print(f"{entry.created_at} | {entry.actor_email} | {entry.action}")
curl "https://api.agent-post.dev/api/v1/org/audit-log?limit=50" \
  -H "Authorization: Bearer $AGENTPOST_API_KEY"

Ownership transfer

Transfer organization ownership to another member:

// Initiate transfer
const transfer = await client.org.transferOwnership({
  new_owner_id: 'mem_bob123',
});

// The new owner must accept the transfer
// (done through the web console or API)
transfer = client.org.transfer_ownership(
    new_owner_id="mem_bob123",
)
curl -X POST "https://api.agent-post.dev/api/v1/org/transfer-ownership" \
  -H "Authorization: Bearer $AGENTPOST_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"new_owner_id": "mem_bob123"}'

SSO configuration

Configure Single Sign-On for enterprise organizations:

// Set up OIDC SSO
const ssoConfig = await client.org.createSsoConfig({
  protocol: 'oidc',
  issuer_url: 'https://auth.acmeco.com',
  client_id: 'your-client-id',
  client_secret: 'your-client-secret',
});

// Activate SSO
await client.org.activateSso(ssoConfig.id);
sso_config = client.org.create_sso_config(
    protocol="oidc",
    issuer_url="https://auth.acmeco.com",
    client_id="your-client-id",
    client_secret="your-client-secret",
)

client.org.activate_sso(sso_config.id)
# Create OIDC SSO configuration
curl -X POST "https://api.agent-post.dev/api/v1/org/sso" \
  -H "Authorization: Bearer $AGENTPOST_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "protocol": "oidc",
    "issuer_url": "https://auth.acmeco.com",
    "client_id": "your-client-id",
    "client_secret": "your-client-secret"
  }'

SSO supports both OIDC and SAML protocols. When SSO enforcement is enabled, all members (except the owner) must authenticate through the configured identity provider. JIT (Just-In-Time) provisioning automatically creates accounts for new SSO users.

Tips

  • The owner role cannot be shared -- there is exactly one owner per organization
  • Invitation counts include pending invitations when checking tier limits
  • Governance policies auto-create a row on first read (lazy initialization)
  • IP allowlist is integrated into auth middleware -- it checks after org resolution
  • Audit log retention varies by tier: 7 days (free) to 730 days (enterprise)
  • Ownership transfer is atomic: the old owner becomes an admin in the same transaction
  • SSO enforcement has an owner bypass for emergency access

On this page