Organizations
Manage tenant organizations via the Provisioning API.
The Provisioning API is used by Super Terra (the parent platform) to create and manage Courimax tenants. All provisioning endpoints require the X-Provisioning-Secret header.
List Organizations
GET /provisioning/organizationsHeaders
| Header | Required | Description |
|---|---|---|
X-Provisioning-Secret | Yes | Provisioning secret |
Example
curl -X GET "https://api.courimax.com/api/provisioning/organizations" \
-H "X-Provisioning-Secret: your_provisioning_secret"
Response (200 OK)
[
{
"id": "org-uuid",
"slug": "acme-corp",
"name": "Acme Corporation",
"isActive": true,
"createdAt": "2026-08-19T10:00:00.000Z",
"counts": {
"members": 5,
"drivers": 12,
"orders": 342
},
"admins": [
{
"id": "user-uuid",
"email": "admin@acme.com",
"name": "John Doe",
"orgRole": "admin",
"invitePending": false
}
]
}
]
Create Organization
POST /provisioning/organizationsHeaders
| Header | Required | Description |
|---|---|---|
X-Provisioning-Secret | Yes | Provisioning secret |
Content-Type | Yes | application/json |
Body Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Organization name |
slug | string | No | URL-safe slug (auto-generated if not provided) |
admin.email | string | Yes | First admin's email |
admin.name | string | No | First admin's name |
Example
curl -X POST "https://api.courimax.com/api/provisioning/organizations" \
-H "X-Provisioning-Secret: your_provisioning_secret" \
-H "Content-Type: application/json" \
-d '{
"name": "Acme Corporation",
"slug": "acme-corp",
"admin": {
"email": "admin@acme.com",
"name": "John Doe"
}
}'
Response (201 Created)
{
"organization": {
"id": "org-uuid",
"slug": "acme-corp",
"name": "Acme Corporation",
"isActive": true,
"createdAt": "2026-08-19T10:00:00.000Z"
},
"admin": {
"id": "user-uuid",
"email": "admin@acme.com",
"name": "John Doe",
"isNewUser": true
},
"invite": {
"expiresAt": "2026-08-26T10:00:00.000Z",
"emailSent": true
}
}
Response Fields
| Field | Type | Description |
|---|---|---|
organization | object | Created organization |
admin | object | Admin user details |
admin.isNewUser | boolean | Whether admin is a new user |
invite | object | Invite details (null if user already exists) |
invite.expiresAt | string | Invite expiration (7 days) |
invite.emailSent | boolean | Whether invite email was sent |
Error Responses
400 Bad Request - Validation error
{
"statusCode": 400,
"message": "Organization name is required",
"error": "Bad Request"
}
409 Conflict - Slug already taken
{
"statusCode": 400,
"message": "Slug \"acme-corp\" is already taken",
"error": "Bad Request"
}
Add Admin
POST /provisioning/organizations/:id/adminsPath Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Organization ID |
Headers
| Header | Required | Description |
|---|---|---|
X-Provisioning-Secret | Yes | Provisioning secret |
Content-Type | Yes | application/json |
Body Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
email | string | Yes | Admin email |
name | string | No | Admin name |
Example
curl -X POST "https://api.courimax.com/api/provisioning/organizations/org-uuid/admins" \
-H "X-Provisioning-Secret: your_provisioning_secret" \
-H "Content-Type: application/json" \
-d '{
"email": "newadmin@acme.com",
"name": "Jane Smith"
}'
Response (201 Created)
{
"admin": {
"id": "user-uuid",
"email": "newadmin@acme.com",
"name": "Jane Smith",
"isNewUser": true,
"alreadyMember": false
},
"invite": {
"expiresAt": "2026-08-26T10:00:00.000Z",
"emailSent": true
}
}
Resend Invite
POST /provisioning/admins/:userId/resend-invitePath Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
userId | string | Yes | User ID |
Headers
| Header | Required | Description |
|---|---|---|
X-Provisioning-Secret | Yes | Provisioning secret |
Example
curl -X POST "https://api.courimax.com/api/provisioning/admins/user-uuid/resend-invite" \
-H "X-Provisioning-Secret: your_provisioning_secret"
Response (200 OK)
{
"admin": {
"id": "user-uuid",
"email": "admin@acme.com",
"name": "John Doe"
},
"invite": {
"expiresAt": "2026-08-26T10:00:00.000Z",
"emailSent": true
}
}
Reset Password
POST /provisioning/admins/:userId/reset-passwordPath Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
userId | string | Yes | User ID |
Headers
| Header | Required | Description |
|---|---|---|
X-Provisioning-Secret | Yes | Provisioning secret |
Content-Type | Yes | application/json |
Body Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
password | string | No | New password (auto-generated if not provided) |
Example
curl -X POST "https://api.courimax.com/api/provisioning/admins/user-uuid/reset-password" \
-H "X-Provisioning-Secret: your_provisioning_secret" \
-H "Content-Type: application/json" \
-d '{
"password": "NewSecurePassword123!"
}'
Response (200 OK)
{
"ok": true,
"email": "admin@acme.com"
}
If no password is provided, a secure temporary password is generated and returned.
Invite Acceptance
Get Invite
GET /provisioning/invite/:tokenThis endpoint is public (no authentication required) and is used to display invite details before acceptance.
curl -X GET "https://api.courimax.com/api/provisioning/invite/invite-token"
Accept Invite
POST /provisioning/invite/:token/acceptcurl -X POST "https://api.courimax.com/api/provisioning/invite/invite-token/accept" \
-H "Content-Type: application/json" \
-d '{
"password": "SecurePassword123!"
}'
Response (200 OK)
{
"ok": true,
"email": "admin@acme.com"
}
Rate Limiting
Provisioning endpoints have rate limits:
GET /organizations: 120 requests per hourPOST /organizations: 30 requests per hourPOST /organizations/:id/admins: 60 requests per hourPOST /admins/:userId/resend-invite: 30 requests per hourPOST /admins/:userId/reset-password: 30 requests per hour
Next Steps
- API Keys - Manage tenant API keys
- Authentication - Learn about API key usage