Organization API
Organizations and Billing
Create organisations, switch active context, manage members, and administer Stripe Connect
This page documents the active-organisation model used by the enterprise reservation system. It covers organisation creation, membership, branding, billing-safe defaults, and the admin-only Stripe Connect routes.
JWT or user API keyPlan limitsActive organisationStripe Connect
Source
- Main controller:
backend-nestjs/src/organisations/organisations.controller.ts - Membership DTOs:
backend-nestjs/src/dto/organisation-user.dto.ts - Organisation DTOs:
backend-nestjs/src/dto/organisation.dto.ts - Billing DTOs:
backend-nestjs/src/dto/organisation-stripe.dto.ts
Authentication and Permissions
- All routes on this page require authentication.
- The main controller uses
JwtAuthGuardplusRbacAuthorizationGuard. - Additional route-level enforcement uses organisation ownership checks, organisation-scope decorators, role requirements, and permission decorators.
- Tenant isolation comes from validated organisation membership and the authenticated user's active organisation, never from arbitrary client input.
Plan Limits
Store: the current user may own 1 active organisationEnterprise: the current user may own up to 5 active organisations
These limits are enforced in the application layer and backed by the ownership model in the database.
Endpoint Reference
Core Organisation Surface
| Method | Path | Purpose | Request or query | Auth | Source |
|---|---|---|---|---|---|
POST | /api/organisations | Create an organisation owned by the current user. | Body: organisation fields | JWT or user API key | organisations/organisations.controller.ts |
GET | /api/organisations | List organisations accessible to the current user. | None | JWT or user API key | organisations/organisations.controller.ts |
PATCH | /api/organisations/active | Switch the authenticated user's active organisation. | Body: organisationId | JWT or user API key | organisations/organisations.controller.ts |
GET | /api/organisations/:id | Get one accessible organisation. | Path: id | JWT or user API key | organisations/organisations.controller.ts |
PATCH | /api/organisations/:id | Update organisation profile fields. | Path: id, body: profile fields | JWT or user API key | organisations/organisations.controller.ts |
DELETE | /api/organisations/:id | Archive an organisation. | Path: id | JWT or user API key | organisations/organisations.controller.ts |
PATCH | /api/organisations/:id/billing | Update billing-safe organisation settings. | Path: id, body: defaultCurrency | JWT or user API key | organisations/organisations.controller.ts |
GET | /api/organisations/:id/stripe/status | Read the Stripe Connect state for an organisation. | Path: id | JWT or user API key | organisations/organisations.controller.ts |
POST | /api/organisations/:id/stripe/onboarding-link | Create or refresh a Stripe onboarding link. | Path: id | JWT or user API key | organisations/organisations.controller.ts |
POST | /api/organisations/:id/stripe/dashboard-link | Create a Stripe dashboard login link. | Path: id | JWT or user API key | organisations/organisations.controller.ts |
POST | /api/organisations/:id/stripe/disconnect | Disconnect the stored Stripe account from the organisation. | Path: id | JWT or user API key | organisations/organisations.controller.ts |
PATCH | /api/organisations/:id/color | Update the organisation color. | Path: id, body: color,cascadeToResourceTypes | JWT or user API key | organisations/organisations.controller.ts |
Membership Surface
| Method | Path | Purpose | Request or query | Auth | Source |
|---|---|---|---|---|---|
POST | /api/organisations/:id/users | Assign a user to the organisation. | Path: id, body: userId | JWT or user API key | organisations/organisations.controller.ts |
DELETE | /api/organisations/:id/users/:userId | Remove a user from the organisation. | Path: id,userId | JWT or user API key | organisations/organisations.controller.ts |
POST | /api/organisations/:id/users/assign | Assign a user with an explicit role. | Path: id, body: userId,role,assignedById? | JWT or user API key | organisations/organisations.controller.ts |
GET | /api/organisations/:id/users/list | List organisation users and roles. | Path: id | JWT or user API key | organisations/organisations.controller.ts |
PATCH | /api/organisations/:id/users/:userId/role | Update a member role. | Path: id,userId, body: role | JWT or user API key | organisations/organisations.controller.ts |
DELETE | /api/organisations/:id/users/:userId/remove | Remove a member through the alternate removal path. | Path: id,userId | JWT or user API key | organisations/organisations.controller.ts |
Request Shapes
Organization profile
CreateOrganisationDto and UpdateOrganisationDto
name: required on createdescription: optional stringaddress: optional stringphone: optional stringemail: optional emailslug: optional kebab-case public booking sluglogoUrl: optional public logo URLpublicBookingHeadline: optional public page headlinepublicBookingDescription: optional public page descriptionisActive: update-only optional boolean
Active organisation
SetActiveOrganisationDto
organisationId: required positive integer
Membership
AssignUserDto.userId: required numberAssignOrganisationUserDto.userId: required numberAssignOrganisationUserDto.role: requiredOrganisationRoleTypeAssignOrganisationUserDto.assignedById: optional numberUpdateOrganisationUserRoleDto.role: requiredOrganisationRoleType
Billing and Stripe
UpdateOrganisationBillingDto
defaultCurrency: optional Stripe-supported three-letter currency code
Example Calls
Create an organisation
curl -X POST "$PRIMECAL_API/api/organisations" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Primecal Store Budapest",
"slug": "primecal-store-budapest",
"publicBookingHeadline": "Book your table",
"publicBookingDescription": "Choose a time and pay only when required."
}'
Switch the active organisation
curl -X PATCH "$PRIMECAL_API/api/organisations/active" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"organisationId": 12
}'
Create a Stripe onboarding link
curl -X POST "$PRIMECAL_API/api/organisations/12/stripe/onboarding-link" \
-H "Authorization: Bearer $TOKEN"
Example response:
{
"url": "https://connect.stripe.com/setup/...",
"stripeAccountId": "acct_1234567890",
"stripeConnectStatus": "pending"
}
Read Stripe status
curl "$PRIMECAL_API/api/organisations/12/stripe/status" \
-H "Authorization: Bearer $TOKEN"
Example response:
{
"organisationId": 12,
"stripeAccountId": "acct_1234567890",
"stripeConnectStatus": "active",
"defaultCurrency": "eur",
"chargesEnabled": true,
"payoutsEnabled": true,
"detailsSubmitted": true,
"requiresOnboarding": false,
"currentlyDue": [],
"pendingVerification": [],
"disabledReason": null
}
Response and Behavior Notes
GET /api/organisationsreturns membership-aware records including role, owner state, and active-organisation state.DELETE /api/organisations/:idarchives the organisation instead of hard-deleting it.- Resource, reservation, and MCP enterprise flows depend on the caller's active organisation, so switching context is part of the expected API usage.
- Stripe status reads can sync the stored state from Stripe before the response is returned.
- The organisation billing UI uses the status route and the organisation read route in parallel so admins can review Stripe readiness and billing defaults in one screen.
Best Practices
- Set the active organisation explicitly at session start in multi-org clients.
- Keep Stripe onboarding and billing routes admin-only in your UI as well as in the API.
- Use role-based membership endpoints instead of encoding organisation access in client state.
- Treat public booking slug and branding fields as customer-facing product content that deserves review before publishing.