Skip to Content

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

GET/api/organizationsRequires: admin:all

List all organizations in the tenant. Returns summary information including member count and whether any SSO connection is configured.

Query parameters

ParameterTypeDescription
pageintegerPage number (default: 1)
limitintegerItems per page (default: 20)
searchstringSearch 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 } } }

POST/api/organizationsRequires: admin:all

Create 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

CodeHTTPDescription
NAME_TAKEN409An organization with this name already exists
VALIDATION_ERROR400Invalid organization name (must be lowercase alphanumeric with hyphens)

GET/api/organizations/[id]Requires: admin:all

Get 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" } }

PUT/api/organizations/[id]Requires: admin:all

Update 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" } } }

DELETE/api/organizations/[id]Requires: admin:all

Delete 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

GET/api/organizations/[id]/membersRequires: admin:all

List all members of an organization with their roles and join dates.

Query parameters

ParameterTypeDescription
pageintegerPage number (default: 1)
limitintegerItems per page (default: 20)
roleOWNER | ADMIN | MEMBER | VIEWERFilter 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 } } }

POST/api/organizations/[id]/membersRequires: admin:all

Add 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

CodeHTTPDescription
USER_NOT_FOUND404User does not exist in this tenant
ALREADY_MEMBER409User is already a member of this organization

PATCH/api/organizations/[id]/members/[userId]Requires: admin:all

Update 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

CodeHTTPDescription
LAST_OWNER400Cannot remove the last OWNER from an organization

DELETE/api/organizations/[id]/members/[userId]Requires: admin:all

Remove a member from the organization. The user’s account is not deleted.

Success response

{ "ok": true, "data": { "removed": true } }

Invitations

GET/api/organizations/[id]/invitationsRequires: admin:all

List 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.


POST/api/organizations/[id]/invitationsRequires: admin:all

Invite 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

CodeHTTPDescription
ALREADY_MEMBER409Email is already an active member of this organization
INVITATION_PENDING409A pending invitation already exists for this email

DELETE/api/organizations/[id]/invitations/[invId]Requires: admin:all

Cancel 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.

GET/api/organizations/[orgId]/sso/connectionsRequires: manage:sso_connections

List 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.


POST/api/organizations/[orgId]/sso/connectionsRequires: manage:sso_connections

Create 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.


POST/api/organizations/[orgId]/sso/connections/[id]/activateRequires: manage:sso_connections

Activate 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" } }

POST/api/organizations/[orgId]/sso/connections/[id]/deactivateRequires: manage:sso_connections

Deactivate 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.

GET/api/organizations/[orgId]/sso/domainsRequires: manage:sso_connections

List 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.


POST/api/organizations/[orgId]/sso/domainsRequires: manage:sso_connections

Add 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.


POST/api/organizations/[orgId]/sso/domains/[id]/checkRequires: manage:sso_connections

Trigger 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.