⚠️ Porta is in beta — APIs and features may change before v1.0
Skip to content

Organizations API

Manage tenant organizations. Each organization represents an isolated tenant with its own users, clients, and configuration.

Base path: /api/admin/organizations

Create Organization

http
POST /api/admin/organizations

Request body:

FieldTypeRequiredDescription
namestringOrganization display name
slugstringURL slug (auto-generated from name if omitted)
default_localestringDefault locale (e.g., en)
default_login_methodsstring[]Login methods: ["password", "magic_link"]
json
{
  "name": "Acme Corp",
  "default_locale": "en",
  "default_login_methods": ["password", "magic_link"]
}

Response: 201 Created

json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "name": "Acme Corp",
  "slug": "acme-corp",
  "status": "active",
  "isSuperAdmin": false,
  "defaultLocale": "en",
  "defaultLoginMethods": ["password", "magic_link"],
  "createdAt": "2024-01-15T10:30:00.000Z",
  "updatedAt": "2024-01-15T10:30:00.000Z"
}

List Organizations

http
GET /api/admin/organizations

Query parameters:

ParameterTypeDescription
pageintegerPage number (default: 1)
pageSizeintegerItems per page (default: 20)
searchstringSearch by name or slug
statusstringFilter by status
sortstringSort field (name, createdAt)
orderstringSort direction (asc, desc)

Response: 200 OK

json
{
  "data": [
    {
      "id": "...",
      "name": "Acme Corp",
      "slug": "acme-corp",
      "status": "active",
      "isSuperAdmin": false,
      "createdAt": "2024-01-15T10:30:00.000Z"
    }
  ],
  "pagination": {
    "total": 5,
    "page": 1,
    "pageSize": 20,
    "totalPages": 1
  }
}

Get Organization

http
GET /api/admin/organizations/:id

Response: 200 OK — Full organization object including branding fields.

Update Organization

http
PUT /api/admin/organizations/:id

Request body: Any subset of mutable fields:

FieldTypeDescription
namestringDisplay name
default_localestringDefault locale
default_login_methodsstring[]Default login methods

Response: 200 OK — Updated organization object.

Suspend Organization

http
POST /api/admin/organizations/:id/suspend

Suspends the organization. All authentication requests will be rejected.

Response: 200 OK

Activate Organization

http
POST /api/admin/organizations/:id/activate

Reactivates a suspended organization.

Response: 200 OK

Archive Organization

http
POST /api/admin/organizations/:id/archive

Permanently archives the organization. This action is irreversible.

Response: 200 OK

DANGER

Archiving is permanent. An archived organization cannot be reactivated.

Update Branding

http
PUT /api/admin/organizations/:id/branding

Request body:

FieldTypeDescription
logo_urlstringLogo URL
favicon_urlstringFavicon URL
primary_colorstringPrimary color (hex, e.g., #0078d4)
company_namestringCompany display name
custom_cssstringCustom CSS for login pages

Response: 200 OK — Updated organization with branding fields.

Get Branding

http
GET /api/admin/organizations/:id/branding

Response: 200 OK — Branding fields for the organization.

Destroy Organization

http
DELETE /api/admin/organizations/:idOrSlug

Permanently hard-deletes an organization and all child entities via PostgreSQL CASCADE. The super-admin organization is protected and cannot be deleted.

Permission: ORG_ARCHIVE

Query parameters:

ParameterTypeDescription
dry-runbooleanIf true, return cascade counts without deleting

Dry Run Response

http
DELETE /api/admin/organizations/acme?dry-run=true

Response: 200 OK

json
{
  "dryRun": true,
  "organization": { "id": "...", "name": "Acme Corp", "slug": "acme", "..." },
  "cascadeCounts": {
    "applications": 3,
    "clients": 5,
    "users": 42,
    "roles": 8,
    "permissions": 16,
    "claim_definitions": 4
  }
}

Destroy Response

http
DELETE /api/admin/organizations/acme

Response: 200 OK

json
{
  "organization": { "id": "...", "name": "Acme Corp", "slug": "acme", "..." },
  "cascadeCounts": {
    "applications": 3,
    "clients": 5,
    "users": 42,
    "roles": 8,
    "permissions": 16,
    "claim_definitions": 4
  }
}

Error responses:

StatusCondition
400Attempting to destroy the super-admin organization
404Organization not found

Released under the MIT License.