Porta v1.11.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
namestring✅Organization display name
slugstringURL slug (auto-generated from name if omitted)
defaultLocalestringDefault locale (e.g., en)
defaultLoginMethodsstring[]Non-empty selection of password and magic_link
brandingobjectOptional initial branding settings
json
{
  "name": "Acme Corp",
  "defaultLocale": "en",
  "defaultLoginMethods": ["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"
}

Validate Slug ​

Check whether a slug can be assigned before creating an organization.

http
GET /api/admin/organizations/validate-slug?slug=acme-corp
InputResult
Well-formed and available200 { "isValid": true }
Well-formed but taken200 { "isValid": false, "error": "Slug already in use" }
Malformed or reserved400 with the standard validation error

new is reserved as a create-action segment and is rejected with 400. Only the exact word is reserved, so slugs such as new-york and renew remain valid.

An organization that already uses a reserved word as its slug keeps its data and remains reachable by UUID. The Admin API does not rename slugs; an operator can change the slug directly in the database when needed.

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
sortBystringSort field (name, created_at)
sortOrderstringSort 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
defaultLocalestringDefault locale
defaultLoginMethodsstring[]Non-empty selection of password and magic_link
brandingobjectNested branding fields; use null to clear an optional field

The optional branding object accepts logoUrl, faviconUrl, primaryColor, companyName, and customCss. Image URLs are fallbacks for organizations without an uploaded asset. Porta accepts HTTPS URLs. In non-production environments it also accepts HTTP URLs for exact loopback hosts only. Credentials in image URLs and other URL schemes are rejected.

Response: 200 OK — { "data": <updated organization> }.

Suspend Organization ​

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

Suspends the organization. All authentication requests will be rejected.

Response: 204 No Content

Activate Organization ​

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

Reactivates a suspended organization.

Response: 204 No Content

Update Branding ​

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

Request body:

FieldTypeDescription
logoUrlstring or nullExternal fallback logo URL, or null to clear it
faviconUrlstring or nullExternal fallback favicon URL, or null to clear it
primaryColorstring or nullSix-digit hex color such as #0078d4, or null
companyNamestring or nullCompany display name, or null to use the organization name
customCssstring or nullExisting custom template CSS, up to 10 KB

Uploaded logo and favicon assets take precedence over logoUrl and faviconUrl. The URLs remain configured fallbacks and are used again if the matching uploaded asset is deleted.

Permission: admin:org:update

Response: 200 OK — { "data": <updated organization> }.

The SDK exposes the same operation as porta.branding.updateSettings(organizationId, input) and returns the complete updated Organization. Branding settings are otherwise read from the organization resource; there is no separate branding-settings read endpoint. GET /:id/branding belongs to the branding-assets API and returns asset metadata.

Delete Organization ​

http
DELETE /api/admin/organizations/:idOrSlug

Permanently deletes an organization and its owned users, clients, assignments, credentials, and security data in one database transaction. Affected sessions are revoked. The super-admin organization is protected and cannot be deleted.

Permission: admin:org:delete

Response: 204 No Content

The retained audit event follows the configured audit retention policy. It is not a surviving organization record.

Error responses:

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

Released under the MIT License.