Organizations API
Organizations are the soft B2B grouping layer inside an Auris Tenant (teams / departments). They are not hard customer isolation. For MSP multi-customer workloads, create one Tenant per customer. Users can belong to multiple organizations with different roles in each.
Organization member roles: OWNER (full control), ADMIN (manage members and settings), MEMBER (standard access), VIEWER (read-only).
All endpoints require the x-tenant header and the admin:all permission unless noted otherwise.
Organization CRUD
/api/organizationsRequires: admin:allList all organizations in the tenant. Returns summary information including member count and whether any SSO connection is configured.
Query parameters
| Parameter | Type | Description |
|---|---|---|
page | integer | Page number (default: 1) |
limit | integer | Items per page (default: 20) |
search | string | Search by organization name or display name |
Success response
{
"ok": true,
"data": {
"data": [
{
"id": "org_abc123",
"name": "acme-corp",
"displayName": "Acme Corporation",
"memberCount": 45,
"hasSso": true,
"createdAt": "2025-01-01T00:00:00Z"
}
],
"pagination": { "page": 1, "limit": 20, "total": 12, "totalPages": 1 }
}
}/api/organizationsRequires: admin:allCreate a new organization. The name is a machine-readable identifier (lowercase, hyphens
allowed) that must be unique within the tenant. The displayName is the human-readable name
shown in the UI.
Request body
{
"name": "acme-corp",
"displayName": "Acme Corporation",
"metadata": {
"industry": "Manufacturing",
"country": "US"
}
}displayName and metadata are optional.
Success response
{
"ok": true,
"data": {
"id": "org_def456",
"name": "acme-corp",
"displayName": "Acme Corporation",
"metadata": { "industry": "Manufacturing", "country": "US" },
"memberCount": 0,
"createdAt": "2025-02-18T10:00:00Z"
}
}Error codes
| Code | HTTP | Description |
|---|---|---|
NAME_TAKEN | 409 | An organization with this name already exists |
VALIDATION_ERROR | 400 | Invalid organization name (must be lowercase alphanumeric with hyphens) |
/api/organizations/[id]Requires: admin:allGet full details for an organization, including metadata and SSO status.
Success response
{
"ok": true,
"data": {
"id": "org_abc123",
"name": "acme-corp",
"displayName": "Acme Corporation",
"metadata": { "industry": "Manufacturing" },
"memberCount": 45,
"hasSso": true,
"ssoProvider": "saml",
"verifiedDomains": ["acme-corp.com"],
"createdAt": "2025-01-01T00:00:00Z",
"updatedAt": "2025-02-01T12:00:00Z"
}
}/api/organizations/[id]Requires: admin:allUpdate an organization’s display name or metadata. The name (machine identifier) cannot be
changed after creation.
Request body
{
"displayName": "Acme Corp International",
"metadata": {
"industry": "Manufacturing",
"country": "US",
"tier": "enterprise"
}
}Success response
{
"ok": true,
"data": {
"id": "org_abc123",
"displayName": "Acme Corp International",
"metadata": { "industry": "Manufacturing", "country": "US", "tier": "enterprise" }
}
}/api/organizations/[id]Requires: admin:allDelete an organization. All members are removed from the organization. SSO connections and domain verifications are deleted. User accounts themselves are not deleted.
Success response
{
"ok": true,
"data": { "deleted": true }
}Member Management
/api/organizations/[id]/membersRequires: admin:allList all members of an organization with their roles and join dates.
Query parameters
| Parameter | Type | Description |
|---|---|---|
page | integer | Page number (default: 1) |
limit | integer | Items per page (default: 20) |
role | OWNER | ADMIN | MEMBER | VIEWER | Filter by role |
Success response
{
"ok": true,
"data": {
"data": [
{
"userId": "usr_abc123",
"email": "[email protected]",
"firstName": "Alice",
"lastName": "Smith",
"role": "ADMIN",
"joinedAt": "2025-01-15T10:00:00Z"
}
],
"pagination": { "page": 1, "limit": 20, "total": 45, "totalPages": 3 }
}
}/api/organizations/[id]/membersRequires: admin:allAdd an existing user (by user ID) to the organization with a specified role. To add users who do not yet have an account, use the invitation endpoints instead.
Request body
{
"userId": "usr_abc123",
"role": "MEMBER"
}Success response
{
"ok": true,
"data": {
"userId": "usr_abc123",
"role": "MEMBER",
"joinedAt": "2025-02-18T11:00:00Z"
}
}Error codes
| Code | HTTP | Description |
|---|---|---|
USER_NOT_FOUND | 404 | User does not exist in this tenant |
ALREADY_MEMBER | 409 | User is already a member of this organization |
/api/organizations/[id]/members/[userId]Requires: admin:allUpdate a member’s role within the organization. Only OWNER and ADMIN members can be changed. An organization must always have at least one OWNER.
Request body
{
"role": "ADMIN"
}Success response
{
"ok": true,
"data": {
"userId": "usr_abc123",
"role": "ADMIN",
"updatedAt": "2025-02-18T12:00:00Z"
}
}Error codes
| Code | HTTP | Description |
|---|---|---|
LAST_OWNER | 400 | Cannot remove the last OWNER from an organization |
/api/organizations/[id]/members/[userId]Requires: admin:allRemove a member from the organization. The user’s account is not deleted.
Success response
{
"ok": true,
"data": { "removed": true }
}Invitations
/api/organizations/[id]/invitationsRequires: admin:allList all pending invitations for an organization.
Success response
{
"ok": true,
"data": {
"data": [
{
"id": "inv_abc123",
"email": "[email protected]",
"role": "MEMBER",
"status": "pending",
"expiresAt": "2025-02-25T10:00:00Z",
"createdAt": "2025-02-18T10:00:00Z"
}
],
"pagination": { "page": 1, "limit": 20, "total": 2, "totalPages": 1 }
}
}Invitation statuses: pending, accepted, expired, cancelled.
/api/organizations/[id]/invitationsRequires: admin:allInvite a user to the organization by email. An invitation email is sent with a token-based accept link. Invitations expire after 7 days. If the email is already associated with a tenant user, they are notified directly. If not, they are prompted to create an account first.
Request body
{
"email": "[email protected]",
"role": "MEMBER"
}Success response
{
"ok": true,
"data": {
"id": "inv_def456",
"email": "[email protected]",
"role": "MEMBER",
"expiresAt": "2025-02-25T10:00:00Z"
}
}Error codes
| Code | HTTP | Description |
|---|---|---|
ALREADY_MEMBER | 409 | Email is already an active member of this organization |
INVITATION_PENDING | 409 | A pending invitation already exists for this email |
/api/organizations/[id]/invitations/[invId]Requires: admin:allCancel a pending invitation. The invitation link in the email becomes invalid immediately.
Success response
{
"ok": true,
"data": { "cancelled": true }
}Enterprise SSO
Enterprise SSO (Single Sign-On) allows organization members to authenticate using their existing identity provider (IdP) — either SAML 2.0 or OIDC-based. SSO connections are scoped to an organization and trigger automatically when users log in with a verified domain email.
All SSO endpoints require manage:sso_connections.
/api/organizations/[orgId]/sso/connectionsRequires: manage:sso_connectionsList all SSO connections configured for an organization.
Success response
{
"ok": true,
"data": [
{
"id": "sso_abc123",
"type": "saml",
"status": "ACTIVE",
"keycloakIdpAlias": "acme-saml",
"domains": ["acme-corp.com"],
"createdAt": "2025-01-20T09:00:00Z"
}
]
}SSO connection statuses: PENDING (configured but not activated), ACTIVE, DISABLED, ERROR.
/api/organizations/[orgId]/sso/connectionsRequires: manage:sso_connectionsCreate a new SSO connection. For SAML, provide the IdP metadata URL or raw XML. For OIDC, provide the discovery URL and client credentials.
Request body — SAML
{
"type": "saml",
"name": "Acme Corporate IdP",
"config": {
"metadataUrl": "https://idp.acme-corp.com/metadata",
"entityId": "https://idp.acme-corp.com",
"ssoUrl": "https://idp.acme-corp.com/sso",
"certificate": "-----BEGIN CERTIFICATE-----\n..."
}
}Request body — OIDC
{
"type": "oidc",
"name": "Acme OIDC",
"config": {
"discoveryUrl": "https://login.acme-corp.com/.well-known/openid-configuration",
"clientId": "auris-sp-client",
"clientSecret": "sp-client-secret"
}
}Success response
{
"ok": true,
"data": {
"id": "sso_def456",
"type": "saml",
"status": "PENDING",
"keycloakIdpAlias": "acme-saml-def456",
"acsUrl": "https://api.altovar.net/api/auth/sso/callback",
"entityId": "https://api.altovar.net"
}
}The acsUrl (Assertion Consumer Service URL) and entityId are values you provide to the IdP
during SP configuration.
/api/organizations/[orgId]/sso/connections/[id]/activateRequires: manage:sso_connectionsActivate an SSO connection. After activation, users with a verified domain email are automatically redirected to the SSO provider at login.
Request: No body required.
Success response
{
"ok": true,
"data": { "activated": true, "status": "ACTIVE" }
}/api/organizations/[orgId]/sso/connections/[id]/deactivateRequires: manage:sso_connectionsDeactivate an SSO connection. Users with domain emails will fall back to standard password authentication until SSO is re-activated.
Request: No body required.
Success response
{
"ok": true,
"data": { "deactivated": true, "status": "DISABLED" }
}Domain Verification
Domain verification proves that you control a domain before enabling SSO-based auto-redirect for email addresses on that domain. Verification is done via a DNS TXT record.
/api/organizations/[orgId]/sso/domainsRequires: manage:sso_connectionsList all domains associated with an organization’s SSO configuration, including verification status.
Success response
{
"ok": true,
"data": [
{
"id": "dom_abc123",
"domain": "acme-corp.com",
"status": "ACTIVE",
"verificationMethod": "TXT",
"verificationToken": "auris-verify-abc123def456",
"verifiedAt": "2025-01-22T14:00:00Z"
}
]
}Domain verification statuses: PENDING, VERIFYING, ACTIVE, FAILED.
/api/organizations/[orgId]/sso/domainsRequires: manage:sso_connectionsAdd a domain and initiate verification. A verificationToken is returned that must be added
as a DNS TXT record on the domain. Then call the check endpoint to confirm.
Request body
{
"domain": "acme-corp.com"
}Success response
{
"ok": true,
"data": {
"id": "dom_def456",
"domain": "acme-corp.com",
"status": "PENDING",
"verificationMethod": "TXT",
"verificationToken": "auris-verify-ghi789jkl012",
"dnsRecord": {
"type": "TXT",
"host": "_auris-verify.acme-corp.com",
"value": "auris-verify-ghi789jkl012"
}
}
}Add the DNS TXT record shown in dnsRecord at your domain registrar, then call the check endpoint.
/api/organizations/[orgId]/sso/domains/[id]/checkRequires: manage:sso_connectionsTrigger DNS verification for a domain. Auris performs a live DNS TXT lookup to check for the verification token. Returns the new status immediately.
Request: No body required.
Success response — verified
{
"ok": true,
"data": {
"domain": "acme-corp.com",
"status": "ACTIVE",
"verifiedAt": "2025-02-18T15:00:00Z"
}
}Success response — not yet propagated
{
"ok": true,
"data": {
"domain": "acme-corp.com",
"status": "PENDING",
"message": "TXT record not found yet. DNS propagation can take up to 48 hours."
}
}DNS propagation typically takes minutes but can take up to 48 hours in rare cases. Call the check endpoint periodically until the status transitions to ACTIVE.
Related
- Multi-Tenancy — How organizations map to Auris tenants
- B2B Multi-Tenant Guide — Set up multi-organization architecture
- Enterprise SSO — Configure SSO for organization members
- Organizations — Manage organizations from the Console
- SSO API — Enterprise SSO connection endpoints