# AI Booking Suggestions Source: https://learn.nexudus.com/api/endpoints/ai/ai-bookings GET /api/public/ai/bookings # AI Booking Suggestions Parses a natural language prompt into a structured booking intent, including time window, duration, party size, desired amenities, resource type, and notes. Use the parsed fields to prefill the bookings search UI. ## Authentication Requires an authenticated customer session. ## Query Parameters The user's natural language booking description. Example: "A meeting room for 10 with a projector next Tuesday 3–5pm". ## Response Structured booking intent. Resource type classification, e.g. "room|Meeting Room". Number of attendees. Desired booking duration in minutes. Preferred time window. Type of time constraint (e.g., fixed, range, recurring). ISO 8601 start datetime. ISO 8601 end datetime. Recurrence rule, if applicable. Named location reference, if extracted. Desired amenities (keys correspond to booking filters). Acceptable shift in start time, in minutes. Optional budget indication. Free-form notes extracted from the prompt. ## Example Response ```json theme={null} { "Response": { "resource_type": "room|Meeting Room", "partySize": 10, "durationMinutes": 120, "timeConstraints": { "kind": "fixed", "startISO": "2025-10-07T15:00:00.000Z", "endISO": "2025-10-07T17:00:00.000Z", "recurrence": "" }, "location": "Downtown", "amenities": ["VideoConferencing", "Projector"], "flexibilityMinutes": 30, "budget": 0, "notes": "Board presentation" } } ``` ## Usage in Portal * Public Bookings – Day and duration shortcuts * `src/views/public/bookings/components/DayAndDurationShortCuts.tsx` (applies AI intent to querystring) ## Related Endpoints * `GET /api/public/ai/chats/{sessionId}` – General-purpose assistant chat * `GET /api/public/ai/tariffs` – Plan suggestions by prompt * `GET /api/public/ai/products` – Product suggestions by prompt ## Error Responses The user is not authenticated. Missing or invalid prompt. # AI Chat Session Source: https://learn.nexudus.com/api/endpoints/ai/ai-chat GET /api/public/ai/chats/{sessionId} # AI Chat Session Starts or continues an AI assistant chat session scoped to the current location. Use it to ask free-form questions about plans, products, bookings, and general portal guidance. The session is identified by a client-generated `sessionId` and can optionally include the user's geolocation to tailor suggestions to nearby locations. Notes * This endpoint is read-only and returns generated text. * Pass the natural-language prompt as a query parameter. * If latitude/longitude are provided, responses may be adjusted to the nearest location. ## Authentication This endpoint requires an authenticated customer session (a logged-in customer of a location). ## Path Parameters Client-generated unique session identifier (for example, a UUID) that keeps the context across requests in the same conversation. ## Query Parameters The user's natural language question or instruction to the assistant. Optional current latitude to personalize responses. Optional current longitude to personalize responses. ## Response AI-generated reply text. Can include markdown. ## Example Response ```json theme={null} { "Response": "You can book a meeting room tomorrow afternoon. Would you like me to filter 8–10 people rooms with video conferencing?" } ``` ## Usage in Portal This endpoint is used by the floating AI assistant available across the portal: * Layouts * `src/layouts/DefaultLayout.tsx` (global assistant button) * `src/layouts/FullPageLayout.tsx` (global assistant button) * Dock * `src/components/Dock/DockSection.tsx` (mobile dock integration) * Chat manager * `src/components/ai/AiChatManager.tsx` (session handling and message flow) ## Related Endpoints * `GET /api/public/ai/tariffs` – Plan suggestions by prompt * `GET /api/public/ai/products` – Product suggestions by prompt * `GET /api/public/ai/bookings` – Booking suggestion intent parsing ## Error Responses The user is not authenticated as a customer of a location. Missing or invalid parameters (e.g., no prompt provided). # AI Product Suggestions Source: https://learn.nexudus.com/api/endpoints/ai/ai-products GET /api/public/ai/products # AI Product Suggestions Returns AI-generated suggestions for which store products (time passes, credits, etc.) best match a natural language prompt. The response includes both an explanation and a list of preferred product IDs. ## Authentication Requires an authenticated customer session. ## Query Parameters The user's natural language question or preference description. Example: "What's the most affordable product with weekend access?" ## Response AI result wrapper. Human-readable explanation answering the prompt. Product IDs recommended by the assistant. ## Example Response ```json theme={null} { "Response": { "Answer": "The 10-day pass is the most cost-effective for occasional weekend use.", "PreferredProductIds": [201, 208, 245] } } ``` ## Usage in Portal * Public Checkout – Products grid * `src/views/public/checkout/products/ProductsGrid.tsx` (filters product list by AI) * `src/views/checkout/steps/components/ProductAiPrompt.tsx` ## Related Endpoints * `GET /api/public/ai/tariffs` – Plan suggestions by prompt * `GET /api/public/ai/bookings` – Booking intent parsing and suggestions * `GET /api/public/ai/chats/{sessionId}` – General-purpose assistant chat ## Error Responses The user is not authenticated. Missing or invalid prompt. # AI Plan Suggestions Source: https://learn.nexudus.com/api/endpoints/ai/ai-tariffs GET /api/public/ai/tariffs # AI Plan Suggestions Returns AI-generated suggestions for which membership plans are most suitable based on a natural language prompt. The response includes an explanation and a list of preferred plan IDs that you can use to filter or preselect plans in the UI. Terminology * We refer to locations (backend term: businesses) as locations in this documentation. * We refer to customers (backend term: coworkers) as customers in this documentation. ## Authentication Requires an authenticated customer session. ## Query Parameters The user's natural language question or preference description. Example: "Which plan is best if I work 3 days a week and need meeting room access?" ## Response AI result wrapper. Human-readable explanation answering the prompt. List of plan IDs recommended by the assistant. ## Example Response ```json theme={null} { "Response": { "Answer": "Based on your requirements, our Part-Time plan with meeting room add-ons is a great fit.", "PreferredPlanIds": [123, 456] } } ``` ## Usage in Portal * Checkout – Plan selection step * `src/views/checkout/steps/TariffSignupStep.tsx` (filters visible plans by AI) * `src/views/checkout/steps/components/TariffAiPrompt.tsx` ## Related Endpoints * `GET /api/public/ai/products` – Product suggestions by prompt * `GET /api/public/ai/bookings` – Booking intent parsing and suggestions * `GET /api/public/ai/chats/{sessionId}` – General-purpose assistant chat ## Error Responses The user is not authenticated. Missing or invalid prompt. # Active Announcements Source: https://learn.nexudus.com/api/endpoints/announcements/active-announcements GET /api/public/announcements/active Returns all currently active announcements for the location. # Active Announcements Returns all announcements that are currently active and visible to members. Used to display notification banners or announcement widgets on the dashboard. ## Authentication Requires a valid customer bearer token. ## Response Returns an array of active announcement objects. ## Examples ### Fetch active announcements ```http theme={null} GET /api/public/announcements/active Authorization: Bearer {token} ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' const response = await httpClient.get(endpoints.announcements.active) ``` # Announcement URL Visit Source: https://learn.nexudus.com/api/endpoints/announcements/announcement-url POST /api/public/announcements/visitUrl Records a click-through on an announcement link. # Announcement URL Visit Records that a customer clicked through on an announcement's external URL. Used for tracking engagement with announcements. ## Authentication Requires a valid customer bearer token. ## Query Parameters Numeric identifier of the announcement. ## Response Returns the external URL to open in the browser. The external URL associated with the announcement. The portal opens this in a new tab via `window.open()`. ## Examples ### Track announcement click ```http theme={null} POST /api/public/announcements/visitUrl?id=10 Authorization: Bearer {token} ``` ```json theme={null} { "Url": "https://example.com/promo" } ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' const response = await httpClient.post<{ Url: string }>(endpoints.announcements.url(10)) window.open(response.data.Url, '_blank') ``` # Get Article Details Source: https://learn.nexudus.com/api/endpoints/articles/article-details GET /api/public/blogPosts/{postId} Returns the full content of a single article. # Get Article Details Returns the full content and metadata for a specific article. Used to render the article detail page. ## Authentication No authentication required. ## Path Parameters Numeric identifier of the article. Returned as `Id` from `GET /api/public/blogPosts`. ## Query Parameters Comma-separated list of field paths to include in the response. When provided, only the specified fields are returned — useful for reducing payload size. Supports nested paths using dot notation. Example: `_shape=Title,SummaryText,FullText,PublishDate,BlogCategories`. ## Response Returns an article object with full content. Unique identifier for the article. Post title. Full post content. May contain HTML. Short summary shown in list views. Publication date in ISO 8601 format. Whether the post has a header image. ## Examples ### Fetch an article ```http theme={null} GET /api/public/blogPosts/55 ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' const response = await httpClient.get(endpoints.blog.details(55)) ``` # Delete Article Comment Source: https://learn.nexudus.com/api/endpoints/articles/delete-comment DELETE /api/public/blogPosts/{postId}/comments/{commentId} Deletes a comment from an article. # Delete Article Comment Removes a specific comment from an article. Only the comment author or an administrator can delete a comment. ## Authentication Requires a valid customer bearer token. The customer must be the comment author. ## Path Parameters Numeric identifier of the article. Numeric identifier of the comment to delete. ## Response Returns a `200 OK` on success. ## Examples ### Delete a comment ```http theme={null} DELETE /api/public/blogPosts/55/comments/103 Authorization: Bearer {token} ``` ``` HTTP/1.1 200 OK ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' await httpClient.delete(endpoints.blog.deleteComment(55, 103)) ``` # List Articles Source: https://learn.nexudus.com/api/endpoints/articles/list-articles GET /api/public/blogPosts Returns a paginated list of published articles with optional filtering by category, keyword, and featured status. # List Articles Returns a paginated list of published articles for the current location. Supports filtering by category, keyword search, and featured flag. ## Authentication No authentication required. ## Query Parameters 1-based page number. Number of posts per page. Filter to posts belonging to a specific category. Omit to return posts across all categories. Keyword filter applied to post title and body. URL-encoded. When `true`, returns only articles marked as featured by the operator. Comma-separated list of field paths to include in the response. When provided, only the specified fields are returned — useful for reducing payload size. Supports nested paths using dot notation. Example: `_shape=BlogPosts.Records.Title,BlogPosts.Records.SummaryText,BlogPosts.Records.PublishDate`. ## Response Returns a `BlogPostList` object containing paginated articles, available categories, and the currently selected category. Paginated wrapper containing article records. Array of article summaries for the current page. Current page number. Total number of matching posts. Total number of pages. Whether there are more pages after the current one. Array of all available article categories. The currently selected category (when filtering by `categoryId`). ## Examples ### Fetch first page of posts ```http theme={null} GET /api/public/blogPosts?page=1&top=10 ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' const { resource: posts } = useTypedData( httpClient, endpoints.blog.blogPosts({ page: 1, top: 10, featured: true, }), ) ``` # Post Article Comment Source: https://learn.nexudus.com/api/endpoints/articles/new-comment POST /api/public/blogPosts/{postId}/comments Posts a new comment on a published article on behalf of the authenticated customer. # Post Article Comment Submits a new comment on a published article. Only available when comments are enabled for the post. ## Authentication Requires a valid customer bearer token. ## Path Parameters Numeric identifier of the article. Returned as `Id` from `GET /api/public/blogPosts`. ## Request Body The text body of the comment. ## Response Returns a `200 OK` on success. ## Examples ### Post a comment ```http theme={null} POST /api/public/blogPosts/55/comments Authorization: Bearer {token} Content-Type: application/json { "comment": "Great article, very helpful tips!" } ``` ``` HTTP/1.1 200 OK ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' await httpClient.post(endpoints.blog.newComment(55), { comment: 'Great article, very helpful tips!', }) ``` # Exchange JWT Source: https://learn.nexudus.com/api/endpoints/auth/exchange-jwt POST /api/sys/users/exchange Exchange a short-lived JWT issued by a Nexudus server-side flow for a bearer token that authenticates subsequent API requests. # Exchange JWT Converts a one-time JWT — issued during sign-up, email verification, password reset, or magic-link flows — into a standard bearer token and refresh token pair. The portal calls this immediately after any server-side operation that returns a raw JWT, so the customer is signed in without ever entering their password. This endpoint is intended for server-issued JWTs passed back to the client (e.g. as part of a sign-up response). It is **not** for exchanging a customer's email and password — use `POST /api/token` for credential-based sign-in. ## Authentication No authentication required. The JWT in the `token` parameter acts as the credential. ## Query Parameters The short-lived JWT to exchange. URL-encode this value. Obtained from server-side flows such as the sign-up response (`Token` field) or a magic-link email. Lifetime of the issued bearer token in minutes. The portal passes `1440` (24 hours) for standard sign-in sessions. ## Response Bearer token to include in the `Authorization` header of all subsequent authenticated requests. Token scheme. Always `bearer`. Lifetime of the bearer token in seconds. Token used to obtain a new bearer token after it expires without requiring the customer to re-authenticate. ## Examples ### Exchange a JWT after sign-up ```http theme={null} POST /api/sys/users/exchange?token=eyJhbGciOiJSUzI1NiJ9...&validForInMinutes=1440 ``` ```json theme={null} { "token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...", "token_type": "bearer", "expires_in": 86400, "refresh_token": "7kMpQxRtZn2" } ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' import { ExchangedToken } from '@/states/useAuthContext' // `rawJwt` is the `Token` field returned by e.g. the sign-up endpoint const response = await httpClient.post(endpoints.system.auth.login(rawJwt)) if (response.data.token) { await saveSession({ tokenResponse: { access_token: response.data.token, token_type: response.data.token_type, expires_in: response.data.expires_in, refresh_token: response.data.refresh_token, }, }) } ``` The endpoint key `endpoints.system.auth.login(token)` builds the URL as: ``` /api/sys/users/exchange?token=${encodeURIComponent(token)}&validForInMinutes=1440 ``` ## Usage in Portal | Context | Source file | | ---------------------------------------------- | ----------------------------------------------------- | | Magic-link / email-verification sign-in | `src/states/useAuthContext.tsx` (`exchangeToken`) | | Sign-up flow — embedded checkout (`/checkout`) | `src/views/checkout/SignupUserPage.tsx` | | Sign-up flow — public checkout (`/join`) | `src/views/public/checkout/components/SignupForm.tsx` | ## Use Cases ### Authenticating API requests on behalf of a customer After a server-side flow (sign-up, email verification, password reset, or magic link) issues a JWT, exchange it for a bearer token to make authenticated API requests on the customer's behalf: ```typescript theme={null} // `rawJwt` is the token from the server-side flow (e.g., sign-up response) const response = await httpClient.post(endpoints.system.auth.login(rawJwt)) // Use the bearer token for subsequent API calls const { access_token, refresh_token } = response.data httpClient.defaults.headers.common['Authorization'] = `Bearer ${access_token}` // Now all requests are authenticated as the customer await httpClient.get('/api/coworkers/me') ``` The returned `access_token` is valid for the duration specified in `expires_in` (default 24 hours). Use `POST /api/token` with `grant_type=refresh_token` to renew it before expiration. ## Error Responses The `token` parameter is missing, malformed, or has already been used. The JWT issued by Nexudus flows is single-use and expires quickly. The JWT signature is invalid or it was issued for a different Nexudus space. ## Related Endpoints | Method | Endpoint | Description | | ------ | -------------------------------------- | -------------------------------------------------------------- | | `POST` | `/api/token` | Exchange a customer's email and password for a bearer token | | `POST` | `/api/sys/users/token/refresh` | Obtain a new bearer token using a refresh token | | `GET` | `/api/sys/users/impersonate` | Issue an impersonation token for a specific customer | | `POST` | `/api/sys/users/startPasswordReset` | Trigger the password-reset email (returns a JWT for this flow) | | `POST` | `/api/sys/users/completePasswordReset` | Complete password reset and exchange the resulting JWT | # Get a bearer token Source: https://learn.nexudus.com/api/endpoints/auth/get-token POST /api/token Exchange a customer email and password for a bearer token used to authenticate all subsequent API requests. # Get a bearer token Exchanges a customer's email address and password for a short-lived bearer token and a refresh token. Every authenticated API call in the Members Portal uses the `access_token` returned here as a `Bearer` credential. Pass `totp` when the customer has two-factor authentication enabled — omitting it when 2FA is active will return a `two_factor_auth_check` error. Unlike most Nexudus API endpoints, this request must be encoded as `application/x-www-form-urlencoded`, **not** `application/json`. Sending a JSON body will result in an `unsupported_grant_type` error. ## Authentication No authentication required. This is the endpoint that issues credentials. ## Request Body Grant flow to use. Must be `password` for email/password authentication. The customer's email address. The customer's password. Time-based One-Time Password for two-factor authentication. Required when the customer has 2FA enabled; omit otherwise. ## Headers A unique identifier for the client application or integration. If omitted, this defaults to the customer's email address, which you must then use as the `client_id` when refreshing the token. ## Response Bearer token to include in the `Authorization` header of all subsequent authenticated requests. Token scheme. Always `bearer`. Lifetime of the access token in seconds. Token used to obtain a new `access_token` after it expires, without requiring the customer to re-enter their password. ## Examples ### Successful sign-in ```http theme={null} POST /api/token Content-Type: application/x-www-form-urlencoded grant_type=password&username=jane.doe%40example.com&password=S3cur3P%40ss ``` ### Sign-in with client identifier Providing a `client_id` is optional. If you provide one, you must use the same value when refreshing the token. If omitted, the customer's email address is used as the `client_id`, which you must then pass to the refresh endpoint. ```http theme={null} POST /api/token Content-Type: application/x-www-form-urlencoded client_id: my-app-identifier grant_type=password&username=jane.doe%40example.com&password=S3cur3P%40ss ``` ```json theme={null} { "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...", "token_type": "bearer", "expires_in": 86400, "refresh_token": "8xLOxBtZp8" } ``` ### Sign-in with two-factor authentication ```http theme={null} POST /api/token Content-Type: application/x-www-form-urlencoded grant_type=password&username=jane.doe%40example.com&password=S3cur3P%40ss&totp=482910 ``` ```json theme={null} { "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...", "token_type": "bearer", "expires_in": 86400, "refresh_token": "8xLOxBtZp8" } ``` ## TypeScript Integration ```typescript theme={null} import { type AxiosResponse } from 'axios' import qs from 'qs' import { AuthToken } from '@/states/useAuthContext' const data = { grant_type: 'password', username: values.email, password: values.password, totp: values.totp, } const res: AxiosResponse = await httpClient.post('/api/token', qs.stringify(data), { headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'client_id': values.clientId, // or email if omitted during sign-in }, }) if (res.data.access_token) { saveSession({ tokenResponse: res.data, remember: values.rememberMe }) } ``` ## Usage in Portal | Context | Source file | | ------------------------ | ------------------------------------ | | Sign-in page (`/signin`) | `src/views/auth/SignIn/useSignIn.ts` | ## Error Responses The `grant_type` field is missing or the body was not encoded as `application/x-www-form-urlencoded`. Credentials are incorrect, the customer is not registered with this location, or the account has been suspended. The `error_description` field contains a human-readable reason. The customer has 2FA enabled but `totp` was not supplied or the supplied code is invalid. Prompt the customer for their one-time code and retry. The customer is required to reset their password before signing in. The `error_description` field contains a password-reset token to pass to the reset-password flow. ## Related Endpoints | Method | Endpoint | Description | | ------ | ------------------------------ | --------------------------------------------------------- | | `POST` | `/api/token` | *(this endpoint)* Exchange credentials for a bearer token | | `GET` | `/api/public/billing/customer` | Retrieve the authenticated customer's profile | | `GET` | `/api/public/teams/my` | List teams the authenticated customer belongs to | # Refresh a bearer token Source: https://learn.nexudus.com/api/endpoints/auth/refresh-bearer-token POST /api/token Use an existing refresh token to obtain a new access token and refresh token without requiring the customer to re-enter their password. # Refresh a bearer token Uses a refresh token to obtain a new access token and refresh token without requiring the customer to re-enter their password. This is useful when the access token has expired but you want to maintain the customer's session. Unlike most Nexudus API endpoints, this request must be encoded as `application/x-www-form-urlencoded`, **not** `application/json`. Sending a JSON body will result in an `unsupported_grant_type` error. ## Authentication No authentication required. This endpoint uses the refresh token itself as the credential. ## Request Body Must be `refresh_token` to use the refresh token grant flow. The refresh token previously received from the sign-in endpoint. ## Headers The client identifier that was used when obtaining the bearer token. If the `client_id` was provided during sign-in, use that value. If `client_id` was omitted during sign-in, use the customer's email address (which defaults to the `client_id` automatically). ## Response New bearer token to include in the `Authorization` header of all subsequent authenticated requests. Token scheme. Always `bearer`. Lifetime of the new access token in seconds. New refresh token to use for subsequent refresh operations. The previous refresh token is invalidated. ## Examples ### Successful token refresh ```http theme={null} POST /api/token Content-Type: application/x-www-form-urlencoded client_id: jane.doe@example.com grant_type=refresh_token&refresh_token=8xLOxBtZp8 ``` ```json theme={null} { "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...", "token_type": "bearer", "expires_in": 86400, "refresh_token": "9yMPyCuQr9" } ``` ## TypeScript Integration ```typescript theme={null} import { type AxiosResponse } from 'axios' import qs from 'qs' import { type AuthToken } from '@/states/useAuthContext' const data = { grant_type: 'refresh_token', refresh_token: session.refreshToken, } const res: AxiosResponse = await httpClient.post('/api/token', qs.stringify(data), { headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'client_id': session.clientId, // or email if client_id was omitted during sign-in }, }) if (res.data.access_token) { saveSession({ tokenResponse: res.data, remember: values.rememberMe }) } ``` ## Error Responses The `grant_type` field is missing or the body was not encoded as `application/x-www-form-urlencoded`. The refresh token is invalid, expired, or has already been used. The `error_description` field contains a human-readable reason. ## Related Endpoints | Method | Endpoint | Description | | ------ | ------------------------------ | --------------------------------------------------------- | | `POST` | `/api/token` | *(this endpoint)* Exchange credentials for a bearer token | | `POST` | `/api/sys/users/token/refresh` | Get a short-lived server-side JWT for authenticated links | # Refresh JWT access token Source: https://learn.nexudus.com/api/endpoints/auth/refresh-token POST /api/sys/users/token/refresh Refresh the current user JWT access token with an optional custom validity period. # Refresh JWT access token Refreshes the authenticated user's JWT access token, generating a new token and returning it in the response. This is useful when you need a fresh token with a different validity period than the original. ## Authentication Requires a valid customer bearer token via the `Authorization` header. ## Request Body Optional. The validity period of the new token in minutes. Defaults to `30` if omitted or `null`. ## Response Returns an `ActionConfirmation` envelope. `true` when the token was refreshed successfully. The new JWT access token string. Use this as the `Authorization: Bearer` value for subsequent API requests. `null` when `WasSuccessful` is `false`. HTTP-style status code mirrored in the response body. `200` on success, `500` on failure. Human-readable message. Usually `"OK"` on success. Validation or server errors. `null` on success. ## Examples ### Refresh with default validity (30 minutes) ```http theme={null} POST /api/sys/users/token/refresh Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9... Content-Type: application/json {} ``` ```json theme={null} { "WasSuccessful": true, "Value": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.new_refreshed_token...", "Status": 200, "Message": "OK", "Errors": null } ``` ### Refresh with custom validity (60 minutes) ```http theme={null} POST /api/sys/users/token/refresh Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9... Content-Type: application/json { "ValidityInMinutes": 60 } ``` ```json theme={null} { "WasSuccessful": true, "Value": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.new_60min_token...", "Status": 200, "Message": "OK", "Errors": null } ``` ## Admin Endpoint: Refresh Another User's Token An admin variant of this endpoint exists at `POST /api/sys/users/{id}/token/refresh` which allows refreshing the token for a specific user by ID. ### Authentication Requires a bearer token with `ADMIN` role or `User-Edit` permission. ### URL Parameter The ID of the user whose token should be refreshed. ### Request Body Same as the current-user endpoint — optional `ValidityInMinutes`. ### Example ```http theme={null} POST /api/sys/users/42/token/refresh Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.admin_token... Content-Type: application/json { "ValidityInMinutes": 60 } ``` ## Use Cases ### Extending token validity When the default token validity is insufficient for a long-running operation, request a fresh token with an extended validity period: ```typescript theme={null} const response = await fetch('/api/sys/users/token/refresh', { method: 'POST', headers: { 'Authorization': `Bearer ${currentToken}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ ValidityInMinutes: 120 }) }) const result = await response.json() if (result.WasSuccessful) { const newToken = result.Value // Use newToken for subsequent requests } ``` ### Token rotation Periodically refresh the access token to maintain a fresh validity window without requiring the user to re-authenticate. ## Error Responses The bearer token is missing, expired, or invalid. The user must sign in again via `POST /api/token`. Returned when the authenticated user cannot be resolved from the token, or (for the admin endpoint) when the admin lacks access to the target user. ## Related Endpoints | Method | Endpoint | Description | | ------ | ----------------------------------- | ----------------------------------------------------------------------- | | `POST` | `/api/token` | Exchange email and password (or a refresh token) for a new bearer token | | `POST` | `/api/sys/users/exchange` | Exchange a server-issued JWT for a bearer token | | `POST` | `/api/sys/users/{id}/token/refresh` | Admin: refresh another user's token | | `GET` | `/api/auth/media/customer` | Obtain a short-lived JWT for accessing protected media files | # Get Contract Details Source: https://learn.nexudus.com/api/endpoints/billing/contract-details GET /api/public/billing/coworkerContracts/{contractId} # Get Contract Details Retrieves a single plan contract for the currently authenticated customer. Contracts represent the customer's active plan subscription, including pricing, billing cycle, renewal dates, and pause/cancellation state. ## Authentication This endpoint requires an authenticated customer session. The contract must belong to the current customer or to a team the customer manages. ## Path Parameters The unique identifier of the contract to retrieve. ## Query Parameters Comma-separated list of field paths to include in the response. When provided, only the specified fields are returned — useful for reducing payload size. Supports nested paths using dot notation. Example: `_shape=Tariff.Name,Price,PriceFormatted,Active,StartDate,RenewalDate`. ## Response Returns a `CoworkerContract` object. ### Plan & Pricing ID of the plan associated with this contract. Display name of the plan. Current monthly (or per-cycle) price. Pre-formatted price string (e.g. `"$199.00"`). Price that will be charged from the next renewal. Pre-formatted next renewal price. ISO 4217 currency code. Number of units (e.g., desks) covered by this contract. ### Dates & Billing ISO 8601 date the contract started. ISO 8601 date of the next billing renewal. UTC version of the renewal date. Day of the month on which the contract is billed. The earliest date the contract can be cancelled without penalty. ISO 8601 date when the contract was cancelled (if applicable). The absolute final date the contract will end (if applicable). ### Status Flags Whether the contract is currently active. Whether the contract has been cancelled. Whether this is the customer's primary contract. Whether the contract is in a paused state. Whether the contract is actively paused at the current moment. Whether the contract is eligible to be paused right now. Whether the current date falls within a scheduled pause period. UTC datetime from which the pause period begins. UTC datetime at which the pause period ends. ### Terms & Deposits Whether the customer has accepted the plan's terms and conditions. ISO 8601 datetime when terms were accepted. Total deposit amount held against this contract. Pre-formatted deposit amount string. ### System Fields Unique identifier of the contract. Globally unique identifier of the contract. ISO 8601 datetime when the contract was created (local time). ISO 8601 datetime when the contract was last updated (local time). ## Example Response ```json theme={null} { "Id": 5001, "UniqueId": "c7d8e9f0-1234-5678-abcd-ef0987654321", "TariffId": 12, "TariffName": "Hot Desk Monthly", "Price": 199.0, "PriceFormatted": "$199.00", "NextPrice": 199.0, "NextPriceFormatted": "$199.00", "CurrencyCode": "USD", "Quantity": 1, "StartDate": "2025-01-01", "RenewalDate": "2025-11-01", "BillingDay": 1, "EarliestCancellationDate": "2025-12-01", "Active": true, "Cancelled": false, "MainContract": true, "IsPaused": false, "IsPausedNow": false, "CanBePausedNow": true, "PricePlanTermsAccepted": true, "DepositsAmount": 0, "CreatedOn": "2025-01-01T09:00:00", "UpdatedOn": "2025-09-15T14:30:00" } ``` ## Usage in Portal This endpoint is used in the My Plans section to display full contract details. * File: `src/views/user/plans/useContractData.ts` ### Typical integration pattern ```ts theme={null} // From src/api/endpoints.ts // endpoints.billing.contracts.one = (contractId: number) => ({ // url: `/api/public/billing/coworkerContracts/${contractId}`, // type: null as unknown as CoworkerContract, // }) // Usage in React const endpoint = useMemo(() => endpoints.billing.contracts.one(contractId), [contractId]) const { resource: contract } = useData(httpClient, endpoint.url) ``` ## Related Endpoints * `GET /api/public/billing/coworkerContracts/{contractId}/pause/meta` – Get pause eligibility metadata * `PUT /api/public/billing/coworkerContracts/v2/{contractId}/pause` – Pause a contract * `PUT /api/public/billing/coworkerContracts/v2/{contractId}/resume` – Resume a paused contract ## Error Responses The current user is not authenticated or the contract is not accessible to them. Contract with the specified ID does not exist. # Pause Contract Source: https://learn.nexudus.com/api/endpoints/billing/contract-pause PUT /api/public/billing/coworkerContracts/v2/{contractId}/pause # Pause Contract Submits a request to pause (freeze) a plan contract for a specified number of billing cycles. While paused, the plan's recurring charges are suspended. Additional services such as bookings may still generate charges during the pause period. Before calling this endpoint, retrieve pause eligibility and options via `GET /api/public/billing/coworkerContracts/{contractId}/pause/meta`. Always present and obtain acceptance of the pause terms and conditions before submitting. ## Authentication This endpoint requires an authenticated customer session. ## Path Parameters The unique identifier of the contract to pause. ## Request Body The number of billing cycles to pause the contract for. Must be at least `1`. The available options are returned by the pause metadata endpoint as `PauseUntilOptions`. ## Response A successful response returns an empty body or a generic confirmation. No typed response object is defined for this endpoint. ## Example Request ```json theme={null} { "PauseCycles": 2 } ``` ## Usage in Portal Called when the customer confirms the pause action in the pause modal. * File: `src/views/user/plans/useMyPlansData.ts` * Used by: `src/views/user/plans/components/PauseContractModal.tsx` ### Typical integration pattern ```ts theme={null} // From src/api/endpoints.ts // endpoints.billing.contracts.pause = (contractId: number) => ({ // url: `/api/public/billing/coworkerContracts/v2/${contractId}/pause`, // }) // Usage const pauseContract = async (contractId: number, pauseCycles: number) => { return httpClient.put(endpoints.billing.contracts.pause(contractId).url, { PauseCycles: pauseCycles }) } ``` ## Related Endpoints * `GET /api/public/billing/coworkerContracts/{contractId}/pause/meta` – Get pause eligibility and options * `GET /api/public/billing/coworkerContracts/pause/bookings` – Preview bookings affected by the pause * `PUT /api/public/billing/coworkerContracts/v2/{contractId}/resume` – Resume a paused contract ## Error Responses The contract cannot be paused (e.g., already paused, limit reached, or the plan does not support pausing). The response body contains an error code. The current user is not authenticated or does not have access to this contract. Contract with the specified ID does not exist. # Get Bookings During Pause Period Source: https://learn.nexudus.com/api/endpoints/billing/contract-pause-bookings GET /api/public/billing/coworkerContracts/pause/bookings # Get Bookings During Pause Period Returns a summary of the customer's bookings that fall within a proposed pause period. Use this endpoint in the pause flow to warn the customer about any existing bookings that will be affected — specifically those that have not yet been charged, invoiced, or paid. ## Authentication This endpoint requires an authenticated customer session. ## Query Parameters ISO 8601 datetime string for the start of the proposed pause period. This is typically the earliest pause date returned by the pause metadata endpoint. ISO 8601 datetime string for the end of the proposed pause period. This is computed from the selected number of pause cycles. ## Response Returns a `PauseBooking` object summarising booking counts within the date range. Total number of bookings within the proposed pause period. Number of bookings that have not yet been charged. Number of bookings that have not yet been invoiced. Number of bookings whose invoices have not yet been paid. ## Example Response ```json theme={null} { "Total": 3, "NotCharged": 1, "NotInvoiced": 2, "NotPaid": 3 } ``` ## Usage in Portal Called inside the pause modal each time the customer changes the number of pause cycles, so the warning counts stay in sync with the selected date range. * File: `src/views/user/plans/components/PauseContractModal.tsx` ### Typical integration pattern ```ts theme={null} // From src/api/endpoints.ts // endpoints.billing.contracts.pauseBookings = (start: string, end: string) => ({ // url: `/api/public/billing/coworkerContracts/pause/bookings?start=${start}&end=${end}`, // type: null as unknown as PauseBooking, // }) // Usage in React (recalculated on every cycle selection change) const endDate = earliestPauseDate.plus({ months: selectedCycles }) const bookingsEndpoint = endpoints.billing.contracts.pauseBookings(earliestPauseDateISO, endDate.toUTC().toISO() ?? earliestPauseDateISO) const { resource: bookings } = useData(httpClient, bookingsEndpoint.url) ``` ## Related Endpoints * `GET /api/public/billing/coworkerContracts/{contractId}/pause/meta` – Get pause eligibility and available date options * `PUT /api/public/billing/coworkerContracts/v2/{contractId}/pause` – Submit the pause request ## Error Responses The current user is not authenticated. Missing or invalid `start`/`end` parameters. # Get Contract Pause Metadata Source: https://learn.nexudus.com/api/endpoints/billing/contract-pause-meta GET /api/public/billing/coworkerContracts/{contractId}/pause/meta # Get Contract Pause Metadata Returns metadata about the pause eligibility and state of a given contract. Use this endpoint before presenting the pause flow to the customer to determine whether pausing is possible, what the earliest pause date is, available pause-until options, and any applicable terms and conditions. ## Authentication This endpoint requires an authenticated customer session. ## Path Parameters The unique identifier of the contract. ## Response Returns a `PauseContractMeta` object. Whether the contract is currently eligible to be paused. Whether the contract is already actively paused. Whether the current date falls within an existing scheduled pause period. Local datetime from which the current pause period starts (if in one). UTC datetime from which the current pause period starts. Local datetime at which the current pause period ends. UTC datetime at which the current pause period ends. ISO 8601 date for the start of the current billing period. UTC version of the current billing period start. Whether the contract is currently within a pro-rata period (affects pause timing). ISO 8601 date of the next scheduled renewal. Maximum number of billing cycles that can be paused (if restricted). `null` means unlimited. Maximum number of months that can be paused per year (if restricted). `null` means unlimited. Number of pause periods already used by this contract. Number of days before the renewal where pro-rata charges apply. Array of ISO 8601 date strings representing the available pause end dates the customer can select from. HTML or plain text for the pause terms and conditions that should be shown to and accepted by the customer before pausing. ## Example Response ```json theme={null} { "CanBePausedNow": true, "IsPausedNow": false, "InPausedPeriod": false, "InPausedPeriodFrom": null, "InPausedPeriodFromUtc": null, "InPausedPeriodUntil": null, "InPausedPeriodUntilUtc": null, "CurrentPeriodStart": "2025-10-01", "CurrentPeriodStartUtc": "2025-10-01T00:00:00Z", "InProratePeriod": false, "RenewalDate": "2025-11-01", "PauseCyclesLimit": null, "PauseYearlyLimit": 3, "PausedPeriodsCount": 0, "ProrateDaysBefore": 5, "PauseUntilOptions": ["2025-11-01", "2025-12-01", "2026-01-01"], "TermsAndConditions": "

By pausing your plan you agree to...

" } ``` ## Usage in Portal Fetched at the start of the pause flow to determine UI state and options presented to the customer. * File: `src/views/user/plans/useContractPauseMeta.ts` * Used by: `src/views/user/plans/components/PauseContractModal.tsx` ### Typical integration pattern ```ts theme={null} // From src/api/endpoints.ts // endpoints.billing.contracts.pauseMmeta = (contractId: number) => ({ // url: `/api/public/billing/coworkerContracts/${contractId}/pause/meta`, // type: null as unknown as PauseContractMeta, // }) // Usage in React const endpoint = endpoints.billing.contracts.pauseMmeta(contractId) const { resource: pauseMeta } = useData(httpClient, endpoint.url) ``` ## Related Endpoints * `GET /api/public/billing/coworkerContracts/{contractId}` – Get full contract details * `PUT /api/public/billing/coworkerContracts/v2/{contractId}/pause` – Submit a pause request * `GET /api/public/billing/coworkerContracts/pause/bookings` – Check bookings affected by the pause period ## Error Responses The current user is not authenticated or does not have access to this contract. Contract with the specified ID does not exist. # Resume Contract Source: https://learn.nexudus.com/api/endpoints/billing/contract-resume PUT /api/public/billing/coworkerContracts/v2/{contractId}/resume # Resume Contract Resumes a previously paused plan contract. Supports two modes: immediate resumption (effective today) or resumption at the natural end of the current pause period. ## Authentication This endpoint requires an authenticated customer session. ## Path Parameters The unique identifier of the contract to resume. ## Query Parameters When `true`, the contract is resumed immediately. When `false`, the contract will resume at the end of its current scheduled pause period. ## Request Body No request body is required. ## Response A successful response returns an empty body or a generic confirmation. No typed response object is defined for this endpoint. ## Usage in Portal Called when the customer clicks the resume button in the My Plans section. * File: `src/views/user/plans/useMyPlansData.ts` ### Typical integration pattern ```ts theme={null} // From src/api/endpoints.ts // endpoints.billing.contracts.resume = (contractId: number, immediate: boolean) => ({ // url: `/api/public/billing/coworkerContracts/v2/${contractId}/resume?immediate=${immediate}`, // }) // Resume immediately const resumeNow = async (contractId: number) => { return httpClient.put(endpoints.billing.contracts.resume(contractId, true).url, {}) } // Resume at end of pause period const resumeAtEnd = async (contractId: number) => { return httpClient.put(endpoints.billing.contracts.resume(contractId, false).url, {}) } ``` ## Related Endpoints * `GET /api/public/billing/coworkerContracts/{contractId}` – Get contract details including pause state * `GET /api/public/billing/coworkerContracts/{contractId}/pause/meta` – Get pause eligibility metadata * `PUT /api/public/billing/coworkerContracts/v2/{contractId}/pause` – Pause a contract ## Error Responses The contract is not currently paused or cannot be resumed. The response body contains an error code. The current user is not authenticated or does not have access to this contract. Contract with the specified ID does not exist. # Get Invoice Details Source: https://learn.nexudus.com/api/endpoints/billing/invoice-details GET /api/public/billing/invoices/{invoiceId} # Get Invoice Details Retrieves a single invoice for the current customer. Invoices are created during checkout flows for bookings, products, plans, and more. This endpoint returns the full invoice breakdown, including lines, taxes, totals, currency, and metadata for the location. ## Authentication This endpoint requires an authenticated customer session. The invoice must belong to the current customer or to a team the customer manages. ## Path Parameters The unique identifier of the invoice you want to retrieve. ## Query Parameters Comma-separated list of field paths to include in the response. When provided, only the specified fields are returned — useful for reducing payload size. Supports nested paths using dot notation. Example: `_shape=InvoiceNumber,TotalAmount,DueAmount,Paid,Lines`. ## Response The response shape follows the `InvoicePreview` contract used across checkout and payments. Below is a summary of the most-used fields. ### Identification and Status Unique identifier for the invoice Globally unique identifier for the invoice Human-friendly invoice number as visible to the customer Whether the invoice is a draft Whether the invoice is fully paid ISO 8601 datetime when the invoice was paid (if paid) ISO 8601 date the invoice is due Whether the document is a credit note Whether the invoice has been refunded ### Customer and Location Customer id the invoice belongs to Location id where this invoice was issued Web address id for the issuing location ### Billing To Billing contact or company name (can be null) Billing address line (can be null) Billing city (can be null) Billing state/region (can be null) Billing postal/ZIP code (can be null) Country object for the billing address Tax/VAT registration number (can be null) ### Amounts and Currency Grand total amount of the invoice (in invoice currency) Amount still due Amount paid so far Total tax amount across all lines Total discount applied to the invoice Invoice currency object with fields: `Name`, `Code`, `Format`, etc. Transaction currency used by the payment gateway (if different) Pre-formatted total, e.g. "\$123.45" Pre-formatted due amount ### Lines and Taxes Array of line items. Each item includes fields such as `Description`, `Quantity`, `UnitPrice`, `SubTotal`, `TaxAmount`, `TaxPercentage`, and optional `DiscountCode`. Breakdown of totals by tax rate, including `Rate`, `TaxSubTotal`, `SubTotal`, and `Lines`. ### Usage of Credits (if applicable) Applied extra service credits with `Amount`, `ChargePeriod`, `ExpiresOn`. Applied booking credits with `Amount`, `ChargePeriod`, `ExpiresOn`. ### System Fields ISO 8601 datetime when the invoice was created (local time) ISO 8601 datetime when the invoice was created (UTC) ISO 8601 datetime when the invoice was last updated (local time) ISO 8601 datetime when the invoice was last updated (UTC) ## Example Response ```json theme={null} { "Id": 12345, "IdString": "12345", "UniqueId": "e9a3a3b8-8d3e-4b54-9f2d-0c82b2a8b9a1", "InvoiceNumber": "INV-2025-000123", "CoworkerId": 987, "BusinessId": 42, "DueDate": "2025-09-30", "Paid": false, "Draft": false, "Currency": { "Code": "USD", "Name": "US Dollar", "Format": "$0,0.00" }, "TotalAmount": 199.0, "DueAmount": 199.0, "TaxAmount": 33.17, "DiscountAmount": 0, "Lines": [ { "Id": 1, "Description": "Meeting room booking", "Quantity": 1, "UnitPrice": 165.83, "SubTotal": 165.83, "TaxAmount": 33.17, "TaxPercentage": 20, "SubTotalFormatted": "$165.83", "TaxAmountFormatted": "$33.17", "UnitPriceFormatted": "$165.83" } ], "TaxCategories": [{ "Rate": 20, "TaxSubTotal": 33.17, "SubTotal": 165.83, "Name": "VAT 20%", "Lines": [] }], "TotalFormated": "$199.00", "DueAmountFormated": "$199.00", "CreatedOn": "2025-09-28T10:15:00", "CreatedOnUtc": "2025-09-28T09:15:00Z" } ``` ## Usage in Portal This endpoint is used during checkout and payment flows whenever an existing invoice id is present (e.g., resuming payment or redirecting back from a payment provider). Key usages include: 1. Checkout flow controller – decides steps when an `invoice_id` is present * File: `src/views/checkout/CheckoutLayoutPage.tsx` 2. Payment selection and processing (uses invoice data to start payment sessions) * Files: * `src/views/checkout/SignupPaymentPage.tsx` * `src/views/public/checkout/booking/components/StripeCheckoutForm.tsx` * `src/views/public/checkout/booking/components/SpreedlyCheckoutForm.tsx` 3. Completion step context * File: `src/views/checkout/SignupCompletePage.tsx` 4. Invoice fetching and basket state orchestration * File: `src/states/useBasketData.tsx` (calls `endpoints.billing.invoices.one` when `invoice_id` is in the URL) 5. Discount code summary UI (reads invoice lines and currency) * File: `src/views/public/checkout/booking/components/DiscountCodeForm.tsx` ### Typical integration pattern ```ts theme={null} // From src/api/endpoints.ts // const endpoints.billing.invoices.one = (invoiceId: number) => ({ // url: `/api/public/billing/invoices/${invoiceId}`, // type: null as unknown as InvoicePreview, // }) // Usage in React const endpoint = endpoints.billing.invoices.one(Number(invoiceId)) const { resource: invoice } = useData(httpClient, invoiceId ? endpoint.url : null) ``` ## Related Endpoints * `POST /en/basket/CreateInvoice` – Create an invoice from the current basket * `POST /api/public/payments/stripe/createGuestSession` – Start a Stripe checkout session * `POST /api/public/payments/spreedly/createGuestSession` – Start a Spreedly payment session ## Error Responses The current user is not authenticated or The invoice is not accessible to the current user Invoice with the specified id does not exist or is not accessible # Preview Next Invoice PDF Source: https://learn.nexudus.com/api/endpoints/billing/invoice-draft-pdf GET /api/public/billing/invoices/draft/pdf # Preview Next Invoice PDF Returns a PDF preview of the customer's upcoming invoice. This allows members to see what their next invoice will look like before it is officially generated, including estimated charges from active contracts and pending items. ## Authentication This endpoint requires a valid media JWT token obtained from `GET /api/auth/media/customer`. ## Query Parameters A short-lived media JWT obtained from `GET /api/auth/media/customer`. This token authorises temporary access to the binary file. Pass the `jwt` field from the response object directly as this query parameter value. ## Response Returns the raw PDF binary (`application/pdf`). The portal constructs the full URL and opens it in a new browser tab. ## Code Examples ```ts TypeScript theme={null} // 1. Fetch a media JWT (requires a valid Bearer token) const { jwt } = await fetch('/api/auth/media/customer', { headers: { Authorization: `Bearer ${customerBearerToken}` }, }).then((r) => r.json()) // 2. Build the draft invoice PDF URL const draftUrl = `https://${business.WebAddress}/en/api/public/billing/invoices/draft/pdf?t=${jwt}` // 3. Open directly — no additional fetch needed window.open(draftUrl, '_blank') ``` ```bash cURL theme={null} # First obtain a media JWT MEDIA_JWT=$(curl -s -H "Authorization: Bearer $TOKEN" \ "https://your-space.nexudus.com/en/api/auth/media/customer" | jq -r '.jwt') # Then download the draft invoice PDF curl -o draft-invoice.pdf \ "https://your-space.nexudus.com/en/api/public/billing/invoices/draft/pdf?t=$MEDIA_JWT" ``` ## Usage in Portal This endpoint is used in the **My Invoices** section to provide a "Preview next invoice" link at the bottom of the invoices table. * File: `src/views/user/activity/invoices/MyInvoicesSection.tsx` ## Related Endpoints * `GET /api/public/billing/invoices/my` – List invoices * `GET /api/public/billing/invoices/{invoiceId}/pdf` – Download a single invoice PDF * `GET /api/public/billing/invoices/statements/pdf` – Download billing statement * `GET /api/auth/media/customer` – Obtain a short-lived media JWT ## Error Responses Missing or invalid media JWT token. # Get Invoice Event Attendee Line Source: https://learn.nexudus.com/api/endpoints/billing/invoice-line-attendee GET /api/public/billing/invoices/{invoiceId}/attendees/{attendeeUniqueId} # Get Invoice Event Attendee Line Returns the `EventAttendee` record linked to a specific invoice line. This endpoint is used to enrich invoice lines that originate from an event ticket purchase, providing event name, product pricing, and attendee details. ## Authentication This endpoint requires an authenticated customer session. ## Path Parameters The unique identifier of the parent invoice. The `UniqueId` of the event attendee record associated with the invoice line. Available on the invoice line as `EventAttendeeUniqueId`. ## Query Parameters Comma-separated list of field paths to include in the response. When provided, only the specified fields are returned — useful for reducing payload size. Supports nested paths using dot notation. Example: `_shape=Attendee.FullName,Attendee.EventProductName,Attendee.CalendarEvent.Name`. ## Response Returns an `EventAttendee` object. ID of the calendar event the attendee signed up for. ID of the event product (ticket type) purchased. Full name of the attendee. Email address of the attendee. Display name of the event. Name of the ticket type or event product purchased. Price of the event product as a formatted string. ISO 4217 currency code for the event product price. ID of the customer who purchased the ticket (if applicable). Full name of the customer (if applicable). Invoice number associated with the purchase (if applicable). Whether the associated invoice has been paid (if applicable). Globally unique identifier for the attendee record. ## Example Response ```json theme={null} { "CalendarEventId": 201, "EventProductId": 55, "FullName": "Jane Smith", "Email": "jane.smith@example.com", "CalendarEventName": "Monthly Networking Meetup", "EventProductName": "General Admission", "EventProductPrice": "$25.00", "EventProductCurrencyCode": "USD", "CoworkerId": 987, "CoworkerFullName": "Jane Smith", "CoworkerInvoiceNumber": "INV-2025-000124", "CoworkerInvoicePaid": "false", "UniqueId": "f1e2d3c4-b5a6-7890-cdef-1234567890ab" } ``` ## Usage in Portal Used to render event/ticket details in invoice line rows within the basket and invoice summary. * File: `src/components/Basket/invoiceLines/EventAttendeeInvoiceLineRow.tsx` ### Typical integration pattern ```ts theme={null} // From src/api/endpoints.ts // endpoints.billing.invoices.attendee = (invoiceId: number, attendeeUniqueId: string) => ({ // url: `/api/public/billing/invoices/${invoiceId}/attendees/${attendeeUniqueId}`, // type: null as unknown as EventAttendee, // }) // Usage in React const endpoint = endpoints.billing.invoices.attendee(invoice.Id, line.EventAttendeeUniqueId) const { resource: attendee } = useData(httpClient, endpoint.url) ``` ## Related Endpoints * `GET /api/public/billing/invoices/{invoiceId}` – Get full invoice details * `GET /api/public/events/{id}` – Get event details ## Error Responses The current user is not authenticated or does not have access to this invoice. The invoice or attendee record does not exist. # Get Invoice Booking Line Source: https://learn.nexudus.com/api/endpoints/billing/invoice-line-booking GET /api/public/billing/invoices/{invoiceId}/bookings/{bookingUniqueId} # Get Invoice Booking Line Returns the `Booking` record linked to a specific invoice line. This endpoint is used to enrich invoice line items that originate from a booking, giving the UI access to full booking details (resource name, times, floor plan, etc.) alongside the invoice. ## Authentication This endpoint requires an authenticated customer session. ## Path Parameters The unique identifier of the parent invoice. The `UniqueId` of the booking associated with the invoice line. This value is available on the invoice line object as `BookingUniqueId`. ## Query Parameters Comma-separated list of field paths to include in the response. When provided, only the specified fields are returned — useful for reducing payload size. Supports nested paths using dot notation. Example: `_shape=Booking.ResourceName,Booking.FromTime,Booking.ToTime`. ## Response Returns a `Booking` object. Unique identifier of the booking. Globally unique identifier of the booking. ID of the booked resource. Display name of the booked resource. ISO 8601 datetime for the start of the booking. ISO 8601 datetime for the end of the booking. ID of the customer who made the booking. ID of the associated invoice. Whether the booking is still tentative/unconfirmed. Whether the booking has been cancelled. ## Example Response ```json theme={null} { "Id": 9876, "UniqueId": "b1a2c3d4-e5f6-7890-abcd-ef1234567890", "ResourceId": 55, "ResourceName": "Focus Room 2", "FromTime": "2025-10-15T09:00:00", "ToTime": "2025-10-15T11:00:00", "CoworkerId": 987, "InvoiceId": 12345, "Tentative": false, "Cancelled": false } ``` ## Usage in Portal This endpoint is used to render booking-specific details within an invoice line row in the basket/invoice summary UI. * File: `src/components/Basket/invoiceLines/BookingInvoiceLineRow.tsx` ### Typical integration pattern ```ts theme={null} // From src/api/endpoints.ts // endpoints.billing.invoices.booking = (invoiceId: number, bookingUniqueId: string) => ({ // url: `/api/public/billing/invoices/${invoiceId}/bookings/${bookingUniqueId}`, // type: null as unknown as Booking, // }) // Usage in React const endpoint = endpoints.billing.invoices.booking(invoice.Id, line.BookingUniqueId) const { resource: booking } = useData(httpClient, endpoint.url) ``` ## Related Endpoints * `GET /api/public/billing/invoices/{invoiceId}` – Get full invoice details * `GET /api/public/bookings/{id}` – Get booking details directly ## Error Responses The current user is not authenticated or does not have access to this invoice. The invoice or booking does not exist or cannot be associated. # Get Invoice Contract Line Source: https://learn.nexudus.com/api/endpoints/billing/invoice-line-contract GET /api/public/billing/invoices/{invoiceId}/coworkerContracts/{coworkerContractsUniqueId} # Get Invoice Contract Line Returns the `CoworkerContract` record linked to a specific invoice line. This endpoint is used to enrich invoice lines that originate from a plan/contract charge, providing full contract details (plan name, dates, pricing, status) alongside the invoice. ## Authentication This endpoint requires an authenticated customer session. ## Path Parameters The unique identifier of the parent invoice. The `UniqueId` of the contract associated with the invoice line. Available on the invoice line object. ## Query Parameters Comma-separated list of field paths to include in the response. When provided, only the specified fields are returned — useful for reducing payload size. Supports nested paths using dot notation. Example: `_shape=Contract.Tariff.Name,Contract.Price,Contract.Active`. ## Response Returns a `CoworkerContract` object. Unique identifier of the contract. Globally unique identifier of the contract. ID of the plan associated with this contract. Display name of the plan. ISO 8601 date when the contract started. ISO 8601 date of the next renewal. Current price of the contract. Pre-formatted price string (e.g. `"$99.00/mo"`). Whether the contract is currently active. Whether the contract has been cancelled. Whether the contract is currently in a paused state. Day of the month on which the contract is billed. ISO 4217 currency code for the contract. ## Example Response ```json theme={null} { "Id": 5001, "UniqueId": "c7d8e9f0-1234-5678-abcd-ef0987654321", "TariffId": 12, "TariffName": "Hot Desk Monthly", "StartDate": "2025-01-01", "RenewalDate": "2025-11-01", "Price": 199.0, "PriceFormatted": "$199.00", "Active": true, "Cancelled": false, "IsPaused": false, "BillingDay": 1, "CurrencyCode": "USD" } ``` ## Usage in Portal Used to render contract/plan details within invoice line rows in the basket summary and invoice views. * File: `src/components/Basket/invoiceLines/PlanInvoiceLineRow.tsx` ### Typical integration pattern ```ts theme={null} // From src/api/endpoints.ts // endpoints.billing.invoices.coworkerContract = (invoiceId: number, coworkerContractsUniqueId: string) => ({ // url: `/api/public/billing/invoices/${invoiceId}/coworkerContracts/${coworkerContractsUniqueId}`, // type: null as unknown as CoworkerContract, // }) // Usage in React const endpoint = endpoints.billing.invoices.coworkerContract(invoice.Id, line.CoworkerContractUniqueId) const { resource: contract } = useData(httpClient, endpoint.url) ``` ## Related Endpoints * `GET /api/public/billing/invoices/{invoiceId}` – Get full invoice details * `GET /api/public/billing/coworkerContracts/{contractId}` – Get contract details directly ## Error Responses The current user is not authenticated or does not have access to this invoice. The invoice or contract does not exist or cannot be associated. # Get Invoice Product Line Source: https://learn.nexudus.com/api/endpoints/billing/invoice-line-product GET /api/public/billing/invoices/{invoiceId}/coworkerProducts/{coworkerProductsUniqueId} # Get Invoice Product Line Returns the `CoworkerProduct` record linked to a specific invoice line. This endpoint enriches invoice lines that originate from a product purchase, providing details such as product ID, quantity, and recurrence type. ## Authentication This endpoint requires an authenticated customer session. ## Path Parameters The unique identifier of the parent invoice. The `UniqueId` of the customer product record associated with the invoice line. Available on the invoice line as `CoworkerProductUniqueId`. ## Query Parameters Comma-separated list of field paths to include in the response. When provided, only the specified fields are returned — useful for reducing payload size. Supports nested paths using dot notation. Example: `_shape=Product.Price,Product.Quantity,Product.Product.Name`. ## Response Returns a `CoworkerProduct` object. Unique identifier of the customer product record. ID of the underlying product in the catalogue. Quantity of the product purchased. Whether this product is set up as a recurring charge. Globally unique identifier for this customer product record. ## Example Response ```json theme={null} { "Id": 3001, "ProductId": 88, "Quantity": 2, "RegularCharge": false, "UniqueId": "a1b2c3d4-5678-90ef-abcd-1234567890ab" } ``` ## Usage in Portal Used to render product details in invoice line rows within the basket and invoice summary. * File: `src/components/Basket/invoiceLines/ProductInvoiceLineRow.tsx` ### Typical integration pattern ```ts theme={null} // From src/api/endpoints.ts // endpoints.billing.invoices.coworkerProduct = (invoiceId: number, coworkerProductsUniqueId: string) => ({ // url: `/api/public/billing/invoices/${invoiceId}/coworkerProducts/${coworkerProductsUniqueId}`, // type: null as unknown as CoworkerProduct, // }) // Usage in React const endpoint = endpoints.billing.invoices.coworkerProduct(invoice.Id, line.CoworkerProductUniqueId) const { resource: product } = useData(httpClient, endpoint.url) ``` ## Related Endpoints * `GET /api/public/billing/invoices/{invoiceId}` – Get full invoice details * `GET /api/public/store/products/{productId}` – Get store product details ## Error Responses The current user is not authenticated or does not have access to this invoice. The invoice or customer product record does not exist. # List Invoices Source: https://learn.nexudus.com/api/endpoints/billing/invoice-list GET /api/public/billing/invoices/my # List Invoices Returns a paginated list of invoices for the currently authenticated customer. Supports filtering by payment status and whether to include credit notes. ## Authentication This endpoint requires an authenticated customer session. ## Query Parameters When `true`, returns only paid invoices. When `false`, returns only unpaid invoices. Omit to return all invoices. When `true`, includes credit notes in the result set. Comma-separated list of field paths to include in the response. When provided, only the specified fields are returned — useful for reducing payload size. Supports nested paths using dot notation. Example: `_shape=Records.InvoiceNumber,Records.TotalAmount,Records.Paid,TotalItems`. ## Response Returns an `ApiListResult` object. ### Pagination The current page number. Number of records in the current page. Total number of invoices matching the query. Total number of available pages. Whether there is a next page. Whether there is a previous page. ### Records Each item in `Records` follows the `InvoicePreview` shape. Key fields: Unique identifier of the invoice. Globally unique identifier of the invoice. Human-readable invoice number as shown to the customer. Whether the invoice has been fully paid. ISO 8601 datetime when the invoice was paid (if applicable). ISO 8601 date the invoice is due. Whether the invoice is still a draft. Whether this document is a credit note rather than a standard invoice. Grand total of the invoice in the invoice currency. Amount still outstanding. Pre-formatted total string (e.g. `"$199.00"`). Currency object with fields: `Code`, `Name`, `Format`. Web address of the location that issued the invoice. Used to construct PDF download links. ISO 8601 datetime when the invoice was created (local time). ## Example Response ```json theme={null} { "Records": [ { "Id": 12345, "UniqueId": "e9a3a3b8-8d3e-4b54-9f2d-0c82b2a8b9a1", "InvoiceNumber": "INV-2025-000123", "Paid": false, "PaidOn": null, "DueDate": "2025-10-01", "Draft": false, "CreditNote": false, "TotalAmount": 199.0, "DueAmount": 199.0, "TotalFormated": "$199.00", "Currency": { "Code": "USD", "Name": "US Dollar", "Format": "$0,0.00" }, "BusinessWebAddress": "myspace.spaces.nexudus.com", "CreatedOn": "2025-09-28T10:15:00" } ], "CurrentPage": 1, "CurrentPageSize": 1, "TotalItems": 1, "TotalPages": 1, "HasNextPage": false, "HasPreviousPage": false } ``` ## Usage in Portal This endpoint is used in two places: 1. **My Invoices section** – lists all invoices grouped by paid/unpaid status. * File: `src/views/user/activity/invoices/useInvoicesData.tsx` 2. **Onboarding action panel** – surfaces unpaid invoices to prompt the member to complete payment. * File: `src/views/user/dashboards/personal/components/OnBoarding/components/UnpaidInvoicesActionPanel.tsx` ### Typical integration pattern ```ts theme={null} // From src/api/endpoints.ts // endpoints.billing.invoices.list = (paid?: boolean, creditNotes?: boolean) => ({ // url: `/api/public/billing/invoices/my?paid=${paid}&creditNotes=${creditNotes}`, // type: null as unknown as ApiListResult, // }) // Usage in React const endpoint = endpoints.billing.invoices.list(false, false) const { resource: invoices } = useData(httpClient, endpoint.url) ``` ## Related Endpoints * `GET /api/public/billing/invoices/{invoiceId}` – Retrieve a single invoice by ID * `GET /api/public/billing/invoices/{invoiceId}/pdf` – Download invoice as PDF ## Error Responses The current user is not authenticated. # Download Invoice PDF Source: https://learn.nexudus.com/api/endpoints/billing/invoice-pdf GET /api/public/billing/invoices/{invoiceId}/pdf # Download Invoice PDF Returns the PDF file for a given invoice. Two variants are available depending on whether the request is made by an authenticated customer or a guest using a one-time token: | Variant | URL | Auth | | ---------------------- | ------------------------------------------------------------------------------- | ------------------------ | | Authenticated customer | `/api/public/billing/invoices/{invoiceId}/pdf?t={mediaJwt}` | Bearer token + media JWT | | Guest / token-based | `/api/public/billing/invoices/{invoiceId}/pdfByToken?token={basketSessionGuid}` | Basket session GUID only | ## Authenticated Variant ### Path Parameters The unique identifier of the invoice. ### Query Parameters A short-lived media JWT obtained from `GET /api/auth/media/customer`. This token authorises temporary access to the binary file. Pass the `jwt` field from the response object directly as this query parameter value. ### Obtaining the Media JWT Call `GET /api/auth/media/customer` with a valid Bearer token. The endpoint returns a single-field JSON object: ```json theme={null} { "jwt": "" } ``` Key properties of this token: * **Short-lived** – expires after approximately **60 seconds**. In the portal, the token is cached and automatically refreshed every **50 seconds** to ensure it is always valid when a download link is constructed. * **Scoped** – it only grants access to protected binary/media resources and cannot be used in place of a regular API Bearer token. * **One-time style** – a fresh token should be fetched for each user session; do not persist it across sessions. #### Example: fetching and using the media JWT ```ts theme={null} // 1. Fetch a media JWT (requires a valid Bearer token in the Authorization header) const { jwt } = await fetch('/api/auth/media/customer', { headers: { Authorization: `Bearer ${customerBearerToken}` }, }).then((r) => r.json()) // 2. Build the PDF URL using the jwt field const pdfUrl = `https://${invoice.BusinessWebAddress}${config.publicBaseUrl}/api/public/billing/invoices/${invoice.Id}/pdf?t=${jwt}` // 3. Open directly — no additional fetch needed window.open(pdfUrl, '_blank') ``` In the portal this is handled by the `withMediaJwt` helper (`src/states/withMediaJwt.ts`), which wraps `endpoints.system.mediaToken` (`/api/auth/media/customer`) and keeps the token fresh: ```ts theme={null} // src/states/withMediaJwt.ts const { resource: mediaJwt } = useData(httpClient, endpoints.system.mediaToken, { queryConfig: { refetchInterval: 50 * 1000, staleTime: 50 * 1000 }, }) // mediaJwt.jwt is then passed to endpoints.billing.invoices.pdf(invoiceId, mediaJwt) ``` ## Guest / Token Variant (`pdfByToken`) ### Path Parameters The unique identifier of the invoice. ### Query Parameters The **basket session GUID** associated with the completed checkout. This is the payment-gateway session ID (e.g. the Stripe, Spreedly, or PayPal session ID) that was used to process the payment. It is available as `stripe_session_id`, `spreedly_session_id`, or `paypal_session_id` in the checkout completion URL and is passed directly to this endpoint — no authenticated session is required. ### How the basket session GUID is obtained When a guest checkout completes, the payment gateway redirects back to the portal's completion page with the session ID as a URL query parameter: ``` /en/invoices/complete?stripe_session_id= /en/invoices/complete?spreedly_session_id= /en/invoices/complete?paypal_session_id= ``` The portal reads one of those parameters and uses it as the `token` for both `pdfByToken` and `registerByToken`: ```ts theme={null} // src/views/public/checkout/complete/index.tsx const stripeSessionId = searchParams.get('stripe_session_id') // GUID const spreedlySessionId = searchParams.get('spreedly_session_id') // GUID const paypalSessionId = searchParams.get('paypal_session_id') // GUID // whichever is present is passed straight through as the token // and then used to build the PDF link: const pdfUrl = `https://${invoice.BusinessWebAddress}${config.publicBaseUrl}${endpoints.billing.invoices.pdfByToken(invoice.Id, token)}` ``` ## Response Both variants return the raw PDF binary (`application/pdf`). The portal constructs a full URL and opens it in a new browser tab or as a direct link rather than fetching it through the API client. ## Usage in Portal These endpoints are used to generate PDF download links in two contexts: 1. **My Invoices section** (authenticated customers) – constructs the `pdf` URL using the media JWT. * File: `src/views/user/activity/invoices/MyInvoicesSection.tsx` 2. **Invoice basket summary** – shows a download link during checkout. * File: `src/views/checkout/components/InvoiceBasketSummary.tsx` 3. **Guest checkout complete page** – uses `pdfByToken` with the payment-gateway basket session GUID to allow PDF download without a session. * File: `src/views/public/checkout/complete/index.tsx` ### Typical integration pattern ```ts theme={null} // Authenticated PDF URL construction const pdfUrl = `https://${invoice.BusinessWebAddress}${config.publicBaseUrl}${endpoints.billing.invoices.pdf(invoice.Id, mediaJwt)}` // Guest PDF URL construction — token is the basket session GUID (e.g. stripe_session_id / spreedly_session_id / paypal_session_id) const pdfUrl = `https://${invoice.BusinessWebAddress}${config.publicBaseUrl}${endpoints.billing.invoices.pdfByToken(invoice.Id, basketSessionGuid)}` // Then open or link to pdfUrl directly — no fetch required ``` ## Related Endpoints * `GET /api/public/billing/invoices/{invoiceId}` – Get full invoice details * `GET /api/auth/media/customer` – Obtain a short-lived media JWT (`{ jwt: string }`) for authenticated downloads. See [Obtaining the Media JWT](#obtaining-the-media-jwt) above for full usage details. ## Error Responses The current user is not authenticated, or the media JWT or invoice token is invalid or expired. Invoice with the given ID does not exist or is not accessible to the caller. # Register Customer by Invoice Token Source: https://learn.nexudus.com/api/endpoints/billing/invoice-register-by-token POST /api/public/billing/invoices/{invoiceId}/registerByToken # Register Customer by Invoice Token Creates a customer record and grants portal access using a `basketSession` GUID token paired with an invoice ID. This endpoint is called at the end of a guest checkout flow — after payment has been completed — to convert the guest into a registered customer. The combination of the invoice ID and the basket session token is used to verify the purchase, create (or link) the customer account, and return a new token that can be used for subsequent token-gated operations on that invoice. ## Authentication No bearer token is required. Authentication is performed via the `token` query parameter, which must be the `basketSession` GUID associated with the completed guest checkout session. ## Path Parameters The unique identifier of the invoice generated during guest checkout. This is used alongside the basket session token to locate and validate the purchase. ## Query Parameters The `basketSession` GUID token associated with the guest checkout session. This token is typically passed through the checkout completion URL and ties the anonymous session to the invoice, enabling customer record creation and portal access to be granted. ## Response A new invoice-scoped token returned after successful customer registration. This token can be used for subsequent token-gated requests on this invoice, such as downloading the invoice PDF via `pdfByToken`. ## Example Response ```json theme={null} { "Token": "eyJhbGciOiJIUzI1NiIsInR..." } ``` ## Usage in Portal This endpoint is called on the guest checkout completion page immediately after a successful payment. It uses the `basketSession` GUID (available from the checkout URL or session state) together with the invoice ID to: 1. Verify the completed guest purchase. 2. Create a new customer record (or link to an existing one). 3. Grant the customer portal access. 4. Return a fresh token for follow-up token-gated operations (e.g. PDF download). * File: `src/views/public/checkout/complete/index.tsx` ### Typical integration pattern ```ts theme={null} // From src/api/endpoints.ts // endpoints.billing.invoices.registerByToken = (invoiceId: number, basketSessionToken: string) => ({ // url: `/api/public/billing/invoices/${invoiceId}/registerByToken?token=${basketSessionToken}`, // type: null as unknown as { Token: string }, // }) // Usage – called after guest checkout payment success const endpoint = endpoints.billing.invoices.registerByToken(invoice.Id, basketSessionToken) const result = await httpClient.post<{ Token: string }>(endpoint.url, {}) const invoiceToken = result.data.Token // use for pdfByToken or other token-gated requests ``` ## Related Endpoints * `GET /api/public/billing/invoices/{invoiceId}/pdfByToken` – Download invoice PDF using a guest token * `GET /api/public/billing/invoices/{invoiceId}` – Get full invoice details (authenticated) ## Error Responses The provided `basketSession` token is invalid, has already been used, or has expired. No invoice exists with the specified ID, or the token does not match the invoice. # Download Statement PDF Source: https://learn.nexudus.com/api/endpoints/billing/invoice-statement-pdf GET /api/public/billing/invoices/statements/pdf # Download Statement PDF Returns a PDF statement summarising all invoices for the currently authenticated customer. The statement provides a consolidated overview of billing history in a single downloadable document. ## Authentication This endpoint requires a valid media JWT token obtained from `GET /api/auth/media/customer`. ## Query Parameters A short-lived media JWT obtained from `GET /api/auth/media/customer`. This token authorises temporary access to the binary file. Pass the `jwt` field from the response object directly as this query parameter value. ## Response Returns the raw PDF binary (`application/pdf`). The portal constructs the full URL and opens it in a new browser tab. ## Code Examples ```ts TypeScript theme={null} // 1. Fetch a media JWT (requires a valid Bearer token) const { jwt } = await fetch('/api/auth/media/customer', { headers: { Authorization: `Bearer ${customerBearerToken}` }, }).then((r) => r.json()) // 2. Build the statement PDF URL const statementUrl = `https://${business.WebAddress}/en/api/public/billing/invoices/statements/pdf?t=${jwt}` // 3. Open directly — no additional fetch needed window.open(statementUrl, '_blank') ``` ```bash cURL theme={null} # First obtain a media JWT MEDIA_JWT=$(curl -s -H "Authorization: Bearer $TOKEN" \ "https://your-space.nexudus.com/en/api/auth/media/customer" | jq -r '.jwt') # Then download the statement PDF curl -o statement.pdf \ "https://your-space.nexudus.com/en/api/public/billing/invoices/statements/pdf?t=$MEDIA_JWT" ``` ## Usage in Portal This endpoint is used in the **My Invoices** section to provide a "Download statement" link at the bottom of the invoices table. * File: `src/views/user/activity/invoices/MyInvoicesSection.tsx` ## Related Endpoints * `GET /api/public/billing/invoices/my` – List invoices * `GET /api/public/billing/invoices/{invoiceId}/pdf` – Download a single invoice PDF * `GET /api/public/billing/invoices/draft/pdf` – Preview upcoming invoice * `GET /api/auth/media/customer` – Obtain a short-lived media JWT ## Error Responses Missing or invalid media JWT token. # Check Booking Availability Source: https://learn.nexudus.com/api/endpoints/bookings/booking-availability POST /api/public/bookings/available Checks whether a resource is available for a specific time slot. # Check Booking Availability Checks whether a resource is available for booking at the specified time. Returns availability status and any error codes if the slot is unavailable. ## Authentication Requires a valid customer bearer token. ## Request Body The resource to check availability for. Desired start time in ISO 8601 format. Desired end time in ISO 8601 format. ## Response `true` if the resource is available for the requested time slot. Error code explaining why the slot is unavailable (empty when available). Customer ID associated with the availability check. Booking ID if checking availability for an existing booking update. ## Examples ### Check availability ```http theme={null} POST /api/public/bookings/available Authorization: Bearer {token} Content-Type: application/json { "ResourceId": 88, "FromTime": "2026-04-01T09:00:00Z", "ToTime": "2026-04-01T10:00:00Z" } ``` ```json theme={null} { "Available": true, "ErrorCode": "", "CoworkerId": 42, "BookingId": null } ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' const { resource: availability } = useTypedData(httpClient, endpoints.bookings.isAvailable()) ``` # Get Booking Details Source: https://learn.nexudus.com/api/endpoints/bookings/booking-details GET /api/public/bookings/{id} Returns the full details of a single booking by its numeric ID. # Get Booking Details Returns the complete details of a specific booking, including resource, time range, and pricing information. ## Authentication Requires a valid customer bearer token. ## Path Parameters Numeric identifier of the booking. ## Query Parameters Comma-separated list of field paths to include in the response. When provided, only the specified fields are returned — useful for reducing payload size. Supports nested paths using dot notation. Example: `_shape=Booking.ResourceName,Booking.FromTime,Booking.ToTime,Resource.Name`. ## Response Returns a `Booking` object with the following fields: #### Identity | Field | Type | Description | | --------------- | --------- | --------------------------------- | | `Id` | `number` | Unique identifier for the booking | | `UniqueId` | `string` | GUID identifier | | `BookingNumber` | `number?` | Sequential booking number | #### Resource | Field | Type | Description | | ---------------------------- | ---------- | ---------------------------------------- | | `Resource` | `Resource` | Full resource object (nested) | | `ResourceId` | `number` | Resource identifier | | `ResourceName` | `string` | Display name of the booked resource | | `ResourceTypeId` | `number` | Resource type identifier | | `ResourceTypeName` | `string` | Resource type name | | `ResourceBusinessId` | `number` | Business identifier for the resource | | `ResourceBusinessName` | `string` | Business name for the resource | | `ResourceBusinessWebAddress` | `string` | Business web address | | `ResourceUpdatedOnUtc` | `string?` | When the resource was last updated (UTC) | #### Floor Plan | Field | Type | Description | | ------------------- | --------------- | ------------------------------- | | `FloorPlanDesk` | `FloorPlanDesk` | Floor plan desk object (nested) | | `FloorPlanDeskId` | `number?` | Floor plan desk identifier | | `FloorPlanDeskName` | `string` | Floor plan desk name | #### Schedule | Field | Type | Description | | ---------------- | --------- | -------------------------------- | | `FromTime` | `string` | Booking start time (local) | | `ToTime` | `string` | Booking end time (local) | | `FromTimeUtc` | `string` | Booking start time (UTC) | | `ToTimeUtc` | `string` | Booking end time (UTC) | | `UtcFromTime` | `string` | Alias for FromTimeUtc | | `UtcToTime` | `string` | Alias for ToTimeUtc | | `CheckedInAt` | `string?` | When the user checked in (local) | | `UtcCheckedInAt` | `string?` | When the user checked in (UTC) | #### Coworker | Field | Type | Description | | ------------ | ---------- | -------------------------------------- | | `Coworker` | `Coworker` | Coworker who made the booking (nested) | | `CoworkerId` | `number` | Coworker identifier | #### Status & Billing | Field | Type | Description | | --------------------------- | --------- | -------------------------------------- | | `Tentative` | `boolean` | Whether the booking is tentative | | `IsCancelled` | `boolean` | Whether the booking has been cancelled | | `Recurring` | `boolean` | Whether this is a recurring booking | | `CancelIfNotPaid` | `boolean` | Auto-cancel if invoice not paid | | `Invoiced` | `boolean` | Whether the booking has been invoiced | | `CoworkerInvoiceId` | `number?` | Associated invoice identifier | | `CoworkerInvoicePaid` | `boolean` | Whether the invoice has been paid | | `CoworkerInvoiceNumber` | `string` | Invoice number | | `CoworkerExtraServicePrice` | `number?` | Price of extra services | #### Other | Field | Type | Description | | ------------------- | --------------- | ------------------------------ | | `Notes` | `string` | Booking notes | | `ZoomData` | `string` | Zoom meeting data | | `IncludeZoomInvite` | `boolean` | Whether to include Zoom invite | | `CustomFields` | `CustomField[]` | Array of custom field values | #### Timestamps (from base) | Field | Type | Description | | -------------- | -------- | ------------------------------------ | | `CreatedOn` | `string` | Record creation timestamp (local) | | `UpdatedOn` | `string` | Record last-update timestamp (local) | | `CreatedOnUtc` | `string` | Record creation timestamp (UTC) | | `UpdatedOnUtc` | `string` | Record last-update timestamp (UTC) | ## Examples ### Fetch booking details ```http theme={null} GET /api/public/bookings/1234 Authorization: Bearer {token} ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' const { resource: booking } = useTypedData(httpClient, endpoints.bookings.one(1234)) ``` # Booking Price Source: https://learn.nexudus.com/api/endpoints/bookings/booking-price POST /api/public/bookings/price Calculate the price for a booking, including dynamic pricing adjustments. # Booking Price Calculates the total price for a booking at a specific resource and time slot. When [dynamic pricing](/member-portal/checkout/dynamic-pricing) is enabled, the response includes demand-based and last-minute price adjustments alongside the base price. This endpoint is used by the Members Portal to display price annotations in the booking calendar and time selectors, but it can also be called directly to preview pricing before creating a booking. ## Authentication Requires a valid customer bearer token. ## Query Parameters Comma-separated list of response fields to include. Use this to limit the response to only the fields you need. Example: `Price,DynamicPriceAdjustment,LastMinutePriceAdjustment,PriceFactorDemand` ## Request Body The resource to calculate pricing for. Booking start time in ISO 8601 UTC format (e.g. `2026-04-06T10:00:00.000Z`). Booking end time in ISO 8601 UTC format (e.g. `2026-04-06T11:00:00.000Z`). Whether the booking should be charged immediately. Array of visitor objects associated with the booking. Pass an empty array if none. Array of add-on products included in the booking. Pass an empty array if none. Custom field values for the booking. Use `{ "Data": [] }` if none. Booking ID. Use `0` for new bookings. For existing bookings, pass the booking ID to preserve any previously locked-in pricing. A unique identifier for the booking. Use a UUID for new bookings. Display name of the customer making the booking. ## Response Total calculated price for the booking, including all dynamic adjustments. Absolute price adjustment from demand-based dynamic pricing. Positive values indicate a surcharge, negative values a discount. `0` when no demand adjustment applies. Absolute price adjustment for last-minute bookings. Applied when the booking is made within the configured last-minute period before the start time. `0` when not applicable. Demand factor as a decimal multiplier. For example, `0.1` means a 10% surcharge, `-0.15` means a 15% discount. `0` when no demand adjustment applies. ## Examples ### Calculate price for a one-hour booking ```http theme={null} POST /api/public/bookings/price?_shape=Price,DynamicPriceAdjustment,LastMinutePriceAdjustment,PriceFactorDemand Authorization: Bearer {token} Content-Type: application/json { "ResourceId": 1491, "FromTime": "2026-04-06T10:00:00.000Z", "ToTime": "2026-04-06T11:00:00.000Z", "ChargeNow": true, "BookingVisitors": [], "BookingProducts": [], "CustomFields": { "Data": [] }, "Id": 0, "UniqueId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "CoworkerFullName": "Jane Smith" } ``` ### Response with dynamic pricing surcharge ```json theme={null} { "Price": 33.0, "DynamicPriceAdjustment": 3.0, "LastMinutePriceAdjustment": 0.0, "PriceFactorDemand": 0.1 } ``` In this example, the base price is $30 and a 10 percent demand surcharge of $3 has been applied, resulting in a total of \$33. ### Response with no dynamic pricing ```json theme={null} { "Price": 30.0, "DynamicPriceAdjustment": 0.0, "LastMinutePriceAdjustment": 0.0, "PriceFactorDemand": 0.0 } ``` ### Response with last-minute discount ```json theme={null} { "Price": 22.5, "DynamicPriceAdjustment": 0.0, "LastMinutePriceAdjustment": -7.5, "PriceFactorDemand": 0.0 } ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' import { BookingPrice } from '@/types/endpoints/BookingPrice' const PRICE_SHAPE = 'Price,DynamicPriceAdjustment,LastMinutePriceAdjustment,PriceFactorDemand' const url = `${endpoints.bookings.price().url}?_shape=${PRICE_SHAPE}` const response = await httpClient.post(url, { ResourceId: 1491, FromTime: '2026-04-06T10:00:00.000Z', ToTime: '2026-04-06T11:00:00.000Z', ChargeNow: true, BookingVisitors: [], BookingProducts: [], CustomFields: { Data: [] }, Id: 0, UniqueId: crypto.randomUUID(), CoworkerFullName: 'Jane Smith', }) ``` ## Notes * Dynamic pricing must be enabled via the `Nexudus.ML.DynamicPricing.Enabled` business setting. When disabled, `DynamicPriceAdjustment`, `LastMinutePriceAdjustment`, and `PriceFactorDemand` will all be `0`. * Pricing is calculated per hour of the booking. Each hour may have a different demand level, so the total adjustment is the sum of all hourly adjustments. * Previously charged bookings (non-zero `Id`) preserve their original pricing factors — the response reflects the locked-in adjustments rather than recalculating. * See [Dynamic Pricing](/member-portal/checkout/dynamic-pricing) for a full explanation of how demand levels, availability thresholds, and last-minute adjustments are determined. # Booking Products Source: https://learn.nexudus.com/api/endpoints/bookings/booking-products GET /api/public/resources/published/{resourceId}/products Returns the add-on products available for a specific resource. # Booking Products Returns the add-on products (e.g. catering, equipment) that can be included with a booking for a specific resource. ## Authentication No authentication required. ## Path Parameters Numeric identifier of the resource. ## Query Parameters Comma-separated list of field paths to include in the response. When provided, only the specified fields are returned — useful for reducing payload size. Supports nested paths using dot notation. Example: `_shape=Products.Name,Products.Price`. ## Response Returns an object with a `Products` array. Each product has the following fields: #### Product Item | Field | Type | Description | | -------------------- | --------- | ----------------------------------------------------------------------------------------------- | | `Id` | `number` | Unique identifier for the resource-product link | | `ProductId` | `number` | Product identifier | | `ProductName` | `string` | Display name of the product | | `ProductDescription` | `string` | Description of the product | | `Product` | `Product` | Full product object (nested — see [List Store Products](/api/endpoints/products/list-products)) | | `Tags` | `string` | Product tags | | `RequestQuantity` | `boolean` | Whether the user can specify a quantity | | `Quantity` | `number` | Default quantity | | `InvoiceInMinutes` | `number?` | Billing interval in minutes | | `Price` | `number` | Price amount | | `FormattedPrice` | `string` | Locale-formatted price string | | `CurrencyCode` | `string` | ISO currency code | | `Selected` | `boolean` | Whether the product is pre-selected | | `TrackStock` | `boolean` | Whether stock tracking is enabled | | `AllowNegativeStock` | `boolean` | Whether negative stock is allowed | | `CurrentStock` | `number?` | Current available stock | ## Examples ### Fetch booking products ```http theme={null} GET /api/public/resources/published/88/products ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' const { resource: products } = useTypedData(httpClient, endpoints.bookings.bookingProducts(88)) ``` # Booking Suggestions Source: https://learn.nexudus.com/api/endpoints/bookings/booking-suggestions GET /api/public/bookings/suggestions Returns AI-generated booking pattern suggestions for the authenticated customer. # Booking Suggestions Returns personalised booking suggestions based on the customer's historical usage patterns. Used to offer smart re-booking options on the dashboard. ## Authentication Requires a valid customer bearer token. ## Query Parameters Comma-separated list of field paths to include in the response. When provided, only the specified fields are returned — useful for reducing payload size. Supports nested paths using dot notation. ## Response Returns a `BookingSuggestions` object containing an array of suggested bookings based on the customer's usage patterns. ### Top-Level Fields | Field | Type | Description | | ------------- | ---------- | ----------------------------------- | | `Suggestions` | `object[]` | Array of booking suggestion objects | ### Suggestion Fields (BookingDrop) #### Identity | Field | Type | Description | | ---------- | -------- | ----------------------------------------- | | `Id` | `number` | Unique numeric identifier for the booking | | `UniqueId` | `string` | Globally unique identifier | #### Resource | Field | Type | Description | | ---------------------------- | -------- | ----------------------------------- | | `ResourceName` | `string` | Resource display name | | `ResourceId` | `number` | Resource identifier | | `ResourceTypeName` | `string` | Resource type (e.g. `Meeting Room`) | | `ResourceTypeId` | `number` | Resource type identifier | | `ResourceBusinessId` | `number` | Location identifier | | `ResourceBusinessName` | `string` | Location display name | | `ResourceBusinessWebAddress` | `string` | Location subdomain | #### Schedule | Field | Type | Description | | ------------- | -------- | --------------------------- | | `FromTime` | `string` | Start time (business-local) | | `ToTime` | `string` | End time (business-local) | | `FromTimeUtc` | `string` | Start time (UTC) | | `ToTimeUtc` | `string` | End time (UTC) | #### Status | Field | Type | Description | | --------------- | ---------------- | ------------------------------------- | | `Tentative` | `boolean` | Whether the booking is tentative | | `Invoiced` | `boolean` | Whether the booking has been invoiced | | `IsCancelled` | `boolean` | Whether the booking is cancelled | | `BookingNumber` | `number \| null` | Booking reference number | #### Timestamps (from base) | Field | Type | Description | | -------------- | ---------------- | --------------------------------------- | | `CreatedOn` | `string` | Date created (business-local time) | | `UpdatedOn` | `string \| null` | Date last updated (business-local time) | | `CreatedOnUtc` | `string` | Date created (UTC) | | `UpdatedOnUtc` | `string \| null` | Date last updated (UTC) | ## Examples ### Fetch suggestions ```http theme={null} GET /api/public/bookings/suggestions Authorization: Bearer {token} ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' const { resource: suggestions } = useTypedData(httpClient, endpoints.bookings.suggestions()) ``` # Cancellation Fee Source: https://learn.nexudus.com/api/endpoints/bookings/cancellation-fee GET /en/bookings/getCancellationFee Returns the cancellation fee for a specific booking, if applicable. # Cancellation Fee Returns the cancellation fee that would apply if the customer cancels a specific booking. Used to show a confirmation dialog before proceeding with cancellation. This endpoint uses the `/en/` legacy route prefix rather than `/api/public/`. ## Authentication Requires a valid customer bearer token. ## Query Parameters Numeric identifier of the booking to check. ## Response Returns the cancellation fee details. ## Examples ### Check cancellation fee ```http theme={null} GET /en/bookings/getCancellationFee?bookingId=1234 Authorization: Bearer {token} ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' const response = await httpClient.get(endpoints.bookings.cancellationFee(1234)) ``` # Cancelled Bookings Source: https://learn.nexudus.com/api/endpoints/bookings/cancelled-bookings GET /api/public/bookings/cancelled Returns cancelled bookings for the authenticated customer. # Cancelled Bookings Returns the list of cancelled bookings for the authenticated customer. Used to show booking history including cancellations. ## Authentication Requires a valid customer bearer token. ## Query Parameters Comma-separated list of field paths to include in the response. When provided, only the specified fields are returned — useful for reducing payload size. Supports nested paths using dot notation. Example: `_shape=Records.ResourceName,Records.FromTime,Records.ToTime`. ## Response Returns a `MyBookings` object (`ApiListResult`) — a paginated wrapper containing an array of cancelled booking records. Array of cancelled booking objects for the current page. Current page number (1-based). Total number of cancelled bookings. Total number of pages. Whether there are more pages after the current one. Whether there are pages before the current one. ## Examples ### Fetch cancelled bookings ```http theme={null} GET /api/public/bookings/cancelled Authorization: Bearer {token} ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' import { MyBookings } from '@/types/endpoints/MyBookings' import { useData } from '@/api/fetchData' const { resource: data } = useData(httpClient, endpoints.bookings.cancelled) ``` # Delete Booking Source: https://learn.nexudus.com/api/endpoints/bookings/delete-booking DELETE /api/public/bookings/{id} Cancels and deletes a specific booking. # Delete Booking Cancels and removes a specific booking. Depending on operator configuration, a cancellation fee may apply. Use the cancellation fee endpoint to check before deleting. ## Authentication Requires a valid customer bearer token. ## Path Parameters Numeric identifier of the booking to delete. ## Response Returns an `ActionConfirmation` object. Whether the cancellation was successful. ## Examples ### Cancel a booking ```http theme={null} DELETE /api/public/bookings/1234 Authorization: Bearer {token} ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' const result = await httpClient.delete(endpoints.bookings.delete(1234).url) ``` # List My Bookings Source: https://learn.nexudus.com/api/endpoints/bookings/my-bookings GET /api/public/bookings/my Returns the authenticated customer's bookings. # List My Bookings Returns the list of active bookings for the authenticated customer across all resources. ## Authentication Requires a valid customer bearer token. ## Query Parameters Comma-separated list of field paths to include in the response. When provided, only the specified fields are returned — useful for reducing payload size. Supports nested paths using dot notation. Example: `_shape=Records.ResourceName,Records.FromTime,Records.ToTime,TotalItems`. ## Response Returns a `MyBookings` object (`ApiListResult`) — a paginated wrapper containing an array of booking records. Array of booking objects for the current page. Current page number (1-based). Total number of bookings. Total number of pages. Whether there are more pages after the current one. Whether there are pages before the current one. ## Examples ### Fetch my bookings ```http theme={null} GET /api/public/bookings/my Authorization: Bearer {token} ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' import { MyBookings } from '@/types/endpoints/MyBookings' import { useData } from '@/api/fetchData' const { resource: data } = useData(httpClient, endpoints.bookings.myBookings) ``` # Team Bookings Source: https://learn.nexudus.com/api/endpoints/bookings/team-bookings GET /api/public/bookings/team Returns bookings for the authenticated customer's team. # Team Bookings Returns active bookings for all members of the authenticated customer's team. Team administrators use this to see and manage their team's resource usage. ## Authentication Requires a valid customer bearer token. The customer must be a team member or administrator. ## Query Parameters Comma-separated list of field paths to include in the response. When provided, only the specified fields are returned — useful for reducing payload size. Supports nested paths using dot notation. Example: `_shape=Records.ResourceName,Records.FromTime,Records.ToTime,TotalItems`. ## Response Returns a `MyBookings` object (`ApiListResult`) — a paginated wrapper containing an array of team booking records. Array of booking objects for the current page. Current page number (1-based). Total number of team bookings. Total number of pages. Whether there are more pages after the current one. Whether there are pages before the current one. ## Examples ### Fetch team bookings ```http theme={null} GET /api/public/bookings/team Authorization: Bearer {token} ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' import { MyBookings } from '@/types/endpoints/MyBookings' import { useData } from '@/api/fetchData' const { resource: data } = useData(httpClient, endpoints.bookings.team) ``` # Check-in Endpoint Source: https://learn.nexudus.com/api/endpoints/checkins/checkin-endpoint POST /api/public/checkin Allows customers to check in to the coworking space using various authentication methods including access codes, email/password, access cards, or MAC address. # Check-in Endpoint Allows customers to check in to the coworking space using multiple authentication methods. This endpoint is used by the Members Portal, self-service kiosks, and access control devices (such as WiFi authenticators and door locks) to verify customer identity and grant access. ## Authentication This endpoint does **not** require a bearer token. Instead, authentication is performed using one of the check-in methods described below. The endpoint automatically determines the customer's location based on the account subdomain. ## Request Body The request body is a JSON object using the `CheckInRequest` type. Not all fields are required — the endpoint accepts various combinations of parameters depending on the check-in method you want to use. ### CheckInRequest Fields | Field | Type | Required | Description | | -------------- | ------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------- | | `email` | string | Conditional | Customer's email address. Required for email/password and email/pincode check-in methods. | | `password` | string | Conditional | Customer's account password. Used with `email` for credential-based check-in. | | `pincode` | string | Conditional | Customer's access pincode. Can be used with or without `email`. | | `mac` | string | Conditional | Device MAC address (minimum 8 characters). Used for device-based check-in and auto-check-in. | | `token` | string | Conditional | Access code token. Can be a shared access token or an approved visitor invitation code. | | `accessCardId` | string | Conditional | Physical access card ID/number. Used for card-based check-in. | | `disconnect` | boolean | Optional | If `true`, disconnects the customer from the current session instead of checking in. Requires a valid `mac` address. | | `toggle` | boolean | Optional | If `true`, toggles check-in state (checks in if not checked in, checks out if already checked in). | | `doNotCheckIn` | boolean | Optional | If `true`, performs validation but does not create a check-in record. Useful for verifying access without actually checking in. | ## Check-in Methods The endpoint supports **six** different check-in methods. Only **one** method needs to be used per request. The methods are evaluated in the following priority order: ### 1. Access Token Check-in Uses a shared access code token assigned to the location. **Required fields:** * `token` — The access code token * `mac` — Device MAC address (minimum 8 characters) **Example:** ```json theme={null} { "token": "ABC123XYZ", "mac": "AA:BB:CC:DD:EE:FF" } ``` **Behavior:** * Validates the token against the location's access tokens * If the token is a visitor invitation code, verifies the visitor has been approved by their host * Records the device MAC address against the token * Returns the session expiration time and remaining minutes * Fails if the token has been depleted (no remaining minutes) * Fails if the visitor has not yet been approved by their host **Response:** ```json theme={null} { "wasSuccessful": true, "message": "2026-06-16T18:30:00 UTC", "value": { "tunnelId": "", "sessionExpire": "2026-06-16T18:30:00 UTC", "sessionTimeOut": 3600 } } ``` *** ### 2. MAC Address Auto-Check-in (Token-Based) Automatically checks in a customer based on their device's MAC address if they have an associated access token. **Required fields:** * `mac` — Device MAC address (minimum 8 characters) **Example:** ```json theme={null} { "mac": "AA:BB:CC:DD:EE:FF" } ``` **Behavior:** * Looks up the largest remaining access token associated with the MAC address * If a valid token with remaining minutes is found, uses it for check-in * This method is independent of email/password — it uses pre-configured access tokens *** ### 3. Email and Password Check-in Uses the customer's email and account password. **Required fields:** * `email` — Customer's email address * `password` — Customer's account password **Example:** ```json theme={null} { "email": "john@example.com", "password": "securePassword123" } ``` **Behavior:** * Validates the email and password against the system * Finds the customer's member profile (coworker) associated with the location * If the customer is not registered with this location but sign-up is enabled, automatically registers them * Checks device limit (configurable per location, default 20 devices) * Creates a check-in record *** ### 4. Email and Pincode Check-in Uses the customer's email and a numeric access pincode. **Required fields:** * `email` — Customer's email address * `pincode` — Customer's access pincode **Example:** ```json theme={null} { "email": "john@example.com", "pincode": "1234" } ``` **Behavior:** * Validates the email exists in the system * Looks up the customer's profile(s) for the location (or network-wide) where `AllowNetworkCheckin` is enabled and the `AccessPincode` matches * If the customer is not registered with this location but sign-up is enabled, automatically registers them * Creates a check-in record *** ### 5. Pincode-Only Check-in Uses only a numeric access pincode without an email address. **Required fields:** * `pincode` — Customer's access pincode **Example:** ```json theme={null} { "pincode": "1234" } ``` **Behavior:** * Searches for customers with the matching pincode across the location * **Exactly one** customer must have the pincode — if multiple customers share the same pincode, the request is rejected for security * Automatically enables unique pincode generation for all locations in the network to prevent future conflicts * If the customer is not registered with this location but sign-up is enabled, automatically registers them * Creates a check-in record **Note:** This method is typically used on self-service kiosks where customers prefer to enter only a pincode. *** ### 6. Access Card Check-in Uses a physical access card number. **Required fields:** * `accessCardId` — The card ID/number **Example:** ```json theme={null} { "accessCardId": "CARD-98765" } ``` **Behavior:** * Looks up the customer associated with the access card ID * Validates that the card ID matches one of the customer's registered cards (supports multiple cards separated by commas) * If the customer is not registered with this location but sign-up is enabled, automatically registers them * Creates a check-in record *** ### 7. MAC Address Auto-Check-in (User-Based) Automatically checks in a customer based on their device's MAC address without requiring credentials. **Required fields:** * `mac` — Device MAC address (minimum 8 characters) **Optional fields:** * `email` — Customer's email (helps disambiguate if multiple users have the same MAC) **Example:** ```json theme={null} { "mac": "AA:BB:CC:DD:EE:FF" } ``` **Behavior:** * Only works if `DisableAutoChecking` is **not** enabled for the location * Looks up the user by MAC address (optionally filtered by email) * If both email and MAC are provided, looks up the user by both criteria * If the customer is not registered with this location but sign-up is enabled, automatically registers them * Creates a check-in record **Note:** This method is typically used by WiFi access points and door controllers that automatically detect device MAC addresses. *** ### 8. Disconnect / Check-out Disconnects a customer from the current session. **Required fields:** * `disconnect`: `true` * `mac` — Device MAC address (minimum 8 characters) **Example:** ```json theme={null} { "disconnect": true, "mac": "AA:BB:CC:DD:EE:FF" } ``` **Behavior:** * Finds the largest access token associated with the MAC address * Calculates remaining minutes since last access * If no token is found, performs a full check-out by MAC address * Returns immediately without creating a check-in record *** ### 9. Toggle Check-in Toggles the customer's check-in state — checks in if not checked in, checks out if already checked in. **Required fields:** * `toggle`: `true` **Optional fields:** * Any check-in method fields (email/password, pincode, mac, etc.) **Example:** ```json theme={null} { "toggle": true, "email": "john@example.com", "password": "securePassword123" } ``` **Behavior:** * First authenticates the customer using the provided credentials * If the customer is already checked in, checks them out * If the customer is not checked in, checks them in * Uses the customer's MAC address if provided *** ## Response Returns an `ActionConfirmation` object. ### Success Response ```json theme={null} { "wasSuccessful": true, "message": "2026-06-16T18:30:00 UTC", "value": { "fullName": "John Doe", "coworkerId": 12345, "tunnelId": "abc-def-ghi", "checkedIn": true, "sessionExpire": "2026-06-16T18:30:00 UTC", "sessionTimeOut": 3600 } } ``` ### Check-out Response ```json theme={null} { "wasSuccessful": true, "message": "OK", "value": { "fullName": "John Doe", "coworkerId": 12345, "checkedIn": false, "sessionExpire": "2026-06-16T16:00:00 UTC", "sessionTimeOut": 0 } } ``` ### Error Response ```json theme={null} { "wasSuccessful": false, "message": "Invalid card number.", "errors": [ { "propertyName": "EventCheckIn", "message": "INVALID_CARD_NUMBER" } ] } ``` ### Error Codes | Error Code | Message | Description | | --------------------------- | ------------------------------------------------ | --------------------------------------------------- | | `INVALID_REQUEST_DATA` | "Invalid request data" | Request body is null or malformed | | `INVALID_ACCOUNT_SUBDOMAIN` | "You passed a invalid account subdomain" | Account subdomain could not be resolved | | `INVALID_ACCESS_TOKEN` | "Access token is not valid." | Token does not exist or has expired | | `VISITOR_NOT_APPROVED` | "Visitor has not yet been approved by host." | Visitor invitation token is not yet approved | | `MAC_NOT_RECEIVED` | "MAC address was not received." | MAC address is required but missing or too short | | `TOKEN_DEPLETED` | "This token has been used completely." | Token has no remaining minutes | | `INVALID_CARD_NUMBER` | "Invalid card number." | Card ID not found or does not match customer | | `INVALID_CREDENTIALS` | "Invalid username or password" | Email/password or email/pincode validation failed | | `MISSING_CUSTOMER` | "This user does not have a member linked to it." | User exists but has no member (coworker) profile | | `DEVICE_LIMIT_REACHED` | "You can't register a new device..." | Customer has exceeded the device registration limit | | `NO_ACCESS_TO_SPACE` | "Coworker does not have access to this space" | Customer is not registered with this location | ## Common Use Cases ### Self-Service Kiosk Check-in Kiosks typically use pincode-only or email/password check-in for customer convenience: ```json theme={null} { "pincode": "1234" } ``` ### WiFi Access Point Authentication WiFi access points use MAC address auto-check-in: ```json theme={null} { "mac": "AA:BB:CC:DD:EE:FF" } ``` ### Shared Access Code for Guests Locations can share access tokens with visitors or partners: ```json theme={null} { "token": "GUEST-ACCESS-2026", "mac": "AA:BB:CC:DD:EE:FF" } ``` ### Door Controller with Card Reader Physical access points use card-based check-in: ```json theme={null} { "accessCardId": "CARD-98765" } ``` ## Configuration The check-in behavior can be customized per location using business settings: | Setting | Default | Description | | -------------------------------- | ------- | ------------------------------------------------------------------------------------------------------- | | `Checkin.DeviceCountLimit` | `20` | Maximum number of devices a customer can register | | `Checkin.DailyCutOffTime` | `0` | Daily cutoff time for pass calculations | | `Security.GenerateUniquePincode` | `false` | When enabled, pincode-only check-in generates unique codes | | `DisableAutoChecking` | `false` | When true, disables MAC address auto-check-in | | `MembersSignUp` | `false` | When true, automatically registers customers who check in but are not yet registered with this location | ## Related Documentation * [Check-in Methods](/platform/access-control/check-in-methods) — Overview of all check-in methods available in the Nexudus platform * [Check-in Metrics](/api/endpoints/checkins/checkin-metrics) — Retrieve aggregate check-in metrics * [WiFi Configuration](/platform/access-control/wifi) — Configure WiFi access control # Check-in Metrics Source: https://learn.nexudus.com/api/endpoints/checkins/checkin-metrics GET /api/public/checkins/metrics Returns check-in metrics for the specified business locations. # Check-in Metrics Returns aggregate check-in metrics (current occupancy, daily totals, etc.) for one or more business locations. Used to display occupancy information on the dashboard. ## Authentication Requires a valid customer bearer token. ## Query Parameters Array of business IDs to retrieve metrics for. Passed as repeated query parameters: `businessesIds=1&businessesIds=2`. ## Response Returns check-in metrics for the requested locations. ## Examples ### Fetch metrics for two locations ```http theme={null} GET /api/public/checkins/metrics?businessesIds=1&businessesIds=2 Authorization: Bearer {token} ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' const response = await httpClient.get(endpoints.checkins.metrics([1, 2])) ``` # Get Checkout Fields Source: https://learn.nexudus.com/api/endpoints/checkout/checkout-fields GET /api/public/checkout/fields Returns the configured form fields for the sign-up checkout flow. # Get Checkout Fields Returns the list of form fields configured by the operator for the sign-up/checkout process. Used to dynamically render the sign-up form with required, optional, and custom fields. ## Authentication No authentication required. ## Response Returns an object describing the available checkout form fields and their configuration. ## Examples ### Fetch checkout fields ```http theme={null} GET /api/public/checkout/fields ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' const response = await httpClient.get(endpoints.checkout.fields) ``` # Get Checkout Types Source: https://learn.nexudus.com/api/endpoints/checkout/checkout-types GET /api/public/checkout/types Returns the available resource types, tariff types, and product types for the checkout flow. # Get Checkout Types Returns the system enum values for resource types, tariff types, and product types available in the checkout flow. Used to configure the checkout UI based on what the operator has enabled for members vs. contacts. ## Authentication No authentication required. ## Query Parameters When `true`, returns only types the operator has made visible in the portal. Optional business ID to scope types to a specific location. ## Response All resource types available for checkout. All tariff/plan types available for checkout. All product types available for checkout. Resource types available specifically to members. Resource types available specifically to contacts. Product types available specifically to members. Product types available specifically to contacts. ## Examples ### Fetch checkout types ```http theme={null} GET /api/public/checkout/types?onlyVisible=true ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' const { resource: types } = useTypedData(httpClient, endpoints.checkout.types(true)) ``` # Contact Sign Up Source: https://learn.nexudus.com/api/endpoints/checkout/contact POST /api/public/signup/contact Creates a contact-level account (non-member) through the public sign-up flow. # Contact Sign Up Creates a new contact-level account. Contacts are users who are not full members but have registered interest, attended events, or interacted with the space. This endpoint is used for lighter-weight registration flows. ## Authentication No authentication required. ## Request Body Same dynamic field structure as the main sign-up endpoint, based on operator checkout configuration. Full name of the contact. Email address for the contact account. ## Response Returns a confirmation object on success. ## Examples ### Register a contact ```http theme={null} POST /api/public/signup/contact Content-Type: application/json { "FullName": "John Visitor", "Email": "john@example.com" } ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' await httpClient.post(endpoints.checkout.contact, formData) ``` # Sign Up Source: https://learn.nexudus.com/api/endpoints/checkout/signup POST /api/public/signup Creates a new customer account through the public sign-up flow. # Sign Up Creates a new customer account. The request body should include all required fields from the checkout fields configuration. This is the primary public registration endpoint for new members. ## Authentication No authentication required. ## Request Body The request body wraps the coworker data inside a `Coworker` property, along with additional registration fields. Object containing the new member's profile fields. Fields are dynamic based on operator checkout configuration. Full name of the new member. Email address for the account. Base64-encoded avatar image, if provided during signup. reCAPTCHA token for bot protection. Team GUID if the signup is via a team invite link. Tariff/plan GUID if the signup is via a plan invite link. Plan ID if pre-selecting a membership plan. ## Response Returns a confirmation object with a token for automatic sign-in. Whether the signup was successful. JWT token for automatic sign-in after registration. ## Examples ### Register a new member ```http theme={null} POST /api/public/signup Content-Type: application/json { "Coworker": { "FullName": "Jane Smith", "Email": "jane@example.com" }, "recaptcha": "03AGdBq24...", "Base64Avatar": null } ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' const response = await httpClient.post<{ WasSuccessful: string; Token: string }>(endpoints.checkout.signup, { Coworker: coworkerData, Base64Avatar: avatarBase64, recaptcha: recaptchaToken, TeamGuid: teamGuid, TariffId: planId, }) ``` # Create Thread Message Source: https://learn.nexudus.com/api/endpoints/community/create-message POST /api/public/community/board/threads/{threadId}/messages Posts a reply in a discussion board thread. # Create Thread Message Posts a new reply message in an existing discussion board thread. ## Authentication Requires a valid customer bearer token. ## Path Parameters Numeric identifier of the thread to reply to. ## Request Body The text content of the reply. ## Response Returns a `200 OK` on success. ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' await httpClient.post(endpoints.community.board.messages.create(101), { Content: 'Great suggestion, thanks!', }) ``` # Create Thread Source: https://learn.nexudus.com/api/endpoints/community/create-thread POST /api/public/community/board/threads Creates a new discussion board thread. # Create Thread Creates a new thread in a discussion board group. The authenticated customer becomes the thread author. ## Authentication Requires a valid customer bearer token. ## Request Body The discussion group to post in. Thread title. Thread body content. Optional array of tags to apply. ## Response Returns a `200 OK` on success. ## Examples ### Create a thread ```http theme={null} POST /api/public/community/board/threads Authorization: Bearer {token} Content-Type: application/json { "GroupId": 1, "Title": "Lunch recommendations nearby?", "Content": "Looking for good lunch spots within walking distance.", "Tags": ["food", "local"] } ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' await httpClient.post(endpoints.community.board.threads.create, threadData) ``` # Delete Thread Message Source: https://learn.nexudus.com/api/endpoints/community/delete-message DELETE /api/public/community/board/threads/{threadId}/messages/{messageId} Deletes a message from a discussion board thread. # Delete Thread Message Removes a specific message from a discussion board thread. Only the message author can delete their own messages. ## Authentication Requires a valid customer bearer token. ## Path Parameters Numeric identifier of the thread. Numeric identifier of the message to delete. ## Response Returns a `200 OK` on success. ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' await httpClient.delete(endpoints.community.board.messages.delete(101, 55)) ``` # Delete Thread Source: https://learn.nexudus.com/api/endpoints/community/delete-thread DELETE /api/public/community/board/threads/{threadId} Deletes a discussion board thread. # Delete Thread Removes a discussion board thread and all its messages. Only the thread author can delete their own threads. ## Authentication Requires a valid customer bearer token. ## Path Parameters Numeric identifier of the thread. ## Response Returns a `200 OK` on success. ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' await httpClient.delete(endpoints.community.board.threads.delete(101)) ``` # Follow Thread Source: https://learn.nexudus.com/api/endpoints/community/follow-thread POST /api/public/community/board/threads/{threadId}/follow Toggles follow status on a discussion board thread. # Follow Thread Toggles the authenticated customer's follow status on a thread. Following a thread enables notifications for new replies. ## Authentication Requires a valid customer bearer token. ## Path Parameters Numeric identifier of the thread. ## Response Returns a `200 OK` on success. ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' await httpClient.post(endpoints.community.board.threads.follow(101)) ``` # Get Thread Source: https://learn.nexudus.com/api/endpoints/community/get-thread GET /api/public/community/board/threads/{threadId} Returns the full details of a discussion board thread. # Get Thread Returns the full details of a specific discussion board thread, including the original post content and metadata. ## Authentication Requires a valid customer bearer token. ## Path Parameters Numeric identifier of the thread. ## Query Parameters Comma-separated list of field paths to include in the response. When provided, only the specified fields are returned — useful for reducing payload size. Supports nested paths using dot notation. Example: `_shape=Subject,Message,Tags,MessageCount,LikeCount`. ## Response Returns a thread detail object with the following fields. ### Thread Fields #### Identity | Field | Type | Description | | ---------- | -------- | ---------------------------------------- | | `Id` | `number` | Unique numeric identifier for the thread | | `UniqueId` | `string` | Globally unique identifier | #### Content | Field | Type | Description | | ----------- | ---------- | ------------------------------------ | | `Subject` | `string` | Thread subject / title | | `Message` | `string` | Original post content (HTML-encoded) | | `Tags` | `string` | Comma-separated tag string | | `TagsArray` | `string[]` | Array of individual tag strings | | `Private` | `boolean` | Whether the thread is private | #### Group | Field | Type | Description | | ----------- | ---------------- | ----------------------------- | | `GroupId` | `number \| null` | Discussion group identifier | | `GroupName` | `string \| null` | Discussion group display name | #### Activity | Field | Type | Description | | ----------------- | ---------------- | ---------------------------- | | `PostedOn` | `string` | Date posted (business-local) | | `UtcPostedOn` | `string` | Date posted (UTC) | | `LastMessageDate` | `string \| null` | Date of last reply | #### Video Conference | Field | Type | Description | | --------------- | ---------------- | ------------------------------------- | | `HasZoom` | `boolean` | Whether the thread has a Zoom meeting | | `ZoomUrl` | `string \| null` | Zoom meeting join URL | | `ZoomMeetingId` | `string \| null` | Zoom meeting identifier | #### Nested Objects | Field | Type | Description | | ---------- | -------- | ----------------------------------------------- | | `Business` | `object` | Location object (`Id`, `Name`, `WebAddress`) | | `User` | `object` | Author object (`Id`, `FullName`, `Email`, etc.) | #### Timestamps (from base) | Field | Type | Description | | -------------- | ---------------- | --------------------------------------- | | `CreatedOn` | `string` | Date created (business-local time) | | `UpdatedOn` | `string \| null` | Date last updated (business-local time) | | `CreatedOnUtc` | `string` | Date created (UTC) | | `UpdatedOnUtc` | `string \| null` | Date last updated (UTC) | ## Examples ### Fetch thread ```http theme={null} GET /api/public/community/board/threads/101 Authorization: Bearer {token} ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' const response = await httpClient.get(endpoints.community.board.threads.one(101)) ``` # Like Thread Message Source: https://learn.nexudus.com/api/endpoints/community/like-message POST /api/public/community/board/{threadId}/messages/{messageId}/like Toggles a like on a discussion board message. # Like Thread Message Toggles the authenticated customer's like on a specific message within a thread. ## Authentication Requires a valid customer bearer token. ## Path Parameters Numeric identifier of the thread. Numeric identifier of the message. ## Response Returns a `200 OK` on success. ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' await httpClient.post(endpoints.community.board.messages.like(101, 55)) ``` # Like Thread Source: https://learn.nexudus.com/api/endpoints/community/like-thread POST /api/public/community/board/threads/{threadId}/like Toggles a like on a discussion board thread. # Like Thread Toggles the authenticated customer's like on a thread. Call once to like, call again to unlike. ## Authentication Requires a valid customer bearer token. ## Path Parameters Numeric identifier of the thread. ## Response Returns a `200 OK` on success. ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' await httpClient.post(endpoints.community.board.threads.like(101)) ``` # List Discussion Groups Source: https://learn.nexudus.com/api/endpoints/community/list-groups GET /api/public/community/board/groups Returns the available discussion board groups. # List Discussion Groups Returns the list of discussion board groups (categories/channels) available in the community. Used to populate group selectors and navigation. ## Authentication Requires a valid customer bearer token. ## Query Parameters Comma-separated list of field paths to include in the response. When provided, only the specified fields are returned — useful for reducing payload size. Supports nested paths using dot notation. Example: `_shape=Groups.Name,Groups.Description`. ## Response Returns an array of group objects with the following fields. ### Group Fields #### Identity | Field | Type | Description | | ---------- | -------- | --------------------------------------- | | `Id` | `number` | Unique numeric identifier for the group | | `UniqueId` | `string` | Globally unique identifier | #### Core | Field | Type | Description | | ----------------- | --------- | -------------------------------------------------------- | | `Name` | `string` | Group display name | | `Description` | `string` | Group description | | `GroupAccess` | `string` | Access level (e.g. `Public`, `Private`) | | `CanPostMessages` | `boolean` | Whether the current user can post messages in this group | #### Nested Objects | Field | Type | Description | | ---------- | -------- | -------------------------------------------- | | `Business` | `object` | Location object (`Id`, `Name`, `WebAddress`) | | `User` | `object` | Group owner object (`Id`, `FullName`, etc.) | #### Timestamps (from base) | Field | Type | Description | | -------------- | ---------------- | --------------------------------------- | | `CreatedOn` | `string` | Date created (business-local time) | | `UpdatedOn` | `string \| null` | Date last updated (business-local time) | | `CreatedOnUtc` | `string` | Date created (UTC) | | `UpdatedOnUtc` | `string \| null` | Date last updated (UTC) | ## Examples ### Fetch groups ```http theme={null} GET /api/public/community/board/groups Authorization: Bearer {token} ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' const response = await httpClient.get(endpoints.community.board.groups) ``` # List Thread Messages Source: https://learn.nexudus.com/api/endpoints/community/list-messages GET /api/public/community/board/threads/{threadId}/messages Returns all messages (replies) in a discussion board thread. # List Thread Messages Returns all messages (replies) in a specific discussion board thread, in chronological order. ## Authentication Requires a valid customer bearer token. ## Path Parameters Numeric identifier of the thread. ## Query Parameters Comma-separated list of field paths to include in the response. When provided, only the specified fields are returned — useful for reducing payload size. Supports nested paths using dot notation. Example: `_shape=Records.Message,Records.User,Records.PostedOn`. ## Response Returns an array of message objects with the following fields. ### Message Fields #### Identity | Field | Type | Description | | ---------- | -------- | ----------------------------------------- | | `Id` | `number` | Unique numeric identifier for the message | | `UniqueId` | `string` | Globally unique identifier | #### Content | Field | Type | Description | | ------------- | -------- | --------------------------------- | | `Message` | `string` | Message body text (HTML-encoded) | | `PostedOn` | `string` | Date posted (business-local time) | | `UtcPostedOn` | `string` | Date posted (UTC) | #### Nested Objects | Field | Type | Description | | ----------------- | -------- | ----------------------------------------------- | | `CommunityThread` | `object` | Parent thread object (`Id`, `Subject`, etc.) | | `User` | `object` | Author object (`Id`, `FullName`, `Email`, etc.) | #### Timestamps (from base) | Field | Type | Description | | -------------- | ---------------- | --------------------------------------- | | `CreatedOn` | `string` | Date created (business-local time) | | `UpdatedOn` | `string \| null` | Date last updated (business-local time) | | `CreatedOnUtc` | `string` | Date created (UTC) | | `UpdatedOnUtc` | `string \| null` | Date last updated (UTC) | ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' const response = await httpClient.get(endpoints.community.board.messages.list(101)) ``` # List Discussion Tags Source: https://learn.nexudus.com/api/endpoints/community/list-tags GET /api/public/community/board/tags Returns the available tags for discussion board threads. # List Discussion Tags Returns all tags that can be applied to discussion board threads. Used to populate tag selectors and filters. ## Authentication Requires a valid customer bearer token. ## Response Returns an array of tag strings. ## Examples ### Fetch tags ```http theme={null} GET /api/public/community/board/tags Authorization: Bearer {token} ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' const response = await httpClient.get(endpoints.community.board.tags) ``` # List Discussion Threads Source: https://learn.nexudus.com/api/endpoints/community/list-threads GET /api/public/community/board/threads Returns discussion board threads filtered by group, inbox, query, and tag. # List Discussion Threads Returns a list of discussion board threads for the community feature. Supports filtering by group, inbox type, keyword search, and tag. ## Authentication Requires a valid customer bearer token. ## Query Parameters Filter threads to a specific discussion group. Inbox filter (e.g. `null` for all, or specific inbox type). Keyword search filter. Filter by tag name. Comma-separated list of field paths to include in the response. When provided, only the specified fields are returned — useful for reducing payload size. Supports nested paths using dot notation. Example: `_shape=Records.Subject,Records.LastMessageUtc,Records.MessageCount`. ## Response Returns a paginated list of thread summary objects. ### Thread Summary Fields #### Identity | Field | Type | Description | | ---------------- | -------- | ---------------------------------------- | | `Id` | `number` | Unique numeric identifier for the thread | | `UniqueId` | `string` | Globally unique identifier | | `ThreadUniqueId` | `string` | Thread-specific unique identifier | #### Content | Field | Type | Description | | --------- | ---------- | ----------------------------- | | `Subject` | `string` | Thread subject / title | | `Message` | `string` | Original post content | | `Tags` | `string[]` | Array of tag strings | | `Private` | `boolean` | Whether the thread is private | #### Author | Field | Type | Description | | --------------- | -------- | ---------------------------------- | | `UserId` | `number` | Author user identifier | | `CoworkerId` | `number` | Author coworker identifier | | `FullName` | `string` | Author full name | | `ShortFullName` | `string` | Abbreviated name (first + initial) | #### Group & Location | Field | Type | Description | | -------------------- | -------- | ----------------------------- | | `GroupId` | `number` | Discussion group identifier | | `GroupName` | `string` | Discussion group display name | | `BusinessId` | `number` | Location identifier | | `BusinessName` | `string` | Location display name | | `BusinessWebAddress` | `string` | Location subdomain identifier | #### Activity | Field | Type | Description | | ------------------------- | ---------------- | -------------------------------- | | `MessageCount` | `number` | Total number of replies | | `LikeCount` | `number` | Total number of likes | | `LastMessage` | `string \| null` | Last reply date (business-local) | | `LastMessageUtc` | `string \| null` | Last reply date (UTC) | | `LastMessageText` | `string` | Last reply message text | | `LastMessageUserFullName` | `string` | Name of last reply author | | `LastMessageCoworkerId` | `number \| null` | Coworker id of last reply author | | `LastMessageId` | `number \| null` | Id of the last reply message | #### Participation | Field | Type | Description | | -------------- | ---------- | ----------------------------------- | | `Participants` | `string[]` | Array of participant identifiers | | `FullNames` | `string[]` | Array of participant full names | | `Likes` | `string[]` | Array of users who liked the thread | | `FileIDs` | `string[]` | Array of attached file identifiers | | `FileNames` | `string[]` | Array of attached file names | #### User State | Field | Type | Description | | ---------------- | --------- | ------------------------------------ | | `MutedForUser` | `boolean` | Whether muted by the current user | | `FollowedByUser` | `boolean` | Whether followed by the current user | | `LikedByUser` | `boolean` | Whether liked by the current user | #### Timestamps | Field | Type | Description | | -------------- | ---------------- | --------------------------------------- | | `PostedOn` | `string` | Date posted (business-local time) | | `PostedOnUtc` | `string` | Date posted (UTC) | | `CreatedOn` | `string` | Date created (business-local time) | | `UpdatedOn` | `string \| null` | Date last updated (business-local time) | | `CreatedOnUtc` | `string` | Date created (UTC) | | `UpdatedOnUtc` | `string \| null` | Date last updated (UTC) | ## Examples ### Fetch threads in a group ```http theme={null} GET /api/public/community/board/threads?groupId=1&inbox=&query=&tag= Authorization: Bearer {token} ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' const response = await httpClient.get(endpoints.community.board.list(1)) ``` # Mute Thread Source: https://learn.nexudus.com/api/endpoints/community/mute-thread POST /api/public/community/board/threads/{threadId}/mute Toggles mute status on a discussion board thread. # Mute Thread Toggles the authenticated customer's mute status on a thread. Muting suppresses notifications for replies on the thread. ## Authentication Requires a valid customer bearer token. ## Path Parameters Numeric identifier of the thread. ## Response Returns a `200 OK` on success. ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' await httpClient.post(endpoints.community.board.threads.mute(101)) ``` # Complete Lesson Source: https://learn.nexudus.com/api/endpoints/courses/complete-lesson POST /api/public/courses/{courseId}/lessons/{lessonUniqueId}/complete Marks a lesson as completed for the authenticated customer. # Complete Lesson Marks a specific lesson as completed for the authenticated customer. Progress is tracked per customer per course. Once all lessons are completed, the course is considered finished. ## Authentication Requires a valid customer bearer token. ## Path Parameters Numeric identifier of the course. The UUID (`UniqueId`) of the lesson to mark as complete. Obtained from `GET /api/public/courses/v2/{courseId}/lessons/{lessonId}`. ## Request Body No request body required. ## Response Returns a `200 OK` on success. ## Examples ### Mark a lesson as complete ```http theme={null} POST /api/public/courses/42/lessons/a1b2c3d4-e5f6-7890-abcd-ef1234567890/complete Authorization: Bearer {token} ``` ``` HTTP/1.1 200 OK ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' await httpClient.post(endpoints.courses.completeLesson(42, 'a1b2c3d4-e5f6-7890-abcd-ef1234567890').url) ``` # Get Course Details Source: https://learn.nexudus.com/api/endpoints/courses/course-details GET /api/public/courses/v2/{id}/summary Returns the summary and metadata for a single course. # Get Course Details Returns the full summary for a specific course, including description, lesson count, and enrolment status. Used on the course detail page before the member chooses to enrol. ## Authentication No authentication required for public course details. Enrolment status fields are populated only for authenticated customers. ## Path Parameters Numeric identifier of the course. Returned as `Id` in the records from `GET /api/public/courses/v2`. ## Query Parameters Comma-separated list of field paths to include in the response. When provided, only the specified fields are returned — useful for reducing payload size. Supports nested paths using dot notation. ## Response Returns a `CourseSummary` object. The course metadata is nested inside a `Course` property. Whether the authenticated customer is enrolled in this course. Whether the authenticated customer has completed this course. Completion percentage (0–100). Total number of lessons in the course. The course metadata object. Unique identifier for the course. Display title of the course. Full course description. May contain HTML. Short summary text for the course. Array of lesson summaries for the course. The host/instructor of the course. Pricing information for the course, if applicable. ## Examples ### Fetch course summary ```http theme={null} GET /api/public/courses/v2/42/summary ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' const { resource: course } = useTypedData(httpClient, endpoints.courses.details(42)) ``` # Get Course Lesson Source: https://learn.nexudus.com/api/endpoints/courses/course-lesson GET /api/public/courses/v2/{courseId}/lessons/{lessonId} Returns the full content of a single lesson within a course. # Get Course Lesson Returns the full content and metadata for a specific lesson within a course. Used to display lesson content and allow the customer to mark it as complete. ## Authentication Requires a valid customer bearer token. ## Path Parameters Numeric identifier of the course. Numeric identifier of the lesson within the course. ## Query Parameters Comma-separated list of field paths to include in the response. When provided, only the specified fields are returned — useful for reducing payload size. Supports nested paths using dot notation. ## Response Returns a `CourseLesson` object. The lesson content is nested inside a `Lesson` property. The lesson content object. Unique identifier for the lesson. UUID for the lesson — used as `{lessonUniqueId}` in the complete-lesson endpoint. Display title of the lesson. Full lesson content. May contain HTML. Short summary text for the lesson. Whether the authenticated customer has marked this lesson as complete. Whether there is a next lesson in the course. Whether this is the last active (uncompleted) lesson. The parent course summary. The section this lesson belongs to. ## Examples ### Fetch a lesson ```http theme={null} GET /api/public/courses/v2/42/lessons/7 Authorization: Bearer {token} ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' const { resource: lesson } = useTypedData(httpClient, endpoints.courses.lesson(42, 7)) ``` # List Course Lessons Source: https://learn.nexudus.com/api/endpoints/courses/course-lessons GET /api/public/courses/v2/{courseId}/lessons Returns all lessons belonging to a specific course. # List Course Lessons Returns the ordered list of lessons for a specific course. Used to render the course syllabus and track which lessons the customer has completed. ## Authentication Requires a valid customer bearer token to include completion status. ## Path Parameters Numeric identifier of the course. Returned as `Id` from `GET /api/public/courses/v2`. ## Query Parameters Comma-separated list of field paths to include in the response. When provided, only the specified fields are returned — useful for reducing payload size. Supports nested paths using dot notation. ## Response Returns a `CourseSummary` object containing the lessons array and course-level metadata. ### Top-Level Fields | Field | Type | Description | | ----------------- | --------- | ---------------------------------------------- | | `Enrolled` | `boolean` | Whether the customer is enrolled in the course | | `Completed` | `boolean` | Whether the customer has completed the course | | `Completeness` | `number` | Completion percentage (0–1) | | `CanAccessCourse` | `boolean` | Whether the customer can access course content | | `AttendeeCount` | `number` | Number of enrolled attendees | | `LessonsCount` | `number` | Total number of lessons | | `CreatedOnUtc` | `string` | Course creation date (UTC) | ### Attendee (current customer) | Field | Type | Description | | -------------- | -------- | -------------------------------- | | `Id` | `number` | Attendee record identifier | | `FullName` | `string` | Attendee full name | | `Email` | `string` | Attendee email | | `CreatedOn` | `string` | Enrollment date (business-local) | | `CreatedOnUtc` | `string` | Enrollment date (UTC) | ### Course | Field | Type | Description | | ------------------- | ---------------- | ----------------------------------------- | | `Id` | `number` | Course identifier | | `Title` | `string` | Course title | | `SummaryText` | `string` | Short course summary | | `FullDescription` | `string` | Full course description (HTML) | | `OverviewText` | `string` | Course overview text | | `GroupName` | `string` | Course group / category name | | `Visibility` | `string` | Visibility setting | | `Active` | `boolean` | Whether the course is active | | `ShowInHomePage` | `boolean` | Whether shown on the home page | | `ShowOverview` | `boolean` | Whether the overview tab is visible | | `HasCommunityGroup` | `boolean` | Whether the course has a discussion group | | `CreatedOn` | `string` | Date created (business-local time) | | `CreatedOnUtc` | `string` | Date created (UTC) | | `UpdatedOn` | `string \| null` | Date last updated (business-local time) | | `UpdatedOnUtc` | `string \| null` | Date last updated (UTC) | ### Lessons Array | Field | Type | Description | | -------------- | --------- | ------------------------------------- | | `Id` | `number` | Lesson identifier | | `Title` | `string` | Lesson title | | `SummaryText` | `string` | Lesson summary text | | `DisplayOrder` | `number` | Sort order within the course | | `IsOpen` | `boolean` | Whether the lesson is available | | `IsComplete` | `boolean` | Whether the customer has completed it | ### Lessons Section (nested) | Field | Type | Description | | ---------------------- | -------- | ------------------ | | `Section.Id` | `number` | Section identifier | | `Section.Title` | `string` | Section title | | `Section.DisplayOrder` | `number` | Section sort order | ### Other | Field | Type | Description | | ---------------- | ---------------- | -------------------------------------- | | `Tariff` | `object \| null` | Associated plan/tariff (if any) | | `Host` | `object \| null` | Course host profile | | `CommunityGroup` | `object \| null` | Linked discussion group (`Id`, `Name`) | | `CurrentLesson` | `object \| null` | The first open, incomplete lesson | ## Examples ### Fetch lessons for a course ```http theme={null} GET /api/public/courses/v2/42/lessons Authorization: Bearer {token} ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' const { resource: lessons } = useTypedData(httpClient, endpoints.courses.lessons(42)) ``` # Enrol in Course Source: https://learn.nexudus.com/api/endpoints/courses/enroll-course POST /api/public/courses/{id}/signup Enrols the authenticated customer in a published course. # Enrol in Course Registers the authenticated customer as an enrolled participant in the specified course. After enrolment, the customer can access lessons and track progress. ## Authentication Requires a valid customer bearer token. ## Path Parameters Numeric identifier of the course to enrol in. Returned as `Id` from `GET /api/public/courses/v2`. ## Request Body No request body required. ## Response Returns a `200 OK` on successful enrolment. ## Examples ### Enrol in a course ```http theme={null} POST /api/public/courses/42/signup Authorization: Bearer {token} ``` ``` HTTP/1.1 200 OK ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' await httpClient.post(endpoints.courses.enroll(42).url) ``` # List Courses Source: https://learn.nexudus.com/api/endpoints/courses/list-courses GET /api/public/courses/v2 Returns a paginated list of published courses, with optional filtering by category, keyword, and home page flag. # List Courses Returns a paginated list of published courses for the current location. Supports filtering by category name, keyword search, and a flag to only return courses marked for the home page. A **course** is a structured learning programme created by the space operator, consisting of multiple lessons. Members can enrol, track progress, and complete lessons through the portal. ## Authentication No authentication required. ## Query Parameters 1-based page number. Number of courses per page. Filter by category name. Omit to return courses across all categories. Keyword filter applied to course name and description. URL-encoded. When `true`, returns only courses flagged to appear on the portal home page. Comma-separated list of field paths to include in the response. When provided, only the specified fields are returned — useful for reducing payload size. Supports nested paths using dot notation. Example: `_shape=Courses.Records.Name,Courses.Records.Description,Categories`. ## Response Returns a `CourseList` object containing available categories and a paginated list of course summaries. Array of all available course category names for filtering. Paginated wrapper containing course records. Array of course summaries for the current page. Current page number. Total number of matching courses. Total number of pages. Whether there are more pages after the current one. ## Examples ### Fetch first page of courses ```http theme={null} GET /api/public/courses/v2?page=1&top=10 ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' const { resource: courses } = useTypedData( httpClient, endpoints.courses.list({ page: 1, top: 10, categoryName: 'Marketing', }), ) ``` # List My Courses Source: https://learn.nexudus.com/api/endpoints/courses/my-courses GET /api/public/courses/v2/my Returns all courses the authenticated customer is enrolled in. # List My Courses Returns a paginated list of courses the authenticated customer has enrolled in. Includes progress information such as completed lesson count. ## Authentication Requires a valid customer bearer token. ## Query Parameters Comma-separated list of field paths to include in the response. When provided, only the specified fields are returned — useful for reducing payload size. Supports nested paths using dot notation. Example: `_shape=Records.Name,Records.Description,Records.Progress`. ## Response Returns an `ApiListResult` with the customer's enrolled courses and progress. The top-level response includes standard pagination fields (`CurrentPage`, `TotalItems`, `TotalPages`, etc.). Each item in the `Records` array has: #### Status | Field | Type | Description | | ----------------- | --------- | --------------------------------------------- | | `Enrolled` | `boolean` | Whether the customer is enrolled | | `Completed` | `boolean` | Whether the customer has completed the course | | `Completeness` | `number` | Completion percentage (0–1) | | `CanAccessCourse` | `boolean` | Whether the customer can access the course | #### Counts | Field | Type | Description | | --------------- | -------- | ------------------------- | | `AttendeeCount` | `number` | Total number of attendees | | `LessonsCount` | `number` | Total number of lessons | #### Attendee | Field | Type | Description | | ----------------------- | -------- | ---------------------- | | `Attendee.Id` | `number` | Attendee identifier | | `Attendee.FullName` | `string` | Attendee full name | | `Attendee.Email` | `string` | Attendee email address | | `Attendee.CreatedOn` | `string` | Enrolment date (local) | | `Attendee.CreatedOnUtc` | `string` | Enrolment date (UTC) | #### Course | Field | Type | Description | | -------------------------- | ---------- | ------------------------------------ | | `Course.Id` | `number` | Course identifier | | `Course.Title` | `string` | Course title | | `Course.SummaryText` | `string` | Short course summary | | `Course.FullDescription` | `string` | Full course description | | `Course.OverviewText` | `string` | Course overview text | | `Course.GroupName` | `string` | Course group/category name | | `Course.Visibility` | `string` | Course visibility setting | | `Course.Active` | `boolean` | Whether the course is active | | `Course.ShowInHomePage` | `boolean` | Whether shown on home page | | `Course.ShowOverview` | `boolean` | Whether overview is shown | | `Course.HasCommunityGroup` | `boolean` | Whether course has a community group | | `Course.Business` | `Business` | Business hosting the course | #### Nested Objects | Field | Type | Description | | ---------------- | ------------ | ------------------------------- | | `Tariff` | `Tariff` | Associated plan/tariff | | `Attendees` | `Coworker[]` | List of course attendees | | `CommunityGroup` | `object` | Community group (`Id`, `Name`) | | `Lessons` | `object[]` | Course lessons | | `Host` | `Coworker` | Course host/instructor | | `CreatedOnUtc` | `string` | Record creation timestamp (UTC) | ## Examples ### Fetch enrolled courses ```http theme={null} GET /api/public/courses/v2/my Authorization: Bearer {token} ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' const { resource: myCourses } = useTypedData(httpClient, endpoints.courses.my()) ``` # Get Customer Benefits Source: https://learn.nexudus.com/api/endpoints/coworkers/customer-benefits GET /api/public/coworkers/profiles/current/benefits Retrieve the plan benefits available to the current customer profile, including booking credits, extra services, and time passes. # Get Customer Benefits Returns all plan benefits currently available to the active customer profile. Benefits are granted through active plan (tariff) subscriptions and include booking credits, extra services (such as printing), and time passes. The portal uses this to display the benefits panel on the My Plans page and to gate access to credit-based features. ## Authentication Requires a valid customer bearer token. ## Query Parameters Comma-separated list of field paths to include in the response. When provided, only the specified fields are returned — useful for reducing payload size. Supports nested paths using dot notation. ## Response The response is split into `Personal` benefits (belonging to the individual profile) and `Team` benefits (shared across the customer's team). Benefits belonging to the individual customer profile. Booking credit allowances granted by active plans. Unique identifier for the booking credit record. Display name of the booking credit allowance. Total credit amount granted (in the location's currency). Remaining credit balance available to spend. `true` when this credit can be applied to room and desk bookings. `true` when this credit can be applied to event ticket purchases. `true` when this credit applies to all resource types. `true` when this credit was granted by an active plan subscription rather than manually assigned. ISO 8601 datetime when this credit expires. `null` if it does not expire. Extra service allowances (e.g. printing credits) granted by active plans. Unique identifier for the extra service record. Identifier of the extra service type. Display name of the extra service. `true` when this service is a printing credit (e.g. PaperCut integration). Total number of uses granted. Remaining uses available. How uses are measured: `"Minutes"`, `"Days"`, `"Weeks"`, `"Months"`, `"Uses"`, or `"FourWeekMonths"`. `true` when granted by an active plan subscription. ISO 8601 expiry datetime. `null` if it does not expire. Time pass allowances granted by active plans. Unique identifier for the time pass record. Identifier of the time pass type. Display name of the time pass. Total number of uses granted. `null` for unlimited passes. Remaining uses. `null` for unlimited passes. `true` when this specific time pass instance has been used. `true` when granted by an active plan subscription. ISO 8601 expiry datetime. `null` if it does not expire. Benefits shared with the customer's team. Contains the same structure as `Personal` (`BookingCredits`, `ExtraServices`, `TimePasses`). ## Example Response ```json theme={null} { "Personal": { "BookingCredits": [ { "Id": 5, "Name": "Monthly Booking Allowance", "TotalCredit": 200.0, "RemainingCredit": 145.5, "CaneBeUsedForBookings": true, "CaneBeUsedForEvents": false, "IsUniversalCredit": false, "IsFromTariff": true, "ExpireDate": "2026-04-30T23:59:59Z" } ], "ExtraServices": [], "TimePasses": [ { "Id": 12, "TimePass": { "Id": 3, "Name": "Day Pass" }, "TotalUses": 5, "RemainingUses": 3, "Used": false, "IsFromTariff": true, "ExpireDate": null } ] }, "Team": { "BookingCredits": [], "ExtraServices": [], "TimePasses": [] } } ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' import { MyBenefits } from '@/types/public/billing/MyBenefits' import { useData } from '@/api/fetchData' import { createShape } from '@/helpers/shape-helper' const shape = createShape()([ 'Personal.BookingCredits.Id', 'Personal.BookingCredits.Name', 'Personal.BookingCredits.RemainingCredit', 'Personal.TimePasses.Id', 'Personal.TimePasses.TimePass.Name', 'Personal.TimePasses.RemainingUses', ]) const { resource: benefits } = useData(httpClient, endpoints.coworkers.benefits, { shape: shape.fields, }) ``` ## Usage in Portal | Context | Source file | | ------------------------------ | ------------------------------------------------------- | | My Plans page — benefits panel | `src/views/user/plans/useMyBenefitsData.ts` | | Benefits display component | `src/views/user/plans/components/MyBenefitsSection.tsx` | ## Error Responses The bearer token is missing, expired, or invalid. ## Related Endpoints | Method | Endpoint | Description | | ------ | ---------------------------------------- | ------------------------------------------ | | `GET` | `/api/public/coworkers/profiles` | List all profiles for the current session | | `GET` | `/api/public/plans/my` | List active plans for the current customer | | `PUT` | `/api/public/coworkers/profiles/current` | Switch the active profile | # List Published Customer Profiles Source: https://learn.nexudus.com/api/endpoints/coworkers/directory-list GET /api/public/coworkers/published Retrieve a paginated, searchable list of published customer profiles shown in the member directory. # List Published Customer Profiles Returns customer profiles that have opted in to the member directory (`ProfileIsPublic: true`). Supports free-text search, tag filtering, and sort ordering. The portal uses this to render the member directory listing and to power the customer tag input autocomplete. ## Authentication Requires a valid customer bearer token. ## Query Parameters Free-text search string matched against the customer's name, company, position, bio, and tags. Pass an empty string to return all published profiles. Filter results to customers whose `ProfileTagsList` contains this exact tag value. Pass an empty string to skip tag filtering. Sort order for results. **Default**: `1` (alphabetical by name). Check the directory meta endpoint for available order options. Comma-separated list of field paths to include in the response. When provided, only the specified fields are returned — useful for reducing payload size. Supports nested paths using dot notation. Example: `_shape=Records.FullName,Records.CompanyName,Records.AvatarUrl,TotalItems`. ## Response Returns an `ApiListResult` — a paginated wrapper containing an array of published customer profiles. ### Pagination Array of published customer profiles for the current page. Current page number (1-based). Total number of matching published profiles. Total number of pages. Whether there are more pages after the current one. Whether there are pages before the current one. ### Coworker Fields (within `Records[]`) Unique numeric identifier for the customer profile. Use as `coworkerId` in `GET /api/public/coworkers/published/{coworkerId}`. Globally unique identifier for the profile. Customer's display name. First name extracted from `FullName` for use in personalised UI text. URL to the customer's avatar image. Job title. Company name. Industry or area of work. Professional bio. May contain Markdown. Personal or company website URL. Array of tag strings from the customer's profile. Display name of the location this customer is invoiced at. ### Social Media (within `Records[]`) | Field | Type | Description | | ----------- | ---------------- | ------------------------------ | | `Twitter` | `string \| null` | Twitter profile URL or handle | | `Linkedin` | `string \| null` | LinkedIn profile URL | | `Github` | `string \| null` | GitHub profile URL or username | | `Instagram` | `string \| null` | Instagram handle or URL | | `Facebook` | `string \| null` | Facebook profile URL | | `Skype` | `string \| null` | Skype username | | `Telegram` | `string \| null` | Telegram username | ## Example Response ```json theme={null} { "Records": [ { "Id": 101, "UniqueId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "FullName": "Jane Doe", "GuessedFirstName": "Jane", "AvatarUrl": "https://nexudushq.spaces.nexudus.com/media/coworker/101/avatar", "Position": "Product Designer", "CompanyName": "Acme Design Co.", "BusinessArea": "Design", "ProfileSummary": "Jane specialises in design systems and user research.", "ProfileWebsite": "https://janedoe.design", "ProfileTagsList": ["UX", "Design Systems", "Research"], "InvoicingSpaceName": "Nexudus HQ", "Linkedin": "https://linkedin.com/in/janedoe", "Twitter": null } ], "CurrentPage": 1, "TotalItems": 42, "TotalPages": 5, "HasNextPage": true, "HasPreviousPage": false } ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' import { Coworker } from '@/types/spaces/Coworker' import { ApiListResult } from '@/types/ApiListResult' import { useData } from '@/api/fetchData' const url = endpoints.coworkers.directory.published_list(searchQuery, selectedTag, sortOrder) // => '/api/public/coworkers/published?query=design&tag=UX&order=1' const { resource: members } = useData>(httpClient, url) ``` ## Usage in Portal | Context | Source file | | ------------------------------- | -------------------------------------------------------------- | | Member directory listing page | `src/views/community/directory/components/useDirectoryData.ts` | | Customer tag autocomplete input | `src/components/CoworkerTagInput.tsx` | ## Error Responses The bearer token is missing, expired, or invalid. ## Related Endpoints | Method | Endpoint | Description | | ------ | ------------------------------------------------------ | ----------------------------------------- | | `GET` | `/api/public/coworkers/published/{coworkerId}` | Get a single published customer profile | | `GET` | `/api/public/coworkers/published/{coworkerId}/related` | Get related profiles for a customer | | `GET` | `/api/public/coworkers/directory/meta` | Get directory configuration and tag cloud | # Get Directory Meta Source: https://learn.nexudus.com/api/endpoints/coworkers/directory-meta GET /api/public/coworkers/directory/meta Retrieve directory configuration and the tag cloud for the customer member directory. # Get Directory Meta Returns configuration settings and tag cloud data for the customer member directory. The portal uses this to determine whether the directory is enabled, what content it shows, and which filter tags to display in the directory sidebar. ## Authentication Requires a valid customer bearer token. ## Query Parameters Comma-separated list of field paths to include in the response. When provided, only the specified fields are returned — useful for reducing payload size. Supports nested paths using dot notation. ## Response `true` when the member directory feature is active for this location. When `false`, the directory page should not be rendered. Controls whose profiles appear in the directory: - `1` — Published profiles only - `2` — Published profiles with an active plan - `3` — Everyone (all customers) - `4` — Everyone with an active plan Controls what record types appear: - `1` — Teams and individual members - `2` — Teams only - `3` — Individual members only When `true`, only customers invoiced at the current location are shown in the directory. When `true`, customers who are currently checked in are highlighted in the directory. Tag cloud used to populate the directory filter sidebar. Each entry represents a tag and its relative frequency. The tag string value (matches entries in `Coworker.ProfileTagsList`). Number of published profiles that have this tag. This tag's share of total tagged profiles, as a percentage (0–100). ## Example Response ```json theme={null} { "Meta": { "DirectoryEnabled": true, "DirectoryContents": 1, "DirectoryRecords": 1, "OnlyInvoicingSpace": false, "ShowCheckInMembers": true, "Tags": [ { "Tag": "UX", "Count": 12, "Percentage": 24.0 }, { "Tag": "Design Systems", "Count": 8, "Percentage": 16.0 }, { "Tag": "Research", "Count": 6, "Percentage": 12.0 } ] } } ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' import { DirectoryMetaData } from '@/types/endpoints/DirectoryMeta' import { useData } from '@/api/fetchData' const { resource: meta } = useData(httpClient, endpoints.coworkers.directory.meta) if (!meta?.Meta.DirectoryEnabled) { // Hide the directory navigation item } ``` ## Usage in Portal | Context | Source file | | ----------------------------------------------------- | -------------------------------------------------------------- | | Member directory page — tag cloud filter and settings | `src/views/community/directory/components/useDirectoryData.ts` | ## Error Responses The bearer token is missing, expired, or invalid. ## Related Endpoints | Method | Endpoint | Description | | ------ | ---------------------------------- | ---------------------------------------------- | | `GET` | `/api/public/coworkers/published` | List published profiles in the directory | | `GET` | `/api/public/teams/directory/meta` | Get the equivalent meta for the team directory | # Get Published Customer Profile Source: https://learn.nexudus.com/api/endpoints/coworkers/directory-profile GET /api/public/coworkers/published/{coworkerId} Retrieve the full published directory profile for a single customer by their ID. # Get Published Customer Profile Returns the full directory profile for a single customer who has opted in to the member directory. The portal loads this when a customer opens a profile card in the member directory, displaying their professional bio, social links, location, and related profiles. ## Authentication Requires a valid customer bearer token. ## Path Parameters The numeric identifier of the customer profile to retrieve. Obtain this from `GET /api/public/coworkers/published` (`[].Id`). ## Query Parameters Comma-separated list of field paths to include in the response. When provided, only the specified fields are returned — useful for reducing payload size. Supports nested paths using dot notation. Example: `_shape=Coworker.FullName,Coworker.CompanyName,Coworker.AvatarUrl`. ## Response Returns a wrapper object containing a single `Coworker` property. See [List Published Customer Profiles](/api/endpoints/coworkers/directory-list) for the full set of coworker fields. The published customer profile object. ### Core Identity (within `Coworker`) Unique numeric identifier for the customer profile. Customer's display name. First name inferred from `FullName`. Used in personalised UI messages. URL to the customer's avatar image. ### Professional Profile (within `Coworker`) Job title. Company name. Full professional bio. May contain Markdown. Personal or company website URL. Array of tag strings from the customer's profile. ### Social Media (within `Coworker`) | Field | Type | Description | | ----------- | ---------------- | ------------------------------ | | `Twitter` | `string \| null` | Twitter profile URL or handle | | `Linkedin` | `string \| null` | LinkedIn profile URL | | `Github` | `string \| null` | GitHub profile URL or username | | `Instagram` | `string \| null` | Instagram handle or URL | | `Facebook` | `string \| null` | Facebook profile URL | | `Skype` | `string \| null` | Skype username | | `Telegram` | `string \| null` | Telegram username | ## Example Response ```json theme={null} { "Coworker": { "Id": 101, "UniqueId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "FullName": "Jane Doe", "GuessedFirstName": "Jane", "AvatarUrl": "https://nexudushq.spaces.nexudus.com/media/coworker/101/avatar", "Position": "Product Designer", "CompanyName": "Acme Design Co.", "ProfileSummary": "Jane is a product designer with over 8 years of experience building intuitive digital products. She specialises in design systems and user research.", "ProfileWebsite": "https://janedoe.design", "ProfileTagsList": ["UX", "Design Systems", "Research"], "InvoicingSpaceName": "Nexudus HQ", "Linkedin": "https://linkedin.com/in/janedoe", "Twitter": null, "Github": "https://github.com/janedoe" } } ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' import { Coworker } from '@/types/spaces/Coworker' import { useData } from '@/api/fetchData' const url = endpoints.coworkers.directory.published_one(coworkerId) // => '/api/public/coworkers/published/101' const { resource: coworkerData } = useData<{ Coworker: Coworker }>(httpClient, url) ``` ## Usage in Portal | Context | Source file | | ------------------------------ | ----------------------------------------------------------------------------- | | Member directory profile modal | `src/views/community/directory/components/CoworkersDirectoryProfileModal.tsx` | ## Error Responses The bearer token is missing, expired, or invalid. No published profile with the given `coworkerId` was found, or the customer has set `ProfileIsPublic` to `false`. ## Related Endpoints | Method | Endpoint | Description | | ------ | ------------------------------------------------------ | -------------------------------------------- | | `GET` | `/api/public/coworkers/published` | List all published profiles in the directory | | `GET` | `/api/public/coworkers/published/{coworkerId}/related` | Get profiles related to this customer | | `GET` | `/api/public/coworkers/directory/meta` | Get directory settings and tag cloud | # Get Related Customer Profiles Source: https://learn.nexudus.com/api/endpoints/coworkers/directory-related GET /api/public/coworkers/published/{coworkerId}/related Retrieve customer profiles related to a given customer, based on shared tags, location, or other affinity signals. # Get Related Customer Profiles Returns a list of customer profiles that are related to the specified customer. Related profiles are surfaced at the bottom of a customer's directory profile card to encourage discovery and connections within the community. ## Authentication Requires a valid customer bearer token. ## Path Parameters The numeric identifier of the customer whose related profiles you want to retrieve. Obtain this from `GET /api/public/coworkers/published` (`[].Id`). ## Query Parameters Comma-separated list of field paths to include in the response. When provided, only the specified fields are returned — useful for reducing payload size. Supports nested paths using dot notation. ## Response Returns an object containing related customer profiles and community threads for the specified customer. Array of customer profiles related to the specified customer. May be empty if no related profiles are found. Array of community threads associated with the specified customer. ### Coworker Fields (within `RelatedProfiles[]`) Unique identifier for the related customer profile. Display name of the related customer. URL to the related customer's avatar image. Job title of the related customer. Company name of the related customer. Tags shared between the source customer and the related customer. ## Example Response ```json theme={null} { "RelatedProfiles": [ { "Id": 202, "FullName": "Carlos Ruiz", "AvatarUrl": "https://nexudushq.spaces.nexudus.com/media/coworker/202/avatar", "GuessedFirstName": "Carlos", "Position": "UX Researcher", "CompanyName": "Ruiz UX Studio", "ProfileTagsList": ["UX", "Research"] } ], "Threads": [] } ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' import { Coworker } from '@/types/spaces/Coworker' import { CommunityThread } from '@/types/spaces/CommunityThread' import { useData } from '@/api/fetchData' const url = endpoints.coworkers.directory.related(coworkerId) // => '/api/public/coworkers/published/101/related' const { resource: related } = useData<{ RelatedProfiles: Coworker[]; Threads: CommunityThread[] }>(httpClient, url) ``` ## Usage in Portal | Context | Source file | | --------------------------------------------------- | ----------------------------------------------------------------------------- | | Related profiles section in directory profile modal | `src/views/community/directory/components/CoworkersDirectoryProfileModal.tsx` | ## Error Responses The bearer token is missing, expired, or invalid. No published profile with the given `coworkerId` was found. ## Related Endpoints | Method | Endpoint | Description | | ------ | ---------------------------------------------- | -------------------------------------------- | | `GET` | `/api/public/coworkers/published/{coworkerId}` | Get the full profile for this customer | | `GET` | `/api/public/coworkers/published` | List all published profiles in the directory | # Impersonate Customer Source: https://learn.nexudus.com/api/endpoints/coworkers/impersonate GET /api/public/coworkers/{coworkerId}/impersonate Generate an impersonation token so a team administrator can sign in as another team member. # Impersonate Customer Returns a short-lived token that can be exchanged for a full auth session as the target customer. Used in the portal when a team administrator chooses to sign in on behalf of a team member — both from the sign-in profile selection flow and from the team permissions page. ## Authentication Requires a valid customer bearer token. The authenticated customer must have the necessary permission (e.g. team admin rights) to impersonate the target customer. ## Path Parameters The numeric identifier of the customer profile to impersonate. Obtain this from `GET /api/public/coworkers/profiles` (`Profiles[].Id`). ## Response Returns a JSON object containing a single `token` field. Pass this token to the token-exchange endpoint (`POST /api/public/auth/login/{token}`) to obtain a full auth session as the target customer. A short-lived token string. Exchange it via `exchangeToken()` (which calls the login endpoint) to start an impersonated session. ## Examples ### Impersonate a team member ```http theme={null} GET /api/public/coworkers/42/impersonate Authorization: Bearer {token} ``` ```json theme={null} { "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." } ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' import { useSignIn } from '@/views/auth/SignIn/useSignIn' // useSignIn exposes the impersonate helper const { impersonate } = useSignIn() // Internally this does: // 1. GET /api/public/coworkers/{id}/impersonate → { token } // 2. POST /api/public/auth/login/{token} → full session const response = await httpClient.get<{ token: string }>(endpoints.coworkers.impersonate(coworkerId)) await exchangeToken(response.data.token, true) await queryContext.invalidateQueries() ``` ## Usage in Portal | Context | Source file | | ---------------------------------------- | -------------------------------------------------------------------- | | Sign-in profile selection flow | `src/views/auth/SignIn/useSignIn.ts` | | Team permissions — "Impersonate account" | `src/views/user/team/permissions/components/TeamPermissionTable.tsx` | ## Error Responses The bearer token is missing, expired, or invalid. The authenticated customer does not have permission to impersonate the specified profile. No customer with the given `coworkerId` was found. ## Related Endpoints | Method | Endpoint | Description | | ------ | ---------------------------------------- | ---------------------------------------------------- | | `GET` | `/api/public/coworkers/profiles` | List all profiles for the current session | | `PUT` | `/api/public/coworkers/profiles/current` | Switch the active profile without impersonation | | `GET` | `/api/sys/users/impersonate` | Admin-level impersonation (requires operator access) | # List Customer Profiles Source: https://learn.nexudus.com/api/endpoints/coworkers/list-profiles GET /api/public/coworkers/profiles Retrieve all customer profiles accessible to the current session, including the active user account and all associated customer profiles. # List Customer Profiles Returns all customer profiles linked to the authenticated user account, together with the user record and default business. A single user account can have multiple profiles — for example, an individual member profile and a company profile — and can switch between them. The portal fetches this on every authenticated session bootstrap to populate the account switcher. A **profile** in Nexudus represents a customer record tied to a specific location. One user can have profiles across multiple locations or multiple profile types (individual, company) within the same location. ## Authentication Requires a valid customer bearer token. ## Query Parameters Comma-separated list of field paths to include in the response. When provided, only the specified fields are returned — useful for reducing payload size. Supports nested paths using dot notation. Example: `_shape=Records.FullName,Records.CompanyName,Records.Avatar`. ## Response The authenticated user account record. Unique numeric identifier for the user account. Display name for the user account. Email address used to sign in. `true` when the account is active and not suspended. `true` when the user has operator-level admin access. Current bearer token for the session (mirrors the `Authorization` header value). The default location associated with this user. Numeric identifier of the default location. Display name of the default location. Subdomain identifier for the default location. All customer profiles accessible to this user. Numeric identifier of the customer profile. Use this as `coworkerId` in profile-scoped endpoints. Display name for this profile. Company name for this profile. `true` when this profile is active. `true` when this is the currently active profile for the session. Profile type: `1` = Individual, `2` = Company. `true` when a Virtual Office contract is active for this profile. `true` when the Virtual Office contract is currently paused. ID of the Virtual Office contract, if one exists. Use with `GET /api/public/billing/coworkerContracts/{contractId}`. ## Example Response ```json theme={null} { "User": { "Id": 42, "FullName": "Jane Doe", "Email": "jane.doe@example.com", "Active": true, "IsAdmin": false, "AccessToken": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..." }, "DefaultBusiness": { "Id": 7, "Name": "Nexudus HQ", "WebAddress": "nexudushq" }, "Profiles": [ { "Id": 101, "FullName": "Jane Doe", "CompanyName": "", "Active": true, "IsDefaultProfile": true, "CoworkerType": 1, "HasVirtualOffice": false, "VirtualOfficePaused": null, "VirtualOfficeContractId": null }, { "Id": 102, "FullName": "Acme Design Co.", "CompanyName": "Acme Design Co.", "Active": true, "IsDefaultProfile": false, "CoworkerType": 2, "HasVirtualOffice": true, "VirtualOfficePaused": false, "VirtualOfficeContractId": 55 } ] } ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' import { CoworkerProfiles } from '@/types/sys/CoworkerProfiles' import { useData } from '@/api/fetchData' const { resource: profiles } = useData(httpClient, endpoints.coworkers.profiles) const activeProfile = profiles?.Profiles.find((p) => p.IsDefaultProfile) ``` ## Usage in Portal | Context | Source file | | ------------------------------------------------- | ------------------------------------------- | | Session bootstrap — loads all profiles on sign-in | `src/states/useAuthContext.tsx` | | Account switcher dropdown in navigation | `src/components/NavBar/AccountDropdown.tsx` | ## Error Responses The bearer token is missing, expired, or invalid. ## Related Endpoints | Method | Endpoint | Description | | ------ | ------------------------------------------------- | ----------------------------------------- | | `PUT` | `/api/public/coworkers/profiles/current` | Switch the active profile for the session | | `GET` | `/api/public/coworkers/profiles/current/benefits` | Get plan benefits for the active profile | | `GET` | `/en/profile?_resource=Coworker` | Retrieve full editable customer profile | # Switch Active Profile Source: https://learn.nexudus.com/api/endpoints/coworkers/switch-profile PUT /api/public/coworkers/profiles/current Switch the active customer profile for the current session to a different profile owned by the same user account. # Switch Active Profile Changes the active customer profile for the current session. A single user account can have multiple customer profiles (individual, company, or profiles at different locations). This endpoint sets the specified profile as the default, so subsequent authenticated requests operate in that profile's context. ## Authentication Requires a valid customer bearer token. ## Query Parameters The numeric identifier of the profile to switch to. Obtain valid profile IDs from `GET /api/public/coworkers/profiles` — use a `Profiles[].Id` value where `Profiles[].Active` is `true`. ## Response The portal typically discards the response body and re-fetches `GET /api/public/coworkers/profiles` after a successful switch to update the session state. Returns an `ActionConfirmation` envelope. `true` when the profile was switched successfully. Usually `null` on success. HTTP-style status code mirrored in the body. `200` on success. Human-readable message. Usually `null` on success. Validation errors. `null` on success. ## Example Response ```json theme={null} { "WasSuccessful": true, "Value": null, "Status": 200, "Message": null, "Errors": null } ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' await httpClient.put(endpoints.coworkers.setCurrentProfile(coworkerId)) // Re-fetch profiles to update UI await refetchProfiles() ``` ## Usage in Portal | Context | Source file | | ------------------------------------------- | ---------------------------------------------------------------------------- | | Account switcher in the navigation dropdown | `src/components/NavBar/AccountDropdown.tsx` | | Virtual Office profile mismatch alert | `src/views/virtual-offices/components/VirtualOfficeProfileMismatchAlert.tsx` | ## Error Responses The bearer token is missing, expired, or invalid. No profile with the given `coworkerId` exists or it does not belong to this user account. ## Related Endpoints | Method | Endpoint | Description | | ------ | ------------------------------------------------- | -------------------------------------------------- | | `GET` | `/api/public/coworkers/profiles` | List all profiles available to the current session | | `GET` | `/api/public/coworkers/profiles/current/benefits` | Get benefits for the currently active profile | # Get Delivery Details Source: https://learn.nexudus.com/api/endpoints/deliveries/delivery-details GET /api/public/deliveries/{id} Returns the full details of a specific delivery. # Get Delivery Details Returns the complete details for a specific delivery, including sender, tracking info, and collection status. ## Authentication Requires a valid customer bearer token. ## Path Parameters Numeric identifier of the delivery. ## Query Parameters Comma-separated list of field paths to include in the response. When provided, only the specified fields are returned — useful for reducing payload size. Supports nested paths using dot notation. Example: `_shape=Delivery.Name,Delivery.Collected`. ## Response Returns an object containing a `Delivery` property with all delivery fields. ### Delivery Fields #### Identity | Field | Type | Description | | ---------- | -------- | ------------------------------------------ | | `Id` | `number` | Unique numeric identifier for the delivery | | `UniqueId` | `string` | Globally unique identifier | #### Core | Field | Type | Description | | ------------------- | ---------------- | -------------------------------------------------------- | | `Name` | `string` | Delivery reference number / name | | `Notes` | `string \| null` | Notes added to the delivery | | `Location` | `string` | Physical location where the delivery is stored | | `DeliveryType` | `string` | Type of delivery (`Parcel`, `Letter`, etc.) | | `CoworkerFullName` | `string` | Full name of the customer the delivery is addressed to | | `RecipientId` | `number \| null` | Id of the specific recipient contact, if applicable | | `RecipientFullName` | `string` | Full name of the recipient (falls back to customer name) | | `RequiresSignature` | `boolean` | Whether collection requires a signature | #### Media | Field | Type | Description | | ------------------ | --------- | ------------------------------------------- | | `HasImage` | `boolean` | Whether the delivery has a label image | | `ImageUrl` | `string` | URL to the delivery label image | | `HasSignature` | `boolean` | Whether a collection signature was captured | | `HasScan` | `boolean` | Whether a scanned copy exists | | `HasForwardedFile` | `boolean` | Whether a forwarding receipt file exists | #### Status | Field | Type | Description | | --------------------- | --------- | --------------------------------------- | | `Collected` | `boolean` | Whether the delivery has been collected | | `StoredForCollection` | `boolean` | Whether stored at the location | | `ReturnedToSender` | `boolean` | Whether returned to sender | | `CheckDeposited` | `boolean` | Whether a check was deposited | | `Forwarded` | `boolean` | Whether forwarded to another address | | `Scanned` | `boolean` | Whether scanned and sent digitally | | `Recycled` | `boolean` | Whether recycled | | `Shredded` | `boolean` | Whether shredded | #### Status Dates | Field | Type | Description | | ----------------------- | ---------------- | ----------------------------------- | | `CollectedOn` | `string \| null` | ISO date when collected | | `StoredForCollectionOn` | `string \| null` | ISO date when stored for collection | | `ReturnedToSenderOn` | `string \| null` | ISO date when returned to sender | | `CheckDepositedOn` | `string \| null` | ISO date when check was deposited | | `ForwardedOn` | `string \| null` | ISO date when forwarded | | `ScannedOn` | `string \| null` | ISO date when scanned | | `RecycledOn` | `string \| null` | ISO date when recycled | | `ShreddedOn` | `string \| null` | ISO date when shredded | #### Handling | Field | Type | Description | | ----------------------------- | ---------------- | ------------------------------------------------ | | `HandlingPreference` | `string \| null` | Current handling preference set by the customer | | `HandlingPreferenceCanChange` | `boolean` | Whether the handling preference can still change | | `ForwardingAddressUniqueId` | `string \| null` | UniqueId of the forwarding address | #### Timestamps (from base) | Field | Type | Description | | -------------- | ---------------- | --------------------------------------- | | `CreatedOn` | `string` | Date created (business-local time) | | `UpdatedOn` | `string \| null` | Date last updated (business-local time) | | `CreatedOnUtc` | `string` | Date created (UTC) | | `UpdatedOnUtc` | `string \| null` | Date last updated (UTC) | ## Examples ### Fetch delivery details ```http theme={null} GET /api/public/deliveries/77 Authorization: Bearer {token} ``` ### Fetch with response shaping ```http theme={null} GET /api/public/deliveries/77?_shape=Delivery.Name,Delivery.DeliveryType,Delivery.Collected Authorization: Bearer {token} ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' const response = await httpClient.get(endpoints.deliveries.details(77)) ``` ## Error Responses The bearer token is missing, expired, or invalid. No delivery exists with the given id. ## Related Endpoints | Method | Endpoint | Description | | ------ | --------------------------------------------- | -------------------------- | | `GET` | `/api/public/deliveries/my` | List all deliveries | | `PUT` | `/api/public/deliveries/{id}/markAsCollected` | Mark delivery as collected | # List Deliveries Source: https://learn.nexudus.com/api/endpoints/deliveries/list-deliveries GET /api/public/deliveries/my Returns the authenticated customer's deliveries. # List Deliveries Returns deliveries addressed to the authenticated customer. Filter by pending status to show only uncollected parcels. ## Authentication Requires a valid customer bearer token. ## Query Parameters Page number for pagination. **Default**: `1`. Number of results per page. **Default**: `15`. `true` — return only uncollected deliveries. `false` — return collected/handled deliveries. Free-text search string matched against the delivery name. Filter by delivery type enum value (e.g. `Parcel`, `Letter`, `LargeParcel`). Comma-separated list of field paths to include in the response. When provided, only the specified fields are returned — useful for reducing payload size. Supports nested paths using dot notation. Example: `_shape=Records.Name,Records.Collected,TotalItems`. ## Response Returns a `DeliveryList` object — a paginated wrapper containing an array of delivery records. ### Pagination Array of delivery objects for the current page. Current page number (1-based). Total number of matching deliveries. Total number of pages. Whether there are more pages after the current one. Whether there are pages before the current one. ### Delivery Fields (within `Records[]`) #### Identity | Field | Type | Description | | ---------- | -------- | ------------------------------------------ | | `Id` | `number` | Unique numeric identifier for the delivery | | `UniqueId` | `string` | Globally unique identifier | #### Core | Field | Type | Description | | ------------------- | ---------------- | -------------------------------------------------------- | | `Name` | `string` | Delivery reference number / name | | `Notes` | `string \| null` | Notes added to the delivery | | `Location` | `string` | Physical location where the delivery is stored | | `DeliveryType` | `string` | Type of delivery (`Parcel`, `Letter`, etc.) | | `CoworkerFullName` | `string` | Full name of the customer the delivery is addressed to | | `RecipientId` | `number \| null` | Id of the specific recipient contact, if applicable | | `RecipientFullName` | `string` | Full name of the recipient (falls back to customer name) | | `RequiresSignature` | `boolean` | Whether collection requires a signature | #### Media | Field | Type | Description | | ------------------ | --------- | ------------------------------------------- | | `HasImage` | `boolean` | Whether the delivery has a label image | | `ImageUrl` | `string` | URL to the delivery label image | | `HasSignature` | `boolean` | Whether a collection signature was captured | | `HasScan` | `boolean` | Whether a scanned copy exists | | `HasForwardedFile` | `boolean` | Whether a forwarding receipt file exists | #### Status | Field | Type | Description | | --------------------- | --------- | --------------------------------------- | | `Collected` | `boolean` | Whether the delivery has been collected | | `StoredForCollection` | `boolean` | Whether stored at the location | | `ReturnedToSender` | `boolean` | Whether returned to sender | | `CheckDeposited` | `boolean` | Whether a check was deposited | | `Forwarded` | `boolean` | Whether forwarded to another address | | `Scanned` | `boolean` | Whether scanned and sent digitally | | `Recycled` | `boolean` | Whether recycled | | `Shredded` | `boolean` | Whether shredded | #### Status Dates | Field | Type | Description | | ----------------------- | ---------------- | ----------------------------------- | | `CollectedOn` | `string \| null` | ISO date when collected | | `StoredForCollectionOn` | `string \| null` | ISO date when stored for collection | | `ReturnedToSenderOn` | `string \| null` | ISO date when returned to sender | | `CheckDepositedOn` | `string \| null` | ISO date when check was deposited | | `ForwardedOn` | `string \| null` | ISO date when forwarded | | `ScannedOn` | `string \| null` | ISO date when scanned | | `RecycledOn` | `string \| null` | ISO date when recycled | | `ShreddedOn` | `string \| null` | ISO date when shredded | #### Handling | Field | Type | Description | | ----------------------------- | ---------------- | ------------------------------------------------ | | `HandlingPreference` | `string \| null` | Current handling preference set by the customer | | `HandlingPreferenceCanChange` | `boolean` | Whether the handling preference can still change | | `ForwardingAddressUniqueId` | `string \| null` | UniqueId of the forwarding address | #### Timestamps (from base) | Field | Type | Description | | -------------- | ---------------- | --------------------------------------- | | `CreatedOn` | `string` | Date created (business-local time) | | `UpdatedOn` | `string \| null` | Date last updated (business-local time) | | `CreatedOnUtc` | `string` | Date created (UTC) | | `UpdatedOnUtc` | `string \| null` | Date last updated (UTC) | ## Examples ### Fetch pending deliveries ```http theme={null} GET /api/public/deliveries/my?showPending=true Authorization: Bearer {token} ``` ### Fetch with response shaping ```http theme={null} GET /api/public/deliveries/my?showPending=true&_shape=Records.Name,Records.DeliveryType,Records.Collected,Records.CollectedOn,TotalItems Authorization: Bearer {token} ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' const { resource: deliveries } = useTypedData(httpClient, endpoints.deliveries.list(true)) ``` ## Error Responses The bearer token is missing, expired, or invalid. ## Related Endpoints | Method | Endpoint | Description | | ------ | --------------------------------------------- | ------------------------------------ | | `GET` | `/api/public/deliveries/{id}` | Get a single delivery's full details | | `PUT` | `/api/public/deliveries/{id}/markAsCollected` | Mark a delivery as collected | # Mark Delivery as Collected Source: https://learn.nexudus.com/api/endpoints/deliveries/mark-collected PUT /api/public/deliveries/{id}/markAsCollected Marks a delivery as collected by the customer. # Mark Delivery as Collected Records that the customer has collected a specific delivery. Removes it from the pending deliveries list. ## Authentication Requires a valid customer bearer token. ## Path Parameters Numeric identifier of the delivery. ## Request Body No request body required. ## Response Returns a `200 OK` on success. ## Examples ### Mark as collected ```http theme={null} PUT /api/public/deliveries/77/markAsCollected Authorization: Bearer {token} ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' await httpClient.put(endpoints.deliveries.markAsCollected(77)) ``` # Save Delivery Source: https://learn.nexudus.com/api/endpoints/deliveries/save-delivery PUT /api/public/deliveries Creates or updates a delivery record. # Save Delivery Creates a new delivery record or updates an existing one. Used when the space operator logs incoming parcels. ## Authentication Requires a valid customer bearer token. ## Request Body Delivery details including sender and tracking information. ## Response Returns a `200 OK` on success. ## Examples ### Save a delivery ```http theme={null} PUT /api/public/deliveries Authorization: Bearer {token} Content-Type: application/json { "SenderName": "Amazon", "TrackingNumber": "TRK123456" } ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' await httpClient.put(endpoints.deliveries.save, deliveryData) ``` # Cancel Event Ticket Source: https://learn.nexudus.com/api/endpoints/events/cancel-ticket DELETE /api/public/events/my/{id} Cancels (deletes) an event ticket belonging to the authenticated customer. # Cancel Event Ticket Cancels and removes the specified ticket from the authenticated customer's event attendances. Used on the My Events page to allow customers to cancel their registration before an event. ## Authentication Requires a valid customer bearer token. The attendance record must belong to the authenticated customer. ## Path Parameters The integer ID of the attendance record to cancel. Obtained as `Records[].Id` from `GET /api/public/events/my`. ## Response Returns an empty `200 OK` on success. ## Examples ### Cancel a ticket ```http theme={null} DELETE /api/public/events/my/9021 Authorization: Bearer {token} ``` ``` HTTP/1.1 200 OK ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' await httpClient.delete(endpoints.events.cancelTicket(9021)) ``` ## Usage in Portal | Context | Source file | | ----------------------------------- | ---------------------------------------------------- | | My Events page (`/activity/events`) | `src/views/user/activity/events/MyEventsSection.tsx` | ## Error Responses The customer is not authenticated or the session has expired. No attendance record with the specified ID exists for the authenticated customer. ## Related Endpoints | Method | Endpoint | Description | | ------ | --------------------------------------- | ----------------------------------------------- | | `GET` | `/api/public/events/my` | List all tickets for the authenticated customer | | `POST` | `/api/public/events/my/{id}/sendTicket` | Re-send a ticket confirmation email | | `GET` | `/api/public/events/{id}` | Full detail for a specific event | # Delete Event Comment Source: https://learn.nexudus.com/api/endpoints/events/delete-comment POST /en/events/deleteComment Deletes a comment previously posted by the authenticated customer on an event. # Delete Event Comment Removes a comment that the authenticated customer posted on an event. After a successful deletion the event detail data should be refetched to update the `Event.Comments` array. This endpoint uses the `/en/` legacy route prefix and the `POST` method rather than `DELETE`, despite being a deletion operation. ## Authentication Requires a valid customer bearer token. Customers can only delete their own comments. ## Request Body The integer ID of the comment to delete. Obtained as `Event.Comments[].Id` from `GET /api/public/events/{id}`. ## Response Returns an empty `200 OK` on success. ## Examples ### Delete a comment ```http theme={null} POST /en/events/deleteComment Authorization: Bearer {token} Content-Type: application/json { "id": 77 } ``` ``` HTTP/1.1 200 OK ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' await httpClient.post(endpoints.events.deleteComment, { id: 77 }) ``` ## Usage in Portal | Context | Source file | | ----------------------------------------------- | ---------------------------------- | | Event detail page comment list (`/events/{id}`) | `src/views/events/details/data.ts` | ## Error Responses The customer is not authenticated or the session has expired. No comment with the specified `id` exists or it does not belong to the authenticated customer. ## Related Endpoints | Method | Endpoint | Description | | ------ | ------------------------- | ---------------------------------------------- | | `GET` | `/api/public/events/{id}` | Event detail — includes `Event.Comments` array | | `POST` | `/en/events/newComment` | Post a new comment on an event | # Get Event Details Source: https://learn.nexudus.com/api/endpoints/events/event-details GET /api/public/events/{id} Returns full detail for a single published event, including ticket products, attendees, related events, and comments. # Get Event Details Returns complete information for a single published event, including all ticket products, a list of recent attendees, related events, and customer comments. Used on the event detail page and in the basket preview. ## Authentication No authentication required. ## Path Parameters The integer ID of the event. Obtained as `Id` from `GET /api/public/events` or `GET /api/public/events/my`. ## Query Parameters Comma-separated list of field paths to include in the response. When provided, only the specified fields are returned — useful for reducing payload size. Supports nested paths using dot notation. Example: `_shape=Event.Name,Event.StartDateUtc,Event.EventProducts,RelatedEvents`. ## Response Returns an `EventDetails` object. ### Core Fields Full event object. See the field descriptions in [List Events](/api/endpoints/events/list-events) for the complete `CalendarEvent` schema. Total number of tickets sold across all ticket products. Full `Coworker` objects for event attendees — used for social proof displays ("X people are going"). All event categories available at this location — useful for populating a "Browse by category" navigation without an additional request. A list of other events from the same location or category, used for the "You might also like" section. Template object for a new comment submission. Use the `newComment` endpoint to post a comment. ### EventComment Fields Unique identifier for the comment. Comment body text. Optional numeric rating (e.g. 1–5) submitted alongside the comment. When `true`, the comment is visible to all customers. The customer who posted the comment, including `Id` and `FullName`. Local datetime the comment was posted (ISO 8601). UTC datetime the comment was posted (ISO 8601). ## Examples ### Fetch event details (full payload) ```http theme={null} GET /api/public/events/412 ``` ```json theme={null} { "AttendeeCount": 7, "Attendees": [{ "Id": 201, "FullName": "Maria Garcia", "Email": "maria@example.com" }], "Categories": [ { "Id": 3, "Title": "Workshops", "UniqueId": "a1b2c3d4-...", "IdString": "3", "IsNull": false, "CreatedOn": "2024-01-10T10:00:00", "UpdatedOn": "2024-01-10T10:00:00", "CreatedOnUtc": "2024-01-10T10:00:00Z", "UpdatedOnUtc": "2024-01-10T10:00:00Z" } ], "RelatedEvents": [ { "Id": 415, "Name": "Afternoon Pilates", "ShortDescription": "A refreshing end-of-day stretch session.", "StartDateUtc": "2026-03-24T17:00:00Z", "EndDateUtc": "2026-03-24T18:00:00Z", "Business": { "Id": 5, "Name": "Downtown Coworking Hub" }, "EventCategories": [{ "Id": 3, "Title": "Workshops" }] } ], "Comment": null, "Event": { "Id": 412, "Name": "Morning Yoga & Mindfulness", "ShortDescription": "Start your week with a guided yoga session open to all levels.", "LongDescription": "

Join us every Monday for a 45-minute yoga session led by certified instructor Sarah Chen...

", "HostFullName": "Sarah Chen", "Location": "Studio Room B", "VenueAddress": null, "StartDate": "2026-03-23T07:30:00", "EndDate": "2026-03-23T08:15:00", "StartDateUtc": "2026-03-23T07:30:00Z", "EndDateUtc": "2026-03-23T08:15:00Z", "MultipleDays": false, "HasTickets": true, "SoldOut": false, "ChepeastPrice": 0, "MostExpensivePrice": 12.0, "Allocation": 20, "Sales": 7, "EnableWaitList": false, "AllowComments": true, "HasLargeImage": true, "HasSmallImage": true, "HasAddress": true, "HasResource": false, "Resource": null, "EventProducts": [ { "Id": 88, "Name": "Free Entry", "Description": "Community member free pass", "Price": 0, "PriceCurrencyCode": "GBP", "PriceFormatted": "£0.00", "TicketsLeft": 13, "SoldOut": false, "IsAvailableNow": true, "MaxTicketsPerAttendee": null, "LastFew": false, "Future": false, "Expired": false, "DisplayOrder": 1, "StartDate": "2026-01-01T00:00:00", "EndDate": "2026-03-23T08:15:00", "Quantity": 1 } ], "EventCategories": [{ "Id": 3, "Title": "Workshops" }], "Business": { "Id": 5, "Name": "Downtown Coworking Hub", "WebAddress": "https://downtown.example.com" }, "Comments": [ { "Id": 77, "Text": "Fantastic session, highly recommend!", "Rating": 5, "Published": true, "PostedBy": { "Id": 201, "FullName": "Maria Garcia" }, "CreatedOn": "2026-02-10T09:15:00", "CreatedOnUtc": "2026-02-10T09:15:00Z" } ], "UniqueId": "b2c3d4e5-f6a7-8901-bcde-f12345678901", "IdString": "412", "CreatedOn": "2025-11-01T09:00:00", "UpdatedOn": "2026-03-01T12:00:00", "CreatedOnUtc": "2025-11-01T09:00:00Z", "UpdatedOnUtc": "2026-03-01T12:00:00Z", "IsNull": false } } ``` ### Fetch event with a minimal field set ```http theme={null} GET /api/public/events/412?_shape=Event.Id,Event.Name,Event.StartDateUtc,Event.EventProducts.Id,Event.EventProducts.Price,Event.EventProducts.TicketsLeft,RelatedEvents.Id,RelatedEvents.Name ``` ```json theme={null} { "Event": { "Id": 412, "Name": "Morning Yoga & Mindfulness", "StartDateUtc": "2026-03-23T07:30:00Z", "EventProducts": [{ "Id": 88, "Price": 0, "TicketsLeft": 13 }] }, "RelatedEvents": [{ "Id": 415, "Name": "Afternoon Pilates" }] } ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' import { EventDetails } from '@/types/endpoints/EventDetails' import { createShape } from '@/helpers/shape-helper' import { useData } from '@/api/fetchData' const endpoint = endpoints.events.details(412) const shape = createShape()([ 'Event.Id', 'Event.Name', 'Event.StartDateUtc', 'Event.EndDateUtc', 'Event.ShortDescription', 'Event.LongDescription', 'Event.HasLargeImage', 'Event.EnableWaitList', 'Event.HasTickets', 'Event.AllowComments', 'Event.EventProducts.Id', 'Event.EventProducts.Name', 'Event.EventProducts.Price', 'Event.EventProducts.TicketsLeft', 'Event.EventProducts.IsAvailableNow', 'RelatedEvents.Id', 'RelatedEvents.Name', 'RelatedEvents.StartDateUtc', 'Event.Comments.Id', 'Event.Comments.Text', 'Event.Comments.PostedBy.FullName', 'Event.Comments.CreatedOnUtc', 'Event.Comments.Rating', ]) const { resource: event } = useData(httpClient, endpoint.url, { shape: shape.fields, }) ``` ## Usage in Portal | Context | Source file | | -------------------------------------------- | --------------------------------------------------------- | | Event detail page (`/events/{id}`) | `src/views/events/details/data.ts` | | Basket item preview (event ticket in basket) | `src/components/Basket/items/EventBasketItemRow.tsx` | | Event checkout page (`/checkout/event`) | `src/views/public/checkout/event/useEventCheckoutData.ts` | ## Error Responses No published event exists with the specified ID. ## Related Endpoints | Method | Endpoint | Description | | ------ | -------------------------------------------------- | ------------------------------------------------- | | `GET` | `/api/public/events` | Paginated list of published events | | `GET` | `/api/public/events/{eventId}/product/{productId}` | Detail for a specific ticket product | | `POST` | `/api/public/events/{id}/joinWaitingList` | Join the waiting list for a sold-out event | | `GET` | `/api/public/events/my` | Events the authenticated customer has tickets for | | `POST` | `/en/events/newComment` | Post a comment on an event | # Get Event Product Source: https://learn.nexudus.com/api/endpoints/events/event-product GET /api/public/events/{eventId}/product/{productId} Returns detail for a specific ticket product belonging to a published event. # Get Event Product Returns the full detail for a single ticket product associated with a published event. Used during the event checkout flow to confirm product availability and price before purchase. ## Authentication No authentication required. ## Path Parameters The integer ID of the event. Obtained as `Id` from `GET /api/public/events` or `GET /api/public/events/{id}`. The integer ID of the ticket product. Obtained as `EventProducts[].Id` from `GET /api/public/events/{id}`. ## Query Parameters Comma-separated list of field paths to include in the response. When provided, only the specified fields are returned — useful for reducing payload size. Supports nested paths using dot notation. ## Response Returns an `EventProduct` object. ### Core Fields Unique identifier for the ticket product. Display name of the ticket type (e.g. "General Admission", "VIP Pass"). Optional description shown to customers during checkout. Ticket price. `0` for free tickets. ISO 4217 currency code (e.g. `"GBP"`, `"USD"`, `"EUR"`). Localised price string including currency symbol (e.g. `"£12.00"`). Use this for display rather than formatting `Price` manually. Full currency object from the business configuration. ### Availability When `true`, the ticket is within its sale window and has stock remaining. When `true`, all available spots for this ticket type have been claimed. Remaining ticket count. `0` when sold out. When `true`, fewer than a threshold number of tickets remain — used to display urgency messaging. Maximum number of tickets a single customer can purchase. `null` means no limit. Total initial allocation for this ticket type. ### Sale Window Local datetime from which this ticket type goes on sale (ISO 8601). Local datetime after which this ticket type is no longer available (ISO 8601). Human-readable formatted start date. Human-readable formatted end date. When `true`, the sale window has passed and tickets can no longer be purchased. When `true`, the sale window has not yet opened. Operator-defined ordering position for display in ticket lists. ### Timestamps All datetime fields are ISO 8601 strings. `*On` fields are in the location's local timezone; `*OnUtc` fields are UTC. Local datetime the ticket product was created. UTC datetime the ticket product was created. Local datetime of the last update. UTC datetime of the last update. ## Examples ### Fetch a ticket product ```http theme={null} GET /api/public/events/412/product/88 ``` ```json theme={null} { "Id": 88, "Name": "General Admission", "Description": "Standard entry ticket. Includes refreshments.", "Price": 15.0, "PriceCurrencyCode": "GBP", "PriceFormatted": "£15.00", "Currency": { "Code": "GBP", "Symbol": "£" }, "IsAvailableNow": true, "SoldOut": false, "TicketsLeft": 13, "LastFew": false, "MaxTicketsPerAttendee": 2, "Quantity": 20, "StartDate": "2026-01-01T00:00:00", "EndDate": "2026-03-23T08:15:00", "StartDateFormatted": "1 Jan 2026", "EndDateFormatted": "23 Mar 2026", "Expired": false, "Future": false, "DisplayOrder": 1, "UniqueId": "d4e5f6a7-b8c9-0123-def0-234567890123", "IdString": "88", "CreatedOn": "2025-11-01T09:00:00", "UpdatedOn": "2026-03-01T12:00:00", "CreatedOnUtc": "2025-11-01T09:00:00Z", "UpdatedOnUtc": "2026-03-01T12:00:00Z", "IsNull": false } ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' import { EventProduct } from '@/types/endpoints/EventList' import { useData } from '@/api/fetchData' const endpoint = endpoints.events.product(412, 88) const { resource: product } = useData(httpClient, endpoint.url) ``` ## Error Responses No event with `eventId` or no ticket product with `productId` exists, or the product does not belong to the specified event. ## Related Endpoints | Method | Endpoint | Description | | ------ | ----------------------------------------- | ----------------------------------------------- | | `GET` | `/api/public/events/{id}` | Full event detail including all ticket products | | `GET` | `/api/public/events` | Paginated list of published events | | `POST` | `/api/public/events/{id}/joinWaitingList` | Join the waiting list for a sold-out event | # Get Events Calendar Source: https://learn.nexudus.com/api/endpoints/events/events-calendar GET /en/bookings/fullCalendarEvents Returns events within a date range in FullCalendar-compatible format for display in booking and events calendars. # Get Events Calendar Returns published events within a given date range formatted for the [FullCalendar](https://fullcalendar.io/) library. Used alongside booking slots in the portal's calendar view to give customers a unified view of space bookings and events. This endpoint uses the `/en/` legacy route prefix rather than `/api/public/`. It does not support `_shape` field shaping. ## Authentication No authentication required. ## Query Parameters ISO 8601 UTC datetime for the start of the range. **Example**: `2026-03-01T00:00:00.000Z` ISO 8601 UTC datetime for the end of the range. **Example**: `2026-03-31T23:59:59.999Z` ## Response Returns an `EventsCalendar` array — a flat list of `EventsCalendarEvent` objects, one per event that falls within the requested range. ### EventsCalendarEvent Fields Unique event identifier (stringified integer) compatible with FullCalendar's `id` field. Event display name shown on the calendar. Event start datetime (ISO 8601). Event end datetime (ISO 8601). When `true`, the event is displayed as an all-day block in the calendar. Brief summary displayed in the calendar event tooltip or popover. Name of the coworking location that published the event. Venue name or room identifier. Full postal address of the event venue. External ticket purchase URL if the operator has set a custom tickets page. External event URL (e.g. a Zoom or Eventbrite link). Portal-relative URL to the event detail page. Use this to navigate on calendar item click. Always `true` — distinguishes event entries from booking entries when both are rendered in the same FullCalendar instance. Always `false` for event entries — events cannot be dragged or resized in the calendar. When `true`, FullCalendar should treat the `start`/`end` values as local times rather than converting from UTC. ID of the linked bookable resource, if the event is associated with a specific room or desk. Display name of the linked resource. ## Examples ### Fetch calendar events for March 2026 ```http theme={null} GET /en/bookings/fullCalendarEvents?start=2026-03-01T00:00:00.000Z&end=2026-03-31T23:59:59.999Z ``` ```json theme={null} [ { "id": "412", "resourceId": "", "resourceName": "", "title": "Morning Yoga & Mindfulness", "shortDescription": "Start your week with a guided yoga session open to all levels.", "businessName": "Downtown Coworking Hub", "location": "Studio Room B", "venueAddress": null, "ticketsPage": null, "webAddress": null, "start": "2026-03-23T07:30:00", "end": "2026-03-23T08:15:00", "allDay": false, "editable": false, "ignoreTimezone": false, "event": true, "url": "/events/412" }, { "id": "420", "resourceId": "15", "resourceName": "Main Conference Room", "title": "Startup Pitch Night", "shortDescription": "Watch 8 local startups pitch to a panel of investors.", "businessName": "Downtown Coworking Hub", "location": "Main Conference Room", "venueAddress": null, "ticketsPage": null, "webAddress": null, "start": "2026-03-28T18:00:00", "end": "2026-03-28T21:00:00", "allDay": false, "editable": false, "ignoreTimezone": false, "event": true, "url": "/events/420" } ] ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' import { EventsCalendar } from '@/types/endpoints/EventsCalendar' import { useData } from '@/api/fetchData' import { DateTime } from 'luxon' const start = DateTime.now().startOf('month') const end = DateTime.now().endOf('month') const endpoint = endpoints.events.calendar(start, end) const { resource: calendarEvents } = useData(httpClient, endpoint.url) ``` ## Usage in Portal | Context | Source file | | ------------------------------------------------- | ----------------------------------------------------- | | Bookings search / resource calendar (`/bookings`) | `src/views/public/bookings/useBookingsSearchData.tsx` | ## Error Responses `start` or `end` is missing or not a valid ISO 8601 datetime string. ## Related Endpoints | Method | Endpoint | Description | | ------ | ----------------------------------- | ----------------------------------------------- | | `GET` | `/api/public/events` | Paginated events list with full event metadata | | `GET` | `/api/public/events/{id}` | Full detail for a specific event | | `GET` | `/en/bookings/fullCalendarBookings` | Bookings in FullCalendar format (same calendar) | # Join Event Waiting List Source: https://learn.nexudus.com/api/endpoints/events/join-waiting-list POST /api/public/events/{id}/joinWaitingList Adds the authenticated customer to the waiting list for a sold-out event. # Join Event Waiting List Registers the authenticated customer on the waiting list for an event that has no available tickets. When a spot becomes available, the operator can notify waiting-list members. Only callable when `CalendarEvent.EnableWaitList` is `true` and the event is sold out. ## Authentication Requires a valid customer bearer token. ## Path Parameters The integer ID of the event. Obtained as `Id` from `GET /api/public/events` or `GET /api/public/events/{id}`. ## Request Body The request body accepts the customer's waiting-list registration data. The exact fields depend on the event configuration; pass an empty object `{}` if no additional fields are required. Full name of the customer registering for the waiting list. Email address to notify when a spot becomes available. ## Response Returns an empty `200 OK` on success. ## Examples ### Join the waiting list ```http theme={null} POST /api/public/events/412/joinWaitingList Authorization: Bearer {token} Content-Type: application/json { "FullName": "Alex Johnson", "Email": "alex@example.com" } ``` ``` HTTP/1.1 200 OK ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' await httpClient.post(endpoints.events.joinWaitingList(412), { FullName: 'Alex Johnson', Email: 'alex@example.com', }) ``` ## Usage in Portal | Context | Source file | | ------------------------------------------------------ | -------------------------------------------------------------- | | Event detail page — waiting list form (`/events/{id}`) | `src/views/events/details/data.ts` | | Waiting list form component | `src/views/events/details/components/EventWaitingListForm.tsx` | ## Error Responses The customer is not authenticated or the session has expired. No event with the specified ID exists. The event does not have waiting list enabled (`EnableWaitList` is `false`), or the customer is already on the waiting list. ## Related Endpoints | Method | Endpoint | Description | | ------ | -------------------------------------------------- | ------------------------------------------------- | | `GET` | `/api/public/events/{id}` | Full event detail including `EnableWaitList` flag | | `GET` | `/api/public/events` | Paginated list of published events | | `GET` | `/api/public/events/my` | Tickets held by the authenticated customer | | `GET` | `/api/public/events/{eventId}/product/{productId}` | Ticket product availability detail | # List Events Source: https://learn.nexudus.com/api/endpoints/events/list-events GET /api/public/events Returns a paginated list of published events, with optional filtering by category, keyword, date range, and featured status. # List Events Returns a paginated list of published calendar events for the current location. Supports filtering by past/upcoming, category, keyword search, and featured flag. Used to power the public-facing events catalogue and homepage event grids. An **event** is a scheduled activity (workshop, networking session, etc.) published by the space operator. Events may have one or more **ticket products** with their own prices and availability windows. ## Authentication No authentication required. The response is scoped to the current business location. ## Query Parameters `true` — return events whose end date is in the past. `false` — return upcoming and active events. 1-based page number. **Default**: `1` Number of events per page. **Default**: `25` Filter to events belonging to a specific category. Omit to return events across all categories. Keyword filter applied to event name and description. URL-encoded. When `true`, returns only events marked as featured by the operator. When `true`, returns only events that the operator has flagged to appear on the home page. Used by the `upcomingEvents` shortcut endpoint. Comma-separated dot-notated field paths to include in the response. When provided, only the specified fields are returned — useful for reducing payload size. **Example**: `_shape=CalendarEvents.Records.Id,CalendarEvents.Records.Name` ## Response Returns an `EventList` object containing pagination metadata and the paginated event records. ### Core Fields Mirrors the `pastEvents` query parameter, confirming which slice of events was returned. All available event categories for the current location — useful for building a category filter UI without a separate request. The currently active category filter, if `categoryId` was supplied. Paginated wrapper containing the matching events. See [API Overview](/api/overview) for pagination fields (`CurrentPage`, `TotalItems`, etc.). ### CalendarEvent Fields Unique integer identifier for the event. Use this as `{id}` in detail, product, and waiting-list endpoints. UUID for the event — stable across edits and suitable as a cache key. Display name of the event. Brief summary shown in list cards. Full event description. May contain HTML. Full name of the event host. Venue name or room identifier. Full postal address of the event venue. External event URL (e.g., a Zoom or Eventbrite link). Facebook event page URL. ### Dates Event start datetime in the location's local timezone (ISO 8601). Event end datetime in the location's local timezone (ISO 8601). Event start datetime in UTC (ISO 8601). Event end datetime in UTC (ISO 8601). When `true`, the event spans more than one calendar day. Local datetime from which the event becomes visible to customers. UTC equivalent of `PublishDate`. ### Tickets & Pricing When `true`, the event has at least one purchasable ticket product. When `true`, all ticket products are sold out or past their sale window. Lowest ticket price across all ticket products. Note the typo in the field name (`Chepeast`) — it is preserved as-is in the API. Highest ticket price across all ticket products. Full `EventProduct` object for the cheapest ticket option. Full `EventProduct` object for the most expensive ticket option. All ticket products for this event. External URL for purchasing tickets when `HasCustomTicketsPage` is `true`. When `true`, ticket purchase is handled on an external page (`TicketsPage`) rather than the portal checkout. Total number of available spots. `null` means unlimited. Number of tickets sold so far. When `true`, customers can join a waiting list when the event is sold out. Additional notes displayed to customers during ticket purchase. When `true`, the checkout form collects the buyer's postal address. ### Categorisation & Display Categories this event belongs to. When `true`, the event appears on the portal home page. When `true`, the event is promoted in the home page banner carousel. When `true`, authenticated customers can post and view comments on the event detail page. ### Media & Resource When `true`, a small thumbnail image is available. When `true`, a full-size banner image is available. Convenience flag — `true` when either `Location` or `VenueAddress` is set. The bookable resource associated with this event, if the event is tied to a room or desk. When `true`, a resource is linked to this event (`Resource` is non-null). The coworking location that published the event. Lightweight list of up to 10 recent attendees, used for social proof display. Published comments on the event. ### Timestamps All datetime fields are ISO 8601 strings. `*On` fields are in the location's local timezone; `*OnUtc` fields are UTC. Local datetime the event record was created. UTC datetime the event record was created. Local datetime of the last update. UTC datetime of the last update. ## Examples ### Fetch upcoming events (full payload) ```http theme={null} GET /api/public/events?pastEvents=false&page=1&top=9 ``` ```json theme={null} { "PastEvents": false, "Categories": [ { "Id": 3, "Title": "Workshops", "UniqueId": "a1b2c3d4-...", "CreatedOn": "2024-01-10T10:00:00", "UpdatedOn": "2024-01-10T10:00:00", "CreatedOnUtc": "2024-01-10T10:00:00Z", "UpdatedOnUtc": "2024-01-10T10:00:00Z", "IdString": "3", "IsNull": false } ], "Category": null, "CalendarEvents": { "Records": [ { "Id": 412, "Name": "Morning Yoga & Mindfulness", "ShortDescription": "Start your week with a guided yoga session open to all levels.", "LongDescription": "

Join us every Monday for a 45-minute yoga session...

", "HostFullName": "Sarah Chen", "Location": "Studio Room B", "VenueAddress": null, "StartDate": "2026-03-23T07:30:00", "EndDate": "2026-03-23T08:15:00", "StartDateUtc": "2026-03-23T07:30:00Z", "EndDateUtc": "2026-03-23T08:15:00Z", "MultipleDays": false, "HasTickets": true, "SoldOut": false, "ChepeastPrice": 0, "MostExpensivePrice": 12.0, "HasCustomTicketsPage": false, "TicketsPage": null, "Allocation": 20, "Sales": 7, "EnableWaitList": false, "AllowComments": true, "ShowInHomePage": true, "ShowInHomeBanner": false, "HasSmallImage": true, "HasLargeImage": true, "HasAddress": true, "HasResource": false, "Resource": null, "EventCategories": [{ "Id": 3, "Title": "Workshops" }], "EventProducts": [{ "Id": 88, "Name": "Free Entry", "Price": 0, "TicketsLeft": 13, "SoldOut": false, "IsAvailableNow": true }], "Business": { "Id": 5, "Name": "Downtown Coworking Hub" }, "Comments": [], "UniqueId": "b2c3d4e5-f6a7-8901-bcde-f12345678901", "IdString": "412", "CreatedOn": "2025-11-01T09:00:00", "UpdatedOn": "2026-03-01T12:00:00", "CreatedOnUtc": "2025-11-01T09:00:00Z", "UpdatedOnUtc": "2026-03-01T12:00:00Z", "IsNull": false } ], "CurrentPage": 1, "CurrentPageSize": 9, "TotalItems": 1, "TotalPages": 1, "HasNextPage": false, "HasPreviousPage": false } } ``` ### Fetch events with a minimal field set Use `_shape` to return only the data your UI needs, reducing payload size. ```http theme={null} GET /api/public/events?pastEvents=false&page=1&top=9&_shape=CalendarEvents.Records.Id,CalendarEvents.Records.Name,CalendarEvents.Records.StartDateUtc,CalendarEvents.Records.HasLargeImage ``` ```json theme={null} { "CalendarEvents": { "Records": [{ "Id": 412, "Name": "Morning Yoga & Mindfulness", "StartDateUtc": "2026-03-23T07:30:00Z", "HasLargeImage": true }], "CurrentPage": 1, "CurrentPageSize": 9, "TotalItems": 1, "TotalPages": 1, "HasNextPage": false, "HasPreviousPage": false } } ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' import { EventList } from '@/types/endpoints/EventList' import { useData } from '@/api/fetchData' const endpoint = endpoints.events.events({ pastEvents: false, page: 1, top: 9, categoryId: undefined, search: undefined, featured: false, }) const { resource: eventList } = useData(httpClient, endpoint.url, { shape: { fields: [ 'CalendarEvents.Records.Id', 'CalendarEvents.Records.Name', 'CalendarEvents.Records.StartDateUtc', 'CalendarEvents.Records.HasLargeImage', 'CalendarEvents.Records.ChepeastPrice', 'CalendarEvents.Records.SoldOut', ], }, }) ``` ## Usage in Portal | Context | Source file | | --------------------------------------- | ---------------------------------------------------------------- | | Events catalogue (`/events`) | `src/views/events/list/useEventsData.ts` | | Homepage events grid (public home page) | `src/views/public/home-business/components/SimpleEventsGrid.tsx` | ## Error Responses A query parameter value is invalid — for example, a non-boolean `pastEvents` or a negative `page`. ## Related Endpoints | Method | Endpoint | Description | | ------ | -------------------------------------------------- | ------------------------------------------------- | | `GET` | `/api/public/events/{id}` | Full detail for a single event | | `GET` | `/api/public/events?onlyHomePage=true` | Upcoming home-page events (no auth required) | | `GET` | `/api/public/events/my` | Events the authenticated customer has tickets for | | `GET` | `/api/public/events/{eventId}/product/{productId}` | Ticket product detail | | `POST` | `/api/public/events/{id}/joinWaitingList` | Join the waiting list for a sold-out event | # List My Events Source: https://learn.nexudus.com/api/endpoints/events/my-events GET /api/public/events/my Returns a paginated list of event tickets belonging to the authenticated customer, optionally filtered to upcoming events. # List My Events Returns a paginated list of event attendances (tickets) for the authenticated customer. Pass `showUpcoming=true` to restrict the list to events that have not yet started — used to power the "Upcoming Events" widget on the personal dashboard and the tickets counter. ## Authentication Requires a valid customer bearer token. ## Query Parameters `true` — return only tickets for events whose end date is in the future. `false` — return all tickets regardless of event date. Comma-separated dot-notated field paths to include in the response. When provided, only the specified fields are returned — useful for reducing payload size. **Example**: `_shape=Records.Id,Records.CalendarEvent.Name` 1-based page number. **Default**: `1` Records per page. **Default**: `25` · **Maximum**: `100` Field to sort by. **Default**: `CreatedOn` `asc` or `desc`. **Default**: `desc` ## Response Returns a `MyEvents` object which extends `ApiListResult`. See [API Overview](/api/overview) for pagination fields. The `Records` array contains attendee (ticket) objects. ### Core Fields Unique identifier for the ticket/attendance record. Use this as `{id}` in the `sendTicket` and `cancelTicket` endpoints. Unique code printed on the ticket — used for check-in at the event. Full name of the ticket holder. Email address of the ticket holder. ### Event & Product The event this ticket belongs to. See [List Events](/api/endpoints/events/list-events) for the full `CalendarEvent` schema. The ticket product that was purchased. Contains price, name, and availability details. Denormalised name of the ticket product — available without expanding `EventProduct`. Denormalised price of the ticket product in the location's currency. ### Attendee The `Coworker` object for the ticket holder, including profile and contact information. The coworking location where the event takes place. ### Timestamps All datetime fields are ISO 8601 strings. `*On` fields are in the location's local timezone; `*OnUtc` fields are UTC. Local datetime the ticket was issued. UTC datetime the ticket was issued. Local datetime of the last update. UTC datetime of the last update. ## Examples ### Fetch upcoming tickets (full payload) ```http theme={null} GET /api/public/events/my?showUpcoming=true Authorization: Bearer {token} ``` ```json theme={null} { "Records": [ { "Id": 9021, "AttendeeCode": "EVT-9021-ABCD", "FullName": "Alex Johnson", "Email": "alex@example.com", "EventProductName": "General Admission", "EventProductPrice": 15.0, "CalendarEvent": { "Id": 412, "Name": "Morning Yoga & Mindfulness", "StartDateUtc": "2026-03-23T07:30:00Z", "EndDateUtc": "2026-03-23T08:15:00Z", "Location": "Studio Room B", "HasLargeImage": true, "Business": { "Id": 5, "Name": "Downtown Coworking Hub" } }, "EventProduct": { "Id": 88, "Name": "General Admission", "Price": 15.0, "PriceCurrencyCode": "GBP", "SoldOut": false, "IsAvailableNow": true }, "Business": { "Id": 5, "Name": "Downtown Coworking Hub" }, "UniqueId": "c3d4e5f6-a7b8-9012-cdef-123456789012", "IdString": "9021", "CreatedOn": "2026-03-01T11:00:00", "UpdatedOn": "2026-03-01T11:00:00", "CreatedOnUtc": "2026-03-01T11:00:00Z", "UpdatedOnUtc": "2026-03-01T11:00:00Z", "IsNull": false } ], "CurrentPage": 1, "CurrentPageSize": 25, "TotalItems": 1, "TotalPages": 1, "HasNextPage": false, "HasPreviousPage": false } ``` ### Fetch my events with a minimal field set ```http theme={null} GET /api/public/events/my?showUpcoming=true&_shape=Records.Id,Records.EventProductName,Records.CalendarEvent.Name,Records.CalendarEvent.StartDateUtc Authorization: Bearer {token} ``` ```json theme={null} { "Records": [ { "Id": 9021, "EventProductName": "General Admission", "CalendarEvent": { "Name": "Morning Yoga & Mindfulness", "StartDateUtc": "2026-03-23T07:30:00Z" } } ], "CurrentPage": 1, "CurrentPageSize": 25, "TotalItems": 1, "TotalPages": 1, "HasNextPage": false, "HasPreviousPage": false } ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' import { MyEvents } from '@/types/endpoints/MyEvents' import { useData } from '@/api/fetchData' const endpoint = endpoints.events.myEvents(true) // showUpcoming=true const { resource: myEvents } = useData(httpClient, endpoint.url) ``` ## Usage in Portal | Context | Source file | | -------------------------------------------------- | --------------------------------------------------------------------------------------------- | | My Events page (`/activity/events`) | `src/views/user/activity/events/MyEventsSection.tsx` | | Weekly Agenda calendar widget (personal dashboard) | `src/views/user/dashboards/personal/components/WeeklyAgendaCalendar/WeeklyAgendaCalendar.tsx` | | Tickets statistic widget (personal dashboard) | `src/views/user/dashboards/personal/components/Statistics/widgets/TicketsStatisticWidget.tsx` | ## Error Responses The customer is not authenticated or the session has expired. ## Related Endpoints | Method | Endpoint | Description | | -------- | ----------------------------------------- | ------------------------------------------ | | `GET` | `/api/public/events` | Browse all published events | | `GET` | `/api/public/events/{id}` | Full detail for a specific event | | `POST` | `/api/public/events/my/{id}/sendTicket` | Re-send a ticket confirmation email | | `DELETE` | `/api/public/events/my/{id}` | Cancel (delete) a ticket | | `POST` | `/api/public/events/{id}/joinWaitingList` | Join the waiting list for a sold-out event | # Post Event Comment Source: https://learn.nexudus.com/api/endpoints/events/new-comment POST /en/events/newComment Posts a new comment (and optional rating) on a published event on behalf of the authenticated customer. # Post Event Comment Submits a new comment and optional star rating on a published event. Only available when the event's `AllowComments` flag is `true`. After a successful post the event detail data should be refetched to display the new comment. This endpoint uses the `/en/` legacy route prefix rather than `/api/public/`. ## Authentication Requires a valid customer bearer token. ## Request Body The integer ID of the event to comment on. Obtained as `Event.Id` from `GET /api/public/events/{id}`. The text body of the comment. Optional title or headline for the comment. Optional numeric rating (e.g. `1`–`5`). Pass `null` to submit without a rating. ## Response Returns an empty `200 OK` on success. Refetch `GET /api/public/events/{id}` to see the new comment in the `Event.Comments` array. ## Examples ### Post a comment with a rating ```http theme={null} POST /en/events/newComment Authorization: Bearer {token} Content-Type: application/json { "Id": 412, "comment": "Fantastic session, highly recommend to anyone looking to start their week right!", "Title": "Great yoga class", "Rating": 5 } ``` ``` HTTP/1.1 200 OK ``` ### Post a comment without a rating ```http theme={null} POST /en/events/newComment Authorization: Bearer {token} Content-Type: application/json { "Id": 412, "comment": "Really enjoyed this. Will be back next week.", "Title": null, "Rating": null } ``` ``` HTTP/1.1 200 OK ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' await httpClient.post(endpoints.events.newComment, { Id: 412, comment: 'Fantastic session, highly recommend!', Title: 'Great yoga class', Rating: 5, }) ``` ## Usage in Portal | Context | Source file | | ----------------------------------------------- | ---------------------------------- | | Event detail page comment form (`/events/{id}`) | `src/views/events/details/data.ts` | ## Error Responses The customer is not authenticated or the session has expired. Missing required field `Id` or `comment`, or the event does not allow comments (`AllowComments` is `false`). No event with the specified `Id` exists. ## Related Endpoints | Method | Endpoint | Description | | ------ | -------------------------- | ----------------------------------------------------------------- | | `GET` | `/api/public/events/{id}` | Event detail — includes `Comments` array and `AllowComments` flag | | `POST` | `/en/events/deleteComment` | Delete a comment previously posted by the customer | # Send Event Ticket Source: https://learn.nexudus.com/api/endpoints/events/send-ticket POST /api/public/events/my/{id}/sendTicket Sends a ticket confirmation email to the authenticated customer for a specific event attendance. # Send Event Ticket Triggers a ticket confirmation email to the authenticated customer for the specified attendance record. Used on the My Events page to allow customers to resend their ticket if it was lost or never received. ## Authentication Requires a valid customer bearer token. The attendance record must belong to the authenticated customer. ## Path Parameters The integer ID of the attendance record. Obtained as `Records[].Id` from `GET /api/public/events/my`. ## Request Body No request body required. ## Response Returns an empty `200 OK` on success. ## Examples ### Send a ticket email ```http theme={null} POST /api/public/events/my/9021/sendTicket Authorization: Bearer {token} ``` ``` HTTP/1.1 200 OK ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' await httpClient.post(endpoints.events.sendTicket(9021)) ``` ## Usage in Portal | Context | Source file | | ----------------------------------- | ---------------------------------------------------- | | My Events page (`/activity/events`) | `src/views/user/activity/events/MyEventsSection.tsx` | ## Error Responses The customer is not authenticated or the session has expired. No attendance record with the specified ID exists for the authenticated customer. ## Related Endpoints | Method | Endpoint | Description | | -------- | ---------------------------- | ----------------------------------------------- | | `GET` | `/api/public/events/my` | List all tickets for the authenticated customer | | `DELETE` | `/api/public/events/my/{id}` | Cancel a ticket | | `GET` | `/api/public/events/{id}` | Full detail for a specific event | # List Upcoming Home Page Events Source: https://learn.nexudus.com/api/endpoints/events/upcoming-events GET /api/public/events Returns published events flagged for the home page, used to populate upcoming event widgets on the portal home. # List Upcoming Home Page Events Returns a list of published events that the operator has flagged to appear on the portal home page (`onlyHomePage=true`). This is the shortcut endpoint behind `endpoints.events.upcomingEvents` — equivalent to calling the events list with `onlyHomePage=true`. This endpoint is a convenience alias for `GET /api/public/events?onlyHomePage=true`. See [List Events](/api/endpoints/events/list-events) for the full parameter and response documentation. ## Authentication No authentication required. ## Query Parameters Must be `true`. Returns only events that the operator has configured to appear on the portal home page. Comma-separated list of field paths to include in the response. When provided, only the specified fields are returned — useful for reducing payload size. Supports nested paths using dot notation. Example: `_shape=CalendarEvents.Records.Name,CalendarEvents.Records.StartDateUtc,CalendarEvents.TotalItems`. ## Response Returns the same `EventList` structure as [List Events](/api/endpoints/events/list-events). See that endpoint for the full field breakdown. ### Key Event Fields | Field | Type | Description | | -------------------- | --------- | --------------------------------------- | | `Id` | `number` | Unique numeric identifier for the event | | `Name` | `string` | Event title (localised) | | `ShortDescription` | `string` | Brief event description | | `StartDateUtc` | `string` | Event start date/time (UTC) | | `EndDateUtc` | `string` | Event end date/time (UTC) | | `HasLargeImage` | `boolean` | Whether the event has a large image | | `ShowInHomePage` | `boolean` | Whether flagged for the home page | | `HasTickets` | `boolean` | Whether the event has ticket products | | `SoldOut` | `boolean` | Whether all tickets are sold out | | `ChepeastPrice` | `number` | Lowest ticket price | | `MostExpensivePrice` | `number` | Highest ticket price | | `Business` | `object` | Location object (`Id`, `Name`) | ## Examples ### Fetch home page events ```http theme={null} GET /api/public/events?onlyHomePage=true ``` ```json theme={null} { "PastEvents": false, "Categories": [], "Category": null, "CalendarEvents": { "Records": [ { "Id": 420, "Name": "Startup Pitch Night", "ShortDescription": "Watch 8 local startups pitch to a panel of investors.", "StartDateUtc": "2026-03-28T18:00:00Z", "EndDateUtc": "2026-03-28T21:00:00Z", "HasLargeImage": true, "ShowInHomePage": true, "HasTickets": true, "SoldOut": false, "ChepeastPrice": 0, "MostExpensivePrice": 25.0, "Business": { "Id": 5, "Name": "Downtown Coworking Hub" } } ], "CurrentPage": 1, "CurrentPageSize": 25, "TotalItems": 1, "TotalPages": 1, "HasNextPage": false, "HasPreviousPage": false } } ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' // endpoints.events.upcomingEvents is a pre-built URL string: // 'api/public/events?onlyHomePage=true' const { resource: upcomingEvents } = useData(httpClient, endpoints.events.upcomingEvents) ``` ## Usage in Portal | Context | Source file | | ------------------------------------------------------ | ------------------------------------------------------------------------------------------------- | | Upcoming Events dashboard section (personal dashboard) | `src/views/user/dashboards/personal/components/UpcomingEvents/UpcomingEventsDashboardSection.tsx` | ## Error Responses Invalid query parameter value. ## Related Endpoints | Method | Endpoint | Description | | ------ | ------------------------- | ------------------------------------------- | | `GET` | `/api/public/events` | Full paginated events list with all filters | | `GET` | `/api/public/events/{id}` | Full detail for a specific event | | `GET` | `/api/public/events/my` | Tickets held by the authenticated customer | # AI FAQ Search Source: https://learn.nexudus.com/api/endpoints/faqs/ai-search POST /api/public/faqs/aiSearch Performs an AI-powered search across FAQs and returns a generated response. # AI FAQ Search Submits a natural language question and returns an AI-generated response based on the location's FAQ knowledge base. If a matching document was used, its ID and name are included in the response. ## Authentication No authentication required. ## Request Body The natural language question to search for. ## Response The AI-generated response. The generated answer text. ID of the FAQ document used to generate the answer, if applicable. Name of the FAQ document used, if applicable. ## Examples ### Search FAQs ```http theme={null} POST /api/public/faqs/aiSearch Content-Type: application/json { "query": "What are the opening hours?" } ``` ```json theme={null} { "AiResponse": { "r": "Our space is open Monday to Friday from 8am to 8pm, and Saturday from 9am to 5pm.", "UsedDocumentId": 15, "UsedDocumentName": "Opening Hours" } } ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' const result = await httpClient.post(endpoints.faqs.aiSearch().url, { query: 'What are the opening hours?', }) ``` # List FAQs Source: https://learn.nexudus.com/api/endpoints/faqs/list-faqs GET /api/public/faqs Returns all published FAQ entries for the current location. # List FAQs Returns the complete list of published FAQ entries for the current location, organised by group. Used to render the FAQ page in the portal. ## Authentication No authentication required. ## Query Parameters Comma-separated list of field paths to include in the response. When provided, only the specified fields are returned — useful for reducing payload size. Supports nested paths using dot notation. ## Response Returns a `FaqList` object containing FAQ entries grouped by category. ### Top-Level Fields | Field | Type | Description | | --------------- | ---------- | ------------------------------------------ | | `Categories` | `string[]` | Array of distinct FAQ group/category names | | `OpenAiEnabled` | `boolean` | Whether AI-powered FAQ search is enabled | ### FaqArticles Array | Field | Type | Description | | --------------- | ---------------- | --------------------------------------- | | `Id` | `number` | Unique numeric identifier for the FAQ | | `UniqueId` | `string` | Globally unique identifier | | `Title` | `string` | FAQ question / title | | `SummaryText` | `string` | Short answer summary | | `FullText` | `string` | Full answer body (HTML) | | `GroupName` | `string` | Category name the FAQ belongs to | | `DisplayOrder` | `number` | Sort order within the group | | `Active` | `boolean` | Whether the FAQ is published | | `HasImage` | `boolean` | Whether the FAQ has a thumbnail image | | `HasLargeImage` | `boolean` | Whether the FAQ has a large image | | `CreatedOn` | `string` | Date created (business-local time) | | `UpdatedOn` | `string \| null` | Date last updated (business-local time) | ## Examples ### Fetch FAQs ```http theme={null} GET /api/public/faqs ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' const { resource: faqs } = useTypedData(httpClient, endpoints.faqs.list()) ``` # E-Sign Status Source: https://learn.nexudus.com/api/endpoints/files/esign-status GET /api/public/files/{fileId}/esign/status Returns the electronic signature status for a specific file. # E-Sign Status Returns the current electronic signature status for a specific file. Used to check whether a document has been signed, is pending, or requires action. ## Authentication Requires a valid customer bearer token. ## Path Parameters Numeric identifier of the file. ## Query Parameters Comma-separated list of field paths to include in the response. When provided, only the specified fields are returned — useful for reducing payload size. Supports nested paths using dot notation. ## Response Returns a `HelloSignSignatureStatus` object with the e-signature status. ### E-Sign Status Fields | Field | Type | Description | | ---------------- | ---------------- | ------------------------------------------------ | | `SignatureId` | `string` | Identifier for the signature request | | `Status` | `string` | Current status (`pending`, `signed`, `declined`) | | `SignedAt` | `string \| null` | Date the document was signed | | `LastViewedAt` | `string \| null` | Date the document was last viewed | | `LastRemindedAt` | `string \| null` | Date the last reminder was sent | ## Examples ### Check e-sign status ```http theme={null} GET /api/public/files/22/esign/status Authorization: Bearer {token} ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' const { resource: status } = useTypedData(httpClient, endpoints.files.esign.status(22)) ``` # List Files Source: https://learn.nexudus.com/api/endpoints/files/list-files GET /api/public/files/my Returns the authenticated customer's files and documents. # List Files Returns the list of files and documents associated with the authenticated customer's account, including contracts, agreements, and uploaded documents. ## Authentication Requires a valid customer bearer token. ## Query Parameters Comma-separated list of field paths to include in the response. When provided, only the specified fields are returned — useful for reducing payload size. Supports nested paths using dot notation. ## Response Returns an array of file objects with the following fields. ### File Fields #### Identity | Field | Type | Description | | ---------- | -------- | -------------------------------------- | | `Id` | `number` | Unique numeric identifier for the file | | `UniqueId` | `string` | Globally unique identifier | #### Core | Field | Type | Description | | ------------------------- | ---------------- | --------------------------------------- | | `Name` | `string` | File display name | | `Description` | `string` | File description | | `BusinessName` | `string` | Location that owns the file | | `Signed` | `boolean` | Whether the document has been signed | | `RequestDigitalSignature` | `boolean` | Whether a digital signature is required | | `ProposalUniqueId` | `string \| null` | Linked proposal GUID (if applicable) | #### Timestamps (from base) | Field | Type | Description | | -------------- | ---------------- | --------------------------------------- | | `CreatedOn` | `string` | Date created (business-local time) | | `UpdatedOn` | `string \| null` | Date last updated (business-local time) | | `CreatedOnUtc` | `string` | Date created (UTC) | | `UpdatedOnUtc` | `string \| null` | Date last updated (UTC) | ## Examples ### Fetch my files ```http theme={null} GET /api/public/files/my Authorization: Bearer {token} ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' const response = await httpClient.get(endpoints.files.list) ``` # Get Form Source: https://learn.nexudus.com/api/endpoints/forms/get-form GET /api/public/forms/{formId} Returns the full configuration of a form or survey for rendering. # Get Form Returns the complete form definition including fields, validation rules, and display settings. Used to render the form for user input. ## Authentication No authentication required for public forms. ## Path Parameters Unique identifier (GUID) of the form. ## Query Parameters Comma-separated list of field paths to include in the response. When provided, only the specified fields are returned — useful for reducing payload size. Supports nested paths using dot notation. ## Response Returns the form configuration object with the following fields. ### Form Fields #### Identity | Field | Type | Description | | ---------- | -------- | -------------------------------------- | | `Id` | `number` | Unique numeric identifier for the form | | `UniqueId` | `string` | Globally unique identifier | #### Core | Field | Type | Description | | ------------- | --------- | ------------------------------- | | `Name` | `string` | Form display name | | `Description` | `string` | Form description / instructions | | `Active` | `boolean` | Whether the form is active | #### Questions Each form contains an array of question objects: | Field | Type | Description | | ----------------------- | ---------------- | ---------------------------------------- | | `Id` | `number` | Question identifier | | `Text` | `string` | Question text | | `Description` | `string` | Question description / help text | | `QuestionType` | `string` | Type of question (e.g. `Text`, `Select`) | | `AvailableOptions` | `string` | Comma-separated list of options | | `AvailableOptionsArray` | `string[]` | Array of option strings | | `DisplayOrder` | `number \| null` | Sort order of the question | | `AllowMultipleOptions` | `boolean` | Whether multiple selections are allowed | | `IsRequired` | `boolean` | Whether the question is required | #### Timestamps (from base) | Field | Type | Description | | -------------- | ---------------- | --------------------------------------- | | `CreatedOn` | `string` | Date created (business-local time) | | `UpdatedOn` | `string \| null` | Date last updated (business-local time) | | `CreatedOnUtc` | `string` | Date created (UTC) | | `UpdatedOnUtc` | `string \| null` | Date last updated (UTC) | ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' const response = await httpClient.get(endpoints.forms.show('abc123')) ``` # Preview Form Source: https://learn.nexudus.com/api/endpoints/forms/preview-form GET /api/public/forms/{formId}/preview Returns the preview configuration for a form or survey. # Preview Form Returns the form schema and configuration for preview purposes. Used to render forms before they are submitted. ## Authentication No authentication required. ## Path Parameters Unique identifier (GUID) of the form. ## Query Parameters Comma-separated list of field paths to include in the response. When provided, only the specified fields are returned — useful for reducing payload size. Supports nested paths using dot notation. ## Response Returns the form schema with field definitions, validation rules, and layout. Same structure as [`GET /api/public/forms/{formId}`](/api/endpoints/forms/get-form) — see that endpoint for the full field breakdown. ### Form Fields #### Identity | Field | Type | Description | | ---------- | -------- | -------------------------------------- | | `Id` | `number` | Unique numeric identifier for the form | | `UniqueId` | `string` | Globally unique identifier | #### Core | Field | Type | Description | | ------------- | --------- | ------------------------------- | | `Name` | `string` | Form display name | | `Description` | `string` | Form description / instructions | | `Active` | `boolean` | Whether the form is active | ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' const response = await httpClient.get(endpoints.forms.preview('abc123')) ``` # Submit Form Source: https://learn.nexudus.com/api/endpoints/forms/submit-form POST /api/public/forms/{formId} Submits a completed form or survey response. # Submit Form Submits the user's responses for a form or survey. The request body contains the field values matching the form schema. ## Authentication Authentication requirements depend on form configuration. Some forms are public, others require a bearer token. ## Path Parameters Unique identifier (GUID) of the form. ## Request Body Dynamic field values matching the form's field definitions. ## Response Returns a `200 OK` on success. ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' await httpClient.post(endpoints.forms.submit('abc123'), formValues) ``` # Close Help Desk Message Source: https://learn.nexudus.com/api/endpoints/helpdesk/close-message PUT /api/public/helpdesk/messages/{messageId}/close Closes an open help desk support ticket. # Close Help Desk Message Marks a help desk message as closed. Only the ticket author can close their own tickets. ## Authentication Requires a valid customer bearer token. ## Path Parameters Numeric identifier of the message to close. ## Request Body No request body required. ## Response Returns a `200 OK` on success. ## Examples ### Close a ticket ```http theme={null} PUT /api/public/helpdesk/messages/501/close Authorization: Bearer {token} ``` ``` HTTP/1.1 200 OK ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' await httpClient.put(endpoints.helpDesk.close(501)) ``` # Create Help Desk Comment Source: https://learn.nexudus.com/api/endpoints/helpdesk/create-comment POST /api/public/helpdesk/messages/{messageId}/comments Adds a comment to an existing help desk message thread. # Create Help Desk Comment Adds a follow-up comment to an existing help desk message thread. Used for back-and-forth communication between the customer and the support team. ## Authentication Requires a valid customer bearer token. ## Path Parameters Numeric identifier of the help desk message to comment on. ## Request Body The text content of the comment. ## Response Returns a `200 OK` on success. ## Examples ### Add a comment ```http theme={null} POST /api/public/helpdesk/messages/501/comments Authorization: Bearer {token} Content-Type: application/json { "MessageText": "The issue is still happening after restarting the router." } ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' await httpClient.post(endpoints.helpDesk.comments.create(501), { MessageText: 'The issue is still happening after restarting the router.', }) ``` # Create Help Desk Message Source: https://learn.nexudus.com/api/endpoints/helpdesk/create-message POST /api/public/helpdesk/messages Creates a new help desk support ticket. # Create Help Desk Message Submits a new support ticket to the help desk. The message is assigned to the operator's configured department or default queue. ## Authentication Requires a valid customer bearer token. ## Request Body Subject line for the support ticket. Full description of the issue or request. Optional department ID to route the ticket. See the departments endpoint. ## Response Returns a `200 OK` on success with the created message details. ## Examples ### Create a ticket ```http theme={null} POST /api/public/helpdesk/messages Authorization: Bearer {token} Content-Type: application/json { "Subject": "Wi-Fi not working", "MessageText": "The Wi-Fi on the 2nd floor has been down since this morning.", "DepartmentId": 3 } ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' await httpClient.post(endpoints.helpDesk.create, { Subject: 'Wi-Fi not working', MessageText: 'The Wi-Fi on the 2nd floor has been down since this morning.', DepartmentId: 3, }) ``` # Delete Help Desk Comment Source: https://learn.nexudus.com/api/endpoints/helpdesk/delete-comment DELETE /api/public/helpdesk/messages/{messageId}/comments/{commentId} Deletes a comment from a help desk message thread. # Delete Help Desk Comment Removes a specific comment from a help desk message thread. Only the comment author can delete their own comments. ## Authentication Requires a valid customer bearer token. ## Path Parameters Numeric identifier of the help desk message. Numeric identifier of the comment to delete. ## Response Returns a `200 OK` on success. ## Examples ### Delete a comment ```http theme={null} DELETE /api/public/helpdesk/messages/501/comments/42 Authorization: Bearer {token} ``` ``` HTTP/1.1 200 OK ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' await httpClient.delete(endpoints.helpDesk.comments.delete(501, 42)) ``` # List Help Desk Comments Source: https://learn.nexudus.com/api/endpoints/helpdesk/list-comments GET /api/public/helpdesk/messages/{messageId}/comments Returns the comments on a help desk message thread. # List Help Desk Comments Returns all comments on a specific help desk message thread. Used to render the conversation history on the ticket detail page. ## Authentication Requires a valid customer bearer token. ## Path Parameters Numeric identifier of the help desk message. ## Query Parameters Comma-separated list of field paths to include in the response. When provided, only the specified fields are returned — useful for reducing payload size. Supports nested paths using dot notation. Example: `_shape=Records.MessageText,Records.CoworkerId,Records.CreatedOn`. ## Response Returns an `ApiListResult` with the comment records. The top-level response includes standard pagination fields (`CurrentPage`, `TotalItems`, `TotalPages`, etc.). Each item in the `Records` array has: #### Identity | Field | Type | Description | | ---------- | -------- | --------------------------------- | | `Id` | `number` | Unique identifier for the comment | | `UniqueId` | `string` | GUID identifier | #### Content | Field | Type | Description | | --------------- | --------- | --------------------------------------- | | `MessageText` | `string` | Comment text content | | `IsAiGenerated` | `boolean` | Whether the comment was generated by AI | #### Author | Field | Type | Description | | ------------ | ---------- | ---------------------------------------- | | `Coworker` | `Coworker` | Coworker who posted the comment (nested) | | `CoworkerId` | `number` | Coworker identifier | #### Media | Field | Type | Description | | --------------- | --------- | ----------------------------------------- | | `HasImage` | `boolean` | Whether the comment has an attached image | | `ImageFileName` | `string` | Filename of the attached image | #### Timestamps (from base) | Field | Type | Description | | -------------- | -------- | ------------------------------------ | | `CreatedOn` | `string` | Record creation timestamp (local) | | `UpdatedOn` | `string` | Record last-update timestamp (local) | | `CreatedOnUtc` | `string` | Record creation timestamp (UTC) | | `UpdatedOnUtc` | `string` | Record last-update timestamp (UTC) | ## Examples ### Fetch comments ```http theme={null} GET /api/public/helpdesk/messages/501/comments Authorization: Bearer {token} ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' const { resource: comments } = useTypedData(httpClient, endpoints.helpDesk.comments.list(501)) ``` # List Help Desk Departments Source: https://learn.nexudus.com/api/endpoints/helpdesk/list-departments GET /api/public/helpdesk/departments Returns the available help desk departments for routing support tickets. # List Help Desk Departments Returns the list of help desk departments configured by the operator. Used to populate a department selector when creating new support tickets. ## Authentication Requires a valid customer bearer token. ## Query Parameters Comma-separated list of field paths to include in the response. When provided, only the specified fields are returned — useful for reducing payload size. Supports nested paths using dot notation. ## Response Array of available departments. Unique identifier for the department. Use as `DepartmentId` when creating a message. Display name of the department. Description of the department's scope. ## Examples ### Fetch departments ```http theme={null} GET /api/public/helpdesk/departments Authorization: Bearer {token} ``` ```json theme={null} { "Departments": [ { "Id": 1, "Name": "General", "Description": "General enquiries" }, { "Id": 2, "Name": "Billing", "Description": "Invoice and payment issues" }, { "Id": 3, "Name": "Facilities", "Description": "Building and equipment" } ] } ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' const { resource: departments } = useTypedData(httpClient, endpoints.helpDesk.departments()) ``` # List Help Desk Messages Source: https://learn.nexudus.com/api/endpoints/helpdesk/list-messages GET /api/public/helpdesk/messages Returns the authenticated customer's help desk messages, optionally including closed tickets. # List Help Desk Messages Returns a list of help desk messages (support tickets) belonging to the authenticated customer. By default returns only open tickets; set `showClosed=true` to include resolved tickets. ## Authentication Requires a valid customer bearer token. ## Query Parameters `true` — include closed/resolved tickets. `false` — return only open tickets. Comma-separated list of field paths to include in the response. When provided, only the specified fields are returned — useful for reducing payload size. Supports nested paths using dot notation. Example: `_shape=Records.Subject,Records.Closed,Records.CreatedOn`. ## Response Returns a `HelpDeskMessages` object containing an array of support ticket records. ### Help Desk Message Fields #### Identity | Field | Type | Description | | ---------- | -------- | ----------------------------------------- | | `Id` | `number` | Unique numeric identifier for the message | | `UniqueId` | `string` | Globally unique identifier | #### Core | Field | Type | Description | | ------------- | --------- | --------------------------------------- | | `Subject` | `string` | Ticket subject line | | `MessageText` | `string` | Ticket body text | | `Closed` | `boolean` | Whether the ticket is closed / resolved | | `HasImage` | `boolean` | Whether an image attachment exists | #### Nested Objects | Field | Type | Description | | ------------ | ---------- | ------------------------------------------------------- | | `Department` | `object` | Help desk department (`Id`, `Name`, `Description`) | | `Coworker` | `object` | Customer who opened the ticket (`Id`, `FullName`, etc.) | | `Comments` | `object[]` | Array of reply comments on this ticket | #### Timestamps (from base) | Field | Type | Description | | -------------- | ---------------- | --------------------------------------- | | `CreatedOn` | `string` | Date created (business-local time) | | `UpdatedOn` | `string \| null` | Date last updated (business-local time) | | `CreatedOnUtc` | `string` | Date created (UTC) | | `UpdatedOnUtc` | `string \| null` | Date last updated (UTC) | ## Examples ### Fetch open tickets ```http theme={null} GET /api/public/helpdesk/messages?showClosed=false Authorization: Bearer {token} ``` ### Fetch all tickets including closed ```http theme={null} GET /api/public/helpdesk/messages?showClosed=true Authorization: Bearer {token} ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' const { resource: messages } = useTypedData(httpClient, endpoints.helpDesk.list(false)) ``` # Get Help Desk Message Source: https://learn.nexudus.com/api/endpoints/helpdesk/message-details GET /api/public/helpdesk/messages/{messageId} Returns the full details of a single help desk message. # Get Help Desk Message Returns the complete details of a specific help desk message (support ticket), including status and associated metadata. ## Authentication Requires a valid customer bearer token. The message must belong to the authenticated customer. ## Path Parameters Numeric identifier of the help desk message. Returned as `Id` from the message list. ## Query Parameters Comma-separated list of field paths to include in the response. When provided, only the specified fields are returned — useful for reducing payload size. Supports nested paths using dot notation. Example: `_shape=Subject,MessageText,Closed,Comments`. ## Response Returns a `HelpDeskMessage` object. Unique identifier for the message. Subject line of the support ticket. Full body text of the message. `true` when the ticket has been closed. Creation timestamp in ISO 8601 format. ## Examples ### Fetch message details ```http theme={null} GET /api/public/helpdesk/messages/501 Authorization: Bearer {token} ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' const { resource: message } = useTypedData(httpClient, endpoints.helpDesk.one(501)) ``` # List Identity Checks Source: https://learn.nexudus.com/api/endpoints/identity/list-identity-checks GET /api/public/identityChecks/my Returns the identity check requests for the authenticated customer. # List Identity Checks Returns identity check requests for the authenticated customer. These are verification requests (e.g. ID upload, KYC) that the operator has configured as part of the onboarding or compliance process. ## Authentication Requires a valid customer bearer token. ## Query Parameters `true` — return only pending/incomplete checks. `false` — return all checks including completed ones. Comma-separated list of field paths to include in the response. When provided, only the specified fields are returned — useful for reducing payload size. Supports nested paths using dot notation. ## Response Returns an `IdentityChecksList` object — a paginated list of identity check records. ### Identity Check Fields #### Identity | Field | Type | Description | | ----- | -------- | ------------------------------------------------ | | `Id` | `number` | Unique numeric identifier for the identity check | #### Core | Field | Type | Description | | ----------------------- | -------- | ------------------------------------------------- | | `Name` | `string` | Check display name | | `Description` | `string` | Check description | | `Notes` | `string` | Additional notes | | `VerificationType` | `string` | Type of verification (e.g. `Identity`, `Address`) | | `IdentityCheckProvider` | `string` | Provider used for the check | | `VerificationStatus` | `string` | Current status (`Pending`, `Verified`, etc.) | | `LastError` | `string` | Last error message (if any) | #### Contact | Field | Type | Description | | ----------------- | -------- | --------------------- | | `ContactId` | `number` | Contact identifier | | `ContactFullName` | `string` | Contact full name | | `BusinessId` | `number` | Location identifier | | `BusinessName` | `string` | Location display name | #### Documents | Field | Type | Description | | -------------------------------- | ---------------- | ------------------------- | | `IdentityDocumentType` | `string` | Type of identity document | | `IdentityDocumentIssuedBy` | `string` | Issuing authority | | `IdentityDocumentExpirationDate` | `string \| null` | Document expiration date | | `AddressDocumentType` | `string` | Type of address document | #### Timestamps | Field | Type | Description | | -------------- | -------- | ------------------ | | `CreatedOnUtc` | `string` | Date created (UTC) | ## Examples ### Fetch pending checks ```http theme={null} GET /api/public/identityChecks/my?showPending=true Authorization: Bearer {token} ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' const { resource: checks } = useTypedData(httpClient, endpoints.identity.list(true)) ``` # Upload Identity Document Source: https://learn.nexudus.com/api/endpoints/identity/upload-document POST /api/public/identityChecks/documents/upload/{id} Uploads a verification document for a specific identity check. # Upload Identity Document Uploads a document (e.g. passport scan, driver's licence) for a specific identity check request. The file is submitted as a multipart form upload. ## Authentication Requires a valid customer bearer token. ## Path Parameters Numeric identifier of the identity check request. ## Request Body Multipart form data with the document file. ## Response Returns a `200 OK` on successful upload. ## Examples ### Upload a document ```http theme={null} POST /api/public/identityChecks/documents/upload/15 Authorization: Bearer {token} Content-Type: multipart/form-data [file data] ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' const formData = new FormData() formData.append('file', file) await httpClient.post(endpoints.identity.upload(15), formData) ``` # Subscribe to Newsletter Source: https://learn.nexudus.com/api/endpoints/newsletter/subscribe POST /api/public/newsletter/subscribe Subscribes the current user or email address to the location newsletter. # Subscribe to Newsletter Registers an email address for the location's newsletter. Can be called by authenticated customers or public visitors providing an email address. ## Authentication No authentication required for public subscription. ## Request Body Email address to subscribe. ## Response `true` if the subscription was created or already existed. ## Examples ### Subscribe ```http theme={null} POST /api/public/newsletter/subscribe Content-Type: application/json { "Email": "visitor@example.com" } ``` ```json theme={null} { "WasSuccessful": true } ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' const result = await httpClient.post(endpoints.newsletter.subscribe().url, { Email: 'visitor@example.com', }) ``` # Onboarding Tasks Source: https://learn.nexudus.com/api/endpoints/onboarding/onboarding-tasks GET /api/public/onboarding Returns the list of onboarding tasks for the authenticated customer. # Onboarding Tasks Returns the current onboarding checklist for the authenticated customer. Tasks include items like completing their profile, adding directors, setting mail preferences, identity checks, or setting up e-invoicing. Used to display onboarding progress on the dashboard. ## Authentication Requires a valid customer bearer token. ## Response Returns an array of `OnBoardingTask` objects with completion status. ### Task Fields | Field | Type | Description | | ------------ | --------- | -------------------------------------------------------------------------------------------- | | `CoworkerId` | `number` | Numeric identifier for the customer the task belongs to | | `GroupId` | `string` | UUID that groups related tasks together (e.g. all virtual office tasks share the same group) | | `Type` | `string` | The onboarding category. See [Task Types](#task-types) below | | `Action` | `string` | The specific action required. See [Task Actions](#task-actions) below | | `Completed` | `boolean` | Whether the customer has completed this task | ### Task Types | Value | Description | | ----------------------- | -------------------------------------------------------- | | `VirtualOffice` | Virtual office setup tasks (directors, mail, recipients) | | `IdentityCheck` | Identity verification tasks | | `DeferredRequiredField` | Required profile fields that must be completed later | | `CompleteProfile` | Personal profile completion | | `CompleteTeamProfile` | Team profile completion | | `UnpaidInvoices` | Outstanding invoices that need payment | | `PendingDelivery` | Pending mail or package deliveries | | `EInvoicing` | Electronic invoicing setup | ### Task Actions | Value | Applicable Type(s) | Description | | ------------------------ | -------------------------------- | ------------------------------------------------ | | `AddDirectors` | `VirtualOffice` | Add company directors to the virtual office | | `AddRecipients` | `VirtualOffice` | Add mail recipients for the virtual office | | `SetMailPreferences` | `VirtualOffice` | Configure mail handling preferences | | `StartIdentityChecks` | `IdentityCheck` | Initiate identity verification | | `CompleteIdentityChecks` | `IdentityCheck`, `VirtualOffice` | Finish all identity verification steps | | `CompleteProfile` | `CompleteProfile` | Fill in all required profile fields | | `PublishProfile` | `CompleteProfile` | Make the member profile visible in the directory | | `CompleteTeamProfile` | `CompleteTeamProfile` | Fill in all required team profile fields | | `AddEInvoicingDetails` | `EInvoicing` | Add electronic invoicing details | ## Examples ### Fetch onboarding tasks ```http theme={null} GET /api/public/onboarding Authorization: Bearer {token} ``` ### Response — Virtual office tasks (mixed completion) ```json theme={null} [ { "CoworkerId": 4706, "GroupId": "ad1d8608-9b95-454a-9a1c-944980f7eca5", "Type": "VirtualOffice", "Action": "AddDirectors", "Completed": true }, { "CoworkerId": 4706, "GroupId": "ad1d8608-9b95-454a-9a1c-944980f7eca5", "Type": "VirtualOffice", "Action": "CompleteIdentityChecks", "Completed": true }, { "CoworkerId": 4706, "GroupId": "ad1d8608-9b95-454a-9a1c-944980f7eca5", "Type": "VirtualOffice", "Action": "SetMailPreferences", "Completed": false } ] ``` ### Response — Identity check tasks ```json theme={null} [ { "CoworkerId": 4706, "GroupId": "b2e4f910-3c78-4d1a-a5ef-82710dc3b6f1", "Type": "IdentityCheck", "Action": "StartIdentityChecks", "Completed": false }, { "CoworkerId": 4706, "GroupId": "b2e4f910-3c78-4d1a-a5ef-82710dc3b6f1", "Type": "IdentityCheck", "Action": "CompleteIdentityChecks", "Completed": false } ] ``` ### Response — Multiple task types ```json theme={null} [ { "CoworkerId": 4706, "GroupId": "ad1d8608-9b95-454a-9a1c-944980f7eca5", "Type": "VirtualOffice", "Action": "AddDirectors", "Completed": false }, { "CoworkerId": 4706, "GroupId": "ad1d8608-9b95-454a-9a1c-944980f7eca5", "Type": "VirtualOffice", "Action": "SetMailPreferences", "Completed": true }, { "CoworkerId": 4706, "GroupId": "ad1d8608-9b95-454a-9a1c-944980f7eca5", "Type": "VirtualOffice", "Action": "AddRecipients", "Completed": true }, { "CoworkerId": 4706, "GroupId": "b2e4f910-3c78-4d1a-a5ef-82710dc3b6f1", "Type": "IdentityCheck", "Action": "StartIdentityChecks", "Completed": false }, { "CoworkerId": 4706, "GroupId": "b2e4f910-3c78-4d1a-a5ef-82710dc3b6f1", "Type": "IdentityCheck", "Action": "CompleteIdentityChecks", "Completed": false }, { "CoworkerId": 4706, "GroupId": "f1a2b3c4-5678-9def-abcd-ef0123456789", "Type": "CompleteProfile", "Action": "CompleteProfile", "Completed": false }, { "CoworkerId": 4706, "GroupId": "f1a2b3c4-5678-9def-abcd-ef0123456789", "Type": "EInvoicing", "Action": "AddEInvoicingDetails", "Completed": false } ] ``` ### Response — No pending tasks ```json theme={null} [] ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' const response = await httpClient.get(endpoints.onboarding.tasks) ``` ### Types ```typescript theme={null} import type { OnBoardingTask, OnBoardingTasks } from '@/types/endpoints/OnBoardingTasks' import { eOnBoardingType, eOnBoardingAction } from '@/types/endpoints/OnBoardingTasks' ``` # Get Passport Business Details Source: https://learn.nexudus.com/api/endpoints/passport/business-details GET /api/passport/business Returns details for a specific business in the passport network. # Get Passport Business Details Returns the full details for a specific coworking business in the passport network. Used when a member selects a location on the passport map. ## Authentication No authentication required. ## Query Parameters Numeric identifier of the business. ## Response Returns a business detail object with location, amenities, and access information. ## Examples ### Fetch business details ```http theme={null} GET /api/passport/business?businessId=5 ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' const response = await httpClient.get(endpoints.passport.details(5)) ``` # Search Passport Locations Source: https://learn.nexudus.com/api/endpoints/passport/search-locations GET /api/passport/map Returns coworking locations near a geographic point, for the passport/network map. # Search Passport Locations Returns coworking locations within a specified distance of a geographic point. Powers the passport/network map feature that lets members discover and access partner spaces. ## Authentication No authentication required. ## Query Parameters Latitude of the search centre point. Longitude of the search centre point. Search radius (in kilometres). Optional root business ID to scope results to a specific network. ## Response Returns an array of location objects with address, coordinates, and business details. ## Examples ### Search near a location ```http theme={null} GET /api/passport/map?latitude=51.5074&longitude=-0.1278&distance=50 ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' const response = await httpClient.get(endpoints.passport.getByCenter(51.5074, -0.1278, 50)) ``` # Claim Perk Source: https://learn.nexudus.com/api/endpoints/perks/claim-perk POST /api/public/perks/{perkId}/claim Claims a perk on behalf of the authenticated customer, returning a redirect URL if applicable. # Claim Perk Records that the authenticated customer has claimed a specific perk. If the perk has an associated external URL (e.g. a discount code landing page), the response includes a `Url` field for redirection. ## Authentication Requires a valid customer bearer token. ## Path Parameters The integer ID of the perk to claim. Obtained as `Perks[].Id` from `GET /api/public/perks`. ## Request Body No request body required. ## Response External URL to redirect the customer to after claiming the perk. May be empty if the perk has no associated link. ## Examples ### Claim a perk ```http theme={null} POST /api/public/perks/101/claim Authorization: Bearer {token} ``` ```json theme={null} { "Url": "https://cornercafe.example.com/discount?code=NX15" } ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' const result = await httpClient.post(endpoints.perks.claim(101)) if (result.Url) { window.open(result.Url, '_blank') } ``` # List Perks Source: https://learn.nexudus.com/api/endpoints/perks/list-perks GET /api/public/perks Returns all published perks for the current location, grouped by category. # List Perks Returns all published perks available at the current location. Perks are grouped by their `GroupName` and include full-text descriptions suitable for rendering in a perks catalogue. A **perk** is a benefit or discount offered by a partner business (restaurant, gym, etc.) to coworking members. Operators configure perks in the admin dashboard and members can claim them from the portal. ## Authentication Requires a valid customer bearer token. ## Query Parameters Comma-separated list of field paths to include in the response. When provided, only the specified fields are returned — useful for reducing payload size. Supports nested paths using dot notation. ## Response ### Core Fields List of unique group names across all perks — use to build category tabs or filter UI. Array of all published perks. Unique identifier for the perk. Use as `{perkId}` in the claim endpoint. Display title of the perk. Category group this perk belongs to. Matches one of the values in the `Groups` array. Full description of the perk. May contain HTML. Short summary shown in perk cards. ## Examples ### Fetch all perks ```http theme={null} GET /api/public/perks Authorization: Bearer {token} ``` ```json theme={null} { "Groups": ["Food & Drink", "Fitness"], "Perks": [ { "Id": 101, "Title": "15% off at Corner Café", "GroupName": "Food & Drink", "FullText": "

Show your member badge at Corner Café for 15% off any order.

", "SummaryText": "15% off any order" } ] } ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' const { resource: perks } = useTypedData(httpClient, endpoints.perks.list()) // perks.Groups, perks.Perks ``` # Cancel Plan Source: https://learn.nexudus.com/api/endpoints/plans/cancel-plan POST /api/public/plans/cancel Submits a cancellation request for an active plan. # Cancel Plan Submits a cancellation request for the authenticated customer's active plan. Depending on operator configuration, cancellation may take effect immediately or at the end of the current billing period. ## Authentication Requires a valid customer bearer token. ## Request Body The request body contains the contract/plan details for the cancellation. The integer ID of the contract to cancel. ## Response Returns a `200 OK` on success. ## Examples ### Cancel a plan ```http theme={null} POST /api/public/plans/cancel Authorization: Bearer {token} Content-Type: application/json { "ContractId": 789 } ``` ``` HTTP/1.1 200 OK ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' await httpClient.post(endpoints.plans.cancel, { ContractId: 789 }) ``` # List My Plans Source: https://learn.nexudus.com/api/endpoints/plans/my-plans GET /api/public/plans/my Returns all active plans (contracts) for the authenticated customer. # List My Plans Returns the list of plans (contracts/tariffs) that the authenticated customer currently holds. Used to display the customer's active subscriptions on the dashboard. A **plan** (also called a tariff) is a recurring membership package. Each plan creates a **contract** that tracks billing, start/end dates, and cancellation status. ## Authentication Requires a valid customer bearer token. ## Query Parameters Comma-separated list of field paths to include in the response. When provided, only the specified fields are returned — useful for reducing payload size. Supports nested paths using dot notation. Example: `_shape=Records.Tariff.Name,Records.Price,Records.Active,Records.StartDate`. ## Response Returns an array of contract/plan objects for the authenticated customer. ### Contract Fields #### Identity | Field | Type | Description | | ---------- | -------- | ------------------------------------------ | | `Id` | `number` | Unique numeric identifier for the contract | | `UniqueId` | `string` | Globally unique identifier | #### Dates | Field | Type | Description | | -------------------------- | ---------------- | --------------------------------------- | | `StartDate` | `string \| null` | Contract start date (business-local) | | `ContractTerm` | `string \| null` | Contract end/term date (business-local) | | `RenewalDate` | `string \| null` | Next renewal date (business-local) | | `RenewalDateUtc` | `string \| null` | Next renewal date (UTC) | | `CancellationDate` | `string \| null` | Scheduled cancellation date | | `CancellationDateUtc` | `string \| null` | Scheduled cancellation date (UTC) | | `EarliestCancellationDate` | `string \| null` | Earliest allowed cancellation date | | `NextAutoInvoice` | `string \| null` | Next automatic invoice date | #### Pricing | Field | Type | Description | | ------------------------- | ---------------- | ----------------------------------------- | | `Price` | `number \| null` | Current contract price | | `PriceWithMinimum` | `number \| null` | Price including minimum charge | | `PriceFormatted` | `string` | Price formatted with currency symbol | | `NextPrice` | `number \| null` | Price after next renewal | | `NextPriceFormatted` | `string` | Next price formatted with currency symbol | | `Value` | `number \| null` | Contract value | | `DepositsAmount` | `number` | Total deposit amount | | `DepositsAmountFormatted` | `string` | Deposits formatted with currency symbol | #### Status | Field | Type | Description | | -------------------------- | ---------------- | ------------------------------------------- | | `Active` | `boolean` | Whether the contract is currently active | | `Cancelled` | `boolean` | Whether the contract has been cancelled | | `MainContract` | `boolean` | Whether this is the primary contract | | `PricePlanTermsAccepted` | `boolean` | Whether T\&C have been accepted | | `PricePlanTermsAcceptedOn` | `string \| null` | When T\&C were accepted | | `IsPaused` | `boolean` | Whether the contract has a pause configured | | `IsPausedNow` | `boolean` | Whether currently in a paused period | | `CanBePausedNow` | `boolean` | Whether the contract can be paused now | | `InPausedPeriod` | `boolean` | Whether currently within a pause period | | `InPausedPeriodFrom` | `string \| null` | Pause start date (business-local) | | `InPausedPeriodUntil` | `string \| null` | Pause end date (business-local) | #### Billing | Field | Type | Description | | ------------ | -------- | ----------------------------------- | | `BillingDay` | `number` | Day of month billing occurs | | `Quantity` | `number` | Number of units on this contract | | `Notes` | `string` | Contract notes | | `Desks` | `string` | Comma-separated assigned desk names | #### Nested Objects | Field | Type | Description | | ------------ | ---------------- | ------------------------------------------------ | | `IssuedBy` | `object` | Location that issued the contract | | `Coworker` | `object` | Customer the contract belongs to | | `Tariff` | `object` | Plan/tariff object (see plan-details for fields) | | `NextTariff` | `object \| null` | Next tariff after renewal (if changing) | | `Schedules` | `object[]` | Contract schedule entries | #### Timestamps (from base) | Field | Type | Description | | -------------- | ---------------- | --------------------------------------- | | `CreatedOn` | `string` | Date created (business-local time) | | `UpdatedOn` | `string \| null` | Date last updated (business-local time) | | `CreatedOnUtc` | `string` | Date created (UTC) | | `UpdatedOnUtc` | `string \| null` | Date last updated (UTC) | ## Examples ### Fetch my plans ```http theme={null} GET /api/public/plans/my Authorization: Bearer {token} ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' const response = await httpClient.get(endpoints.plans.my) ``` # Get Plan Details Source: https://learn.nexudus.com/api/endpoints/plans/plan-details GET /api/public/plans/{planId} Returns the full details for a specific plan (tariff). # Get Plan Details Returns the full configuration and pricing details for a specific plan. Used on the plan detail page to show features, pricing tiers, and included benefits. ## Authentication No authentication required for public plan details. ## Path Parameters Numeric identifier of the plan. Returned as `Id` from the published plans endpoint. ## Query Parameters Comma-separated list of field paths to include in the response. When provided, only the specified fields are returned — useful for reducing payload size. Supports nested paths using dot notation. Example: `_shape=Name,Price,Description,InvoiceEvery,TimePasses,ExtraServices`. ## Response Returns a `Tariff` object with full plan configuration. Unique identifier for the plan. Display name of the plan. Full plan description. May contain HTML. Base recurring price. ISO 4217 currency code. ## Examples ### Fetch plan details ```http theme={null} GET /api/public/plans/12 ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' const { resource: plan } = useTypedData(httpClient, endpoints.plans.one(12)) ``` # List Published Plans Source: https://learn.nexudus.com/api/endpoints/plans/published-plans GET /api/public/plans/published Returns all published plans available for sign-up, optionally filtered by invite code. # List Published Plans Returns all plans (tariffs) that are published and available for new customers to sign up for. Optionally accepts an invite GUID to show invite-only plans. ## Authentication No authentication required. ## Query Parameters Invite GUID to unlock private/invite-only plans. Omit to see only publicly listed plans. Comma-separated list of field paths to include in the response. When provided, only the specified fields are returned — useful for reducing payload size. Supports nested paths using dot notation. Example: `_shape=Plans.Name,Plans.Price,Plans.Description`. ## Response Returns an object with a `Plans` array. Each plan has the following fields: #### Identity | Field | Type | Description | | ---------- | -------- | ------------------------------ | | `Id` | `number` | Unique identifier for the plan | | `UniqueId` | `string` | GUID identifier | #### Core | Field | Type | Description | | -------------------- | --------- | ------------------------------------- | | `Name` | `string` | Display name of the plan | | `Description` | `string` | Plan description (may contain HTML) | | `TermsAndConditions` | `string` | Terms and conditions text | | `GroupName` | `string` | Plan group name for categorisation | | `SystemTariffType` | `number` | Internal tariff type identifier | | `IsVirtualOffice` | `boolean` | Whether this is a virtual office plan | #### Pricing | Field | Type | Description | | --------------------- | ---------- | ----------------------------- | | `Price` | `string` | Formatted price string | | `PriceFormatted` | `string` | Locale-formatted price string | | `PriceDecimal` | `number` | Price as decimal value | | `PriceDecimalExTax` | `number` | Price excluding tax | | `TotalPrice` | `string` | Total price string | | `TotalPriceFormatted` | `string` | Locale-formatted total price | | `TotalPriceDecimal` | `number` | Total price as decimal | | `Currency` | `Currency` | Currency object (nested) | | `TaxRate` | `number?` | Applicable tax rate | #### Billing | Field | Type | Description | | ---------------------------- | --------- | ----------------------------------------- | | `InvoiceEvery` | `number` | Invoice frequency | | `InvoiceEveryWeeks` | `number` | Invoice frequency in weeks | | `InvoicePeriod` | `number` | Invoice period | | `InvoiceInMonths` | `boolean` | Whether billing is in months | | `DefaultContractTerm` | `number?` | Default contract term length | | `DisablePortalCancellations` | `boolean` | Whether portal cancellations are disabled | | `CanBePaused` | `boolean` | Whether the plan can be paused | | `KeepNewAccountsOnHold` | `boolean` | Whether new accounts are kept on hold | #### Limits | Field | Type | Description | | ----------------------- | --------- | ----------------------------- | | `CheckinPricePlanLimit` | `number?` | Check-in limit per price plan | | `CheckinMonthLimit` | `number?` | Monthly check-in limit | | `CheckinWeekLimit` | `number?` | Weekly check-in limit | | `HoursPricePlanLimit` | `number?` | Hours limit per price plan | | `HoursMonthLimit` | `number?` | Monthly hours limit | | `HoursWeekLimit` | `number?` | Weekly hours limit | #### Discounts | Field | Type | Description | | ----------------------- | --------- | -------------------------- | | `DiscountCharges` | `number?` | Discount on charges | | `DiscountExtraServices` | `number?` | Discount on extra services | | `DiscountTimePasses` | `number?` | Discount on time passes | #### Virtual Office | Field | Type | Description | | ----------------------- | --------- | ------------------------- | | `MaximumAddresses` | `number?` | Maximum virtual addresses | | `MaximumCompanyAliases` | `number?` | Maximum company aliases | | `MaximumRecipients` | `number?` | Maximum mail recipients | #### Nested Objects | Field | Type | Description | | ---------------- | ----------------------- | -------------------------------- | | `TimePasses` | `TariffTimePass[]` | Time passes included in the plan | | `ExtraServices` | `TariffExtraService[]` | Extra services included | | `BookingCredits` | `TariffBookingCredit[]` | Booking credits included | | `SignupProducts` | `Product[]` | Products added at sign-up | | `Products` | `Product[]` | Products included with the plan | #### Business | Field | Type | Description | | -------------------- | -------- | -------------------- | | `BusinessId` | `number` | Business identifier | | `BusinessName` | `string` | Business name | | `BusinessWebAddress` | `string` | Business web address | #### Timestamps (from base) | Field | Type | Description | | -------------- | -------- | ------------------------------------ | | `CreatedOn` | `string` | Record creation timestamp (local) | | `UpdatedOn` | `string` | Record last-update timestamp (local) | | `CreatedOnUtc` | `string` | Record creation timestamp (UTC) | | `UpdatedOnUtc` | `string` | Record last-update timestamp (UTC) | ## Examples ### Fetch published plans ```http theme={null} GET /api/public/plans/published ``` ### Fetch with invite code ```http theme={null} GET /api/public/plans/published?invite_guid=abc123-def456 ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' const { resource: plans } = useTypedData(httpClient, endpoints.plans.published()) // plans.Plans ``` # List Store Products Source: https://learn.nexudus.com/api/endpoints/products/list-products GET /api/public/store/products Returns the list of products available in the store, with optional filtering by tag, type, and selected plans. # List Store Products Returns all products available in the ecommerce store for the current location. Supports filtering by tag, product type (time passes), and selected plans. ## Authentication No authentication required for public product listing. ## Query Parameters Customer profile ID to personalise available products. Defaults to `0`. Filter by product tag. URL-encoded. Filter to a specific product by ID. When `true`, returns only time-pass products. Array of plan IDs to filter products compatible with specific plans. Comma-separated list of field paths to include in the response. When provided, only the specified fields are returned — useful for reducing payload size. Supports nested paths using dot notation. Example: `_shape=Products.Name,Products.Price,Products.PriceFormatted`. ## Response Returns an object with a `Products` array. Each product has the following fields: #### Identity | Field | Type | Description | | ---------- | -------- | --------------------------------- | | `Id` | `number` | Unique identifier for the product | | `UniqueId` | `string` | GUID identifier | #### Core | Field | Type | Description | | ------------------- | --------- | ------------------------------------------- | | `Name` | `string` | Display name of the product | | `Description` | `string` | Product description (may contain HTML) | | `Tags` | `string` | Comma-separated tags | | `DisplayOrder` | `number` | Sort order for display | | `SystemProductType` | `number` | Internal product type identifier | | `Visible` | `boolean` | Whether the product is visible in the store | #### Pricing | Field | Type | Description | | --------------------- | ---------- | ----------------------------- | | `Price` | `number` | Price amount | | `PriceFormatted` | `string` | Locale-formatted price string | | `ProductCurrencyCode` | `string` | ISO currency code | | `Currency` | `Currency` | Currency object (nested) | | `TaxRate` | `number?` | Applicable tax rate | #### Billing | Field | Type | Description | | ----------------- | --------- | ---------------------------------- | | `Quantity` | `number` | Default quantity | | `RegularCharge` | `boolean` | Whether this is a recurring charge | | `AlwaysRecurrent` | `boolean` | Always billed as recurring | | `AlwaysOneOff` | `boolean` | Always billed as one-off | | `InvoiceCoworker` | `boolean` | Whether to invoice the coworker | #### Stock | Field | Type | Description | | -------------------- | --------- | --------------------------------- | | `TrackStock` | `boolean` | Whether stock tracking is enabled | | `CurrentStock` | `number?` | Current available stock | | `AllowNegativeStock` | `boolean` | Whether negative stock is allowed | #### Business | Field | Type | Description | | -------------------- | --------- | ---------------------------------------------- | | `BusinessId` | `number` | Business identifier | | `BusinessName` | `string` | Business name | | `BusinessWebAddress` | `string` | Business web address | | `HasTimePasses` | `boolean` | Whether the product has associated time passes | #### Timestamps (from base) | Field | Type | Description | | -------------- | -------- | ------------------------------------ | | `CreatedOn` | `string` | Record creation timestamp (local) | | `UpdatedOn` | `string` | Record last-update timestamp (local) | | `CreatedOnUtc` | `string` | Record creation timestamp (UTC) | | `UpdatedOnUtc` | `string` | Record last-update timestamp (UTC) | ## Examples ### Fetch all store products ```http theme={null} GET /api/public/store/products?profileId=0 ``` ### Fetch time passes only ```http theme={null} GET /api/public/store/products?profileId=0&onlyTimePasses=true ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' const { resource: store } = useTypedData( httpClient, endpoints.products.products({ profileId: 0, tag: 'day-pass', }), ) // store.Products ``` # List My Products Source: https://learn.nexudus.com/api/endpoints/products/my-products GET /api/public/products/my Returns the products purchased by the authenticated customer. # List My Products Returns all products that the authenticated customer has purchased or has active. Used on the customer's account page to show active memberships, passes, and add-on products. ## Authentication Requires a valid customer bearer token. ## Query Parameters Comma-separated list of field paths to include in the response. When provided, only the specified fields are returned — useful for reducing payload size. Supports nested paths using dot notation. Example: `_shape=Records.Product.Name,Records.Price,Records.Quantity`. ## Response Returns an array of `CoworkerProduct` objects with the following fields. ### CoworkerProduct Fields #### Identity | Field | Type | Description | | ---------- | -------- | -------------------------- | | `Id` | `number` | Unique numeric identifier | | `UniqueId` | `string` | Globally unique identifier | #### Pricing | Field | Type | Description | | ---------------- | -------- | ---------------------------------------- | | `Price` | `number` | Calculated price (including tax display) | | `PriceFormatted` | `string` | Price formatted with currency symbol | #### Billing | Field | Type | Description | | --------------- | ---------------- | ------------------------------------------ | | `RegularCharge` | `boolean` | Whether this is a recurring charge | | `RepeatCycle` | `string` | Billing cycle (e.g. `Monthly`, `Annually`) | | `RepeatUnit` | `number \| null` | Number of cycles between charges | | `Quantity` | `number` | Quantity purchased | | `InvoiceOn` | `string \| null` | Next invoice date | #### Product Details | Field | Type | Description | | --------- | -------- | ------------------------------------------------ | | `Product` | `object` | Nested product object (see Product Fields below) | ### Nested Product Fields | Field | Type | Description | | --------------------- | ---------------- | ------------------------------------------- | | `Id` | `number` | Product identifier | | `Name` | `string` | Product display name | | `Description` | `string` | Product description | | `Price` | `number` | Unit price (with tax display) | | `PriceFormatted` | `string` | Price formatted with currency symbol | | `Tags` | `string` | Comma-separated product tags | | `Visible` | `boolean` | Whether the product is visible in the store | | `DisplayOrder` | `number` | Sort order in listings | | `CurrentStock` | `number \| null` | Current stock level (if tracked) | | `TrackStock` | `boolean` | Whether stock tracking is enabled | | `AllowNegativeStock` | `boolean` | Whether negative stock is permitted | | `ProductCurrencyCode` | `string` | ISO 4217 currency code | | `SystemProductType` | `number` | Internal product type identifier | | `BusinessId` | `number` | Location identifier | | `BusinessName` | `string` | Location display name | | `BusinessWebAddress` | `string` | Location subdomain | #### Timestamps (from base) | Field | Type | Description | | -------------- | ---------------- | --------------------------------------- | | `CreatedOn` | `string` | Date created (business-local time) | | `UpdatedOn` | `string \| null` | Date last updated (business-local time) | | `CreatedOnUtc` | `string` | Date created (UTC) | | `UpdatedOnUtc` | `string \| null` | Date last updated (UTC) | ## Examples ### Fetch my products ```http theme={null} GET /api/public/products/my Authorization: Bearer {token} ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' const response = await httpClient.get(endpoints.products.my) ``` # Get Product Details Source: https://learn.nexudus.com/api/endpoints/products/product-details GET /api/public/store/products/{productId} Returns the full details for a single product in the store. # Get Product Details Returns the complete product information including pricing, description, and availability. Used on the product detail page and in the checkout flow. ## Authentication No authentication required for public product details. ## Path Parameters Numeric identifier of the product. Returned as `Id` from the products list. ## Query Parameters Comma-separated list of field paths to include in the response. When provided, only the specified fields are returned — useful for reducing payload size. Supports nested paths using dot notation. Example: `_shape=Name,Price,PriceFormatted,Description`. ## Response Returns a `Product` object. Unique identifier for the product. Display name of the product. Full product description. May contain HTML. Unit price. ISO 4217 currency code. ## Examples ### Fetch product details ```http theme={null} GET /api/public/store/products/33 ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' const { resource: product } = useTypedData(httpClient, endpoints.products.one(33)) ``` # Generate AI Profile Source: https://learn.nexudus.com/api/endpoints/profile/generate-ai-profile POST /en/profile/GenerateOpenAiProfile Generate an AI-written professional profile summary for the authenticated customer based on their existing profile data. # Generate AI Profile Uses OpenAI to generate a professional profile summary for the authenticated customer. The AI drafts the `ProfileSummary` text based on the customer's existing profile fields (name, position, company, tags, etc.). The portal presents the result for the customer to review and accept before saving it via `PATCH /api/public/coworker/profile`. This endpoint requires the location to have the OpenAI integration enabled. If it is not configured, the AI profile button will not appear in the portal UI. ## Authentication Requires a valid customer bearer token. ## Request Body No body is required. The AI uses the customer's existing profile data from the server session. ```http theme={null} POST /en/profile/GenerateOpenAiProfile Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9... ``` ## Response Returns a `Coworker` object with the `ProfileSummary` field populated with the AI-generated text. The customer's profile is **not** saved automatically — the customer must review and confirm, after which the portal calls `PATCH /api/public/coworker/profile` with `ProfileSummary`. The AI-generated professional profile summary. May contain Markdown formatting. Presented to the customer for review before saving. `true` when AI profile generation is available for this location. Use this to show or hide the "Generate with AI" button. ## Example Response ```json theme={null} { "ProfileSummary": "Jane is a product designer with over 8 years of experience building intuitive digital products for SaaS companies. Based at Nexudus Coworking, she specialises in design systems and user research.", "OpenAiProfileAvailable": true, "FullName": "Jane Doe", "Position": "Product Designer", "CompanyName": "Acme Design Co." } ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' import { Coworker } from '@/types/spaces/Coworker' const result = await httpClient.post(endpoints.profile.ai) if (result.data.ProfileSummary) { // Present the generated text to the customer for review setGeneratedSummary(result.data.ProfileSummary) } ``` ## Usage in Portal | Context | Source file | | ----------------------------------------------------- | --------------------------------------------------- | | Professional profile form — "Generate with AI" button | `src/views/user/components/ProfessionalProfile.tsx` | ## Error Responses The bearer token is missing, expired, or invalid. The location does not have the OpenAI integration enabled, or the customer's profile lacks sufficient data to generate a summary. ## Related Endpoints | Method | Endpoint | Description | | ------- | -------------------------------- | ---------------------------------------------------- | | `PATCH` | `/api/public/coworker/profile` | Save the reviewed AI summary to the customer profile | | `GET` | `/en/profile?_resource=Coworker` | Retrieve full customer profile data | # Update Profile Source: https://learn.nexudus.com/api/endpoints/profile/update-profile PATCH /api/public/coworker/profile Partially update the authenticated customer profile — personal info, billing details, notifications, credentials, or professional profile fields. # Update Profile Partially updates the authenticated customer's profile. The same endpoint is used across all profile editing pages in the portal — personal information, billing details, notification preferences, account credentials, and the professional (public-facing) profile. Send only the fields you want to change; omitted fields are left unchanged. ## Authentication Requires a valid customer bearer token. ## Request Body Send a JSON object containing only the fields to update. All fields are optional; omitting a field leaves the current value unchanged. ### Personal Information The customer's display name. Optional informal name displayed in some community contexts. Gender identifier. Used for salutation generation. ISO 8601 date of birth (e.g. `"1990-06-15"`). Mobile phone number in any format. Landline phone number. Street address. Postal or ZIP code. City name. State or region. Numeric country identifier. Obtain valid IDs from `GET /api/public/countries`. ### Billing Information Name to appear on invoices. Email address for invoice delivery. Billing street address. Billing postal code. Billing city. Billing state or region. Numeric country identifier for the billing address. VAT or tax identification number printed on invoices. ### Professional Profile Job title displayed on the public directory profile. Company name displayed on the public directory profile. Industry or area of work. Free-text professional bio. Supports Markdown. Displayed on the public directory profile when `ProfileIsPublic` is `true`. Personal or company website URL. When `true`, the customer's profile is listed in the member directory. Comma-separated skill or interest tags shown on the directory profile. ### Social Media Twitter profile URL or handle. LinkedIn profile URL. GitHub profile URL or username. Instagram profile URL or handle. Facebook profile URL. Skype username. Telegram username. ### Notification Preferences When `true`, the customer receives email notifications for new help desk replies. When `true`, the customer receives email notifications for new community board posts. When `true`, the customer receives email notifications for new article comments. When `true`, the customer receives email notifications for new event comments. When `true`, the customer receives a periodic community activity digest email. When `true`, the customer is opted in to the space's newsletter. ### Credentials The customer's current password. Required when changing the password. The new password to set. Must satisfy the location's password policy. Must match `NewPassword` exactly. Validated server-side. ## Response Returns an `ActionConfirmation` envelope. `true` when the profile was updated successfully. Usually `null` on success. HTTP-style status code mirrored in the body. `200` on success. Human-readable message. Usually `null` on success. Validation error object. `null` on success. Check this when `WasSuccessful` is `false`. ## Example Response ```json theme={null} { "WasSuccessful": true, "Value": null, "Status": 200, "Message": null, "Errors": null } ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' import { ActionConfirmation } from '@/types/ActionConfirmation' const result = await httpClient.patch(endpoints.profile.patch, { FullName: 'Jane Doe', Position: 'Product Designer', ProfileIsPublic: true, }) if (result.data.WasSuccessful) { // Refresh profile data and show success toast } ``` ## Usage in Portal | Context | Source file | | -------------------------------------- | -------------------------------------------- | | Personal information form (`/profile`) | `src/views/user/PersonalInformationPage.tsx` | | Professional profile form (`/profile`) | `src/views/user/ProfessionalProfilePage.tsx` | | Billing information form (`/profile`) | `src/views/user/BillingInformationPage.tsx` | | Notification preferences (`/profile`) | `src/views/user/NotificationsPage.tsx` | | Change password (`/profile`) | `src/views/user/CredentialsPage.tsx` | ## Error Responses The bearer token is missing, expired, or invalid. One or more fields failed validation (e.g. password mismatch, invalid `CountryId`). Check `Errors` in the response body. ## Related Endpoints | Method | Endpoint | Description | | ------ | ----------------------------------- | -------------------------------------------------------------- | | `GET` | `/login/me?` | Retrieve the current user session and notification preferences | | `GET` | `/en/profile?_resource=Coworker` | Retrieve the full customer profile for editing | | `GET` | `/api/public/coworkers/profiles` | List all customer profiles for the session | | `POST` | `/en/profile/GenerateOpenAiProfile` | Generate an AI-written professional profile summary | # Start E-Sign Source: https://learn.nexudus.com/api/endpoints/proposals/esign-start POST /api/public/proposals/{proposalId}/esign/start Initiates the electronic signature process for a proposal. # Start E-Sign Initiates the electronic signature flow for a proposal. Returns an object containing the signature request identifier that can be used to launch the e-sign UI. ## Authentication No authentication required — proposals are accessed via their unique identifier. ## Path Parameters The unique string identifier (GUID) of the proposal. ## Request Body No request body required. ## Response Signature request identifier. Name of the signature request. ## Examples ### Start e-sign ```http theme={null} POST /api/public/proposals/abc123-def456/esign/start ``` ```json theme={null} { "Id": 42, "Name": "Membership Agreement" } ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' const result = await httpClient.post(endpoints.proposals.esign.start('abc123-def456').url) ``` # Accept Proposal Source: https://learn.nexudus.com/api/endpoints/proposals/proposal-accept PUT /api/public/proposals/{proposalId}/accept Accepts a proposal on behalf of the recipient. # Accept Proposal Accepts the proposal, triggering any associated plan sign-ups, contract creation, and billing. This is the final step in the proposal flow after the recipient has reviewed and optionally e-signed the document. ## Authentication Requires prior proposal login authentication. ## Path Parameters The unique string identifier (GUID) of the proposal. ## Request Body No request body required. ## Response Returns the proposal file ID and an access token. The portal exchanges this token for a full auth session. The numeric identifier of the proposal file. A token exchanged for a full auth session via `exchangeToken()`. ## Examples ### Accept a proposal ```http theme={null} PUT /api/public/proposals/abc123-def456/accept Authorization: Bearer {token} ``` ```json theme={null} { "file": 42, "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." } ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' const result = await httpClient.put<{ file: number; accessToken: string }>(endpoints.proposals.accept('abc123-def456')) await exchangeToken(result.data.accessToken) ``` # Get Proposal Details Source: https://learn.nexudus.com/api/endpoints/proposals/proposal-details GET /api/public/proposals/{proposalId} Returns the full details of a proposal by its unique identifier. # Get Proposal Details Returns the full content and status of a specific proposal. Proposals are sent by operators to prospective or existing members and may include plan selections, terms, and pricing. ## Authentication No authentication required — proposals are accessed via their unique identifier. ## Path Parameters The unique string identifier (GUID) of the proposal. ## Query Parameters Comma-separated list of field paths to include in the response. When provided, only the specified fields are returned — useful for reducing payload size. Supports nested paths using dot notation. Example: `_shape=Tariff.Name,Price,Status,StartDate,Contracts,Products`. ## Response Returns a `ProposalData` object containing the proposal, associated invoices, and bill run information. ### Proposal The top-level `Proposal` object has the following fields: #### Identity | Field | Type | Description | | ----------- | -------- | ---------------------------------- | | `Id` | `number` | Unique identifier for the proposal | | `UniqueId` | `string` | GUID identifier | | `Reference` | `string` | Proposal reference code | #### Status | Field | Type | Description | | --------------- | --------- | ------------------------------------------- | | `Status` | `string` | Current proposal status | | `HasExpired` | `boolean` | Whether the proposal has expired | | `HasFile` | `boolean` | Whether a file is attached | | `HasFileToSend` | `boolean` | Whether there is a file to send | | `HasFileToSign` | `boolean` | Whether there is a file requiring signature | | `FileToSignId` | `number?` | File-to-sign identifier | #### Pricing | Field | Type | Description | | --------------------- | --------- | ------------------------------- | | `Price` | `number?` | Base price amount | | `PriceFormatted` | `string` | Locale-formatted price | | `TotalPrice` | `number` | Total price including all items | | `TotalPriceFormatted` | `string` | Locale-formatted total price | | `Quantity` | `number` | Quantity | | `ApplyProrating` | `boolean` | Whether prorating is applied | | `DoNotIssueInvoice` | `boolean` | Whether invoicing is suppressed | #### Dates | Field | Type | Description | | ------------------ | --------- | ------------------------ | | `StartDate` | `string?` | Contract start date | | `CancellationDate` | `string?` | Cancellation date | | `BillingDay` | `number` | Day of month for billing | #### Content | Field | Type | Description | | --------------------- | -------- | ------------------------- | | `Notes` | `string` | Proposal notes | | `DiscountDescription` | `string` | Discount description text | | `Desks` | `string` | Assigned desks | #### Nested Objects | Field | Type | Description | | ------------- | -------------------- | --------------------------------- | | `IssuedBy` | `Business` | Business that issued the proposal | | `Coworker` | `Coworker` | Coworker the proposal is for | | `Responsible` | `User` | User responsible for the proposal | | `Tariff` | `Tariff` | Associated plan/tariff | | `Contracts` | `ProposalContract[]` | Contract schedule items | | `Products` | `ProposalProduct[]` | Products included in the proposal | #### Timestamps (from base) | Field | Type | Description | | -------------- | -------- | ------------------------------------ | | `CreatedOn` | `string` | Record creation timestamp (local) | | `UpdatedOn` | `string` | Record last-update timestamp (local) | | `CreatedOnUtc` | `string` | Record creation timestamp (UTC) | | `UpdatedOnUtc` | `string` | Record last-update timestamp (UTC) | ### ProposalProduct Each item in the `Products` array has: | Field | Type | Description | | --------------------- | --------- | ---------------------------------- | | `Id` | `number` | Unique identifier | | `Product` | `Product` | Full product object (nested) | | `Price` | `number` | Price amount | | `PriceFormatted` | `string` | Locale-formatted price | | `TotalPrice` | `number?` | Total price | | `TotalPriceFormatted` | `string` | Locale-formatted total price | | `Quantity` | `number` | Quantity | | `RegularCharge` | `boolean` | Whether this is a recurring charge | | `IsContractProduct` | `boolean` | Whether tied to a contract | | `RepeatCycle` | `string` | Repeat cycle description | | `RepeatUnit` | `number?` | Repeat unit | | `InvoiceOn` | `string?` | Next invoice date | | `RepeatFrom` | `string?` | Repeat start date | | `RepeatUntil` | `string?` | Repeat end date | ### Invoices `Invoices` is an array of invoice preview objects associated with the proposal. ### BillRun Each item in the `BillRun` array has: | Field | Type | Description | | -------------------- | --------- | ------------------------ | | `FullName` | `string` | Customer full name | | `FloorPlanDeskNames` | `string` | Assigned desk names | | `PurchaseOrder` | `string` | Purchase order reference | | `ItemId` | `number` | Item identifier | | `Type` | `string` | Charge type | | `Date` | `string` | Charge date | | `PeriodStart` | `string` | Billing period start | | `PeriodEnd` | `string` | Billing period end | | `Description` | `string` | Charge description | | `Total` | `number` | Charge total | | `TeamNames` | `string` | Associated team names | | `PayingMemberId` | `number?` | Paying member identifier | ## Examples ### Fetch proposal details ```http theme={null} GET /api/public/proposals/abc123-def456 ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' import { ProposalData } from '@/types/public/billing/Proposal' const { resource: proposalData } = useTypedData(httpClient, endpoints.proposals.one('abc123-def456')) // Access: proposalData.Proposal, proposalData.Invoices, proposalData.BillRun ``` # Proposal Login Source: https://learn.nexudus.com/api/endpoints/proposals/proposal-login PUT /api/public/proposals/{proposalId}/login Authenticates a user to view and interact with a proposal. # Proposal Login Authenticates a user to access a specific proposal. Used when proposals require email verification before the recipient can view or accept them. ## Authentication No prior authentication required. ## Path Parameters The unique string identifier (GUID) of the proposal. ## Request Body Email address of the proposal recipient for verification. ## Response Returns the proposal file ID and an access token for subsequent proposal interactions. The numeric identifier of the proposal file. A token used to authenticate further proposal actions (e.g. accepting the proposal). Exchanged for a full auth session via `exchangeToken()`. ## Examples ### Login to view a proposal ```http theme={null} PUT /api/public/proposals/abc123-def456/login Content-Type: application/json { "Email": "member@example.com" } ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' await httpClient.put(endpoints.proposals.login('abc123-def456'), { Email: 'member@example.com', }) ``` # Resource Details List Source: https://learn.nexudus.com/api/endpoints/resources/resource-details GET /api/public/resources/published/details Returns detailed information for all published resources. # Resource Details List Returns full details for all published resources at the current location, including configuration, pricing, and availability metadata. Used to render the resources catalogue. ## Authentication No authentication required. ## Query Parameters Comma-separated list of field paths to include in the response. When provided, only the specified fields are returned — useful for reducing payload size. Supports nested paths using dot notation. Example: `_shape=Name,ResourceTypeName,Capacity,Visible`. ## Response Returns a `PublicResources` object containing an array of resource records with full detail. ### Resource Fields #### Identity | Field | Type | Description | | ---------- | -------- | ------------------------------------------ | | `Id` | `number` | Unique numeric identifier for the resource | | `UniqueId` | `string` | Globally unique identifier | #### Core | Field | Type | Description | | -------------------- | --------- | ---------------------------------------- | | `Name` | `string` | Resource display name (localised) | | `Description` | `string` | Resource description (localised) | | `GroupName` | `string` | Resource group name | | `ResourceTypeName` | `string` | Resource type display name (localised) | | `Visible` | `boolean` | Whether the resource is publicly visible | | `DisplayOrder` | `number` | Sort order in listings | | `SystemResourceType` | `number` | Internal resource type identifier | #### Location | Field | Type | Description | | -------------------- | ---------------- | --------------------- | | `BusinessId` | `number` | Location identifier | | `BusinessName` | `string` | Location display name | | `BusinessWebAddress` | `string` | Location subdomain | | `Longitude` | `number \| null` | Longitude coordinate | | `Latitude` | `number \| null` | Latitude coordinate | #### Capacity & Booking Rules | Field | Type | Description | | ---------------------------------- | ---------------- | ---------------------------------------------- | | `Allocation` | `number \| null` | Maximum concurrent bookings | | `AllowMultipleBookings` | `boolean` | Whether multiple bookings are allowed | | `RequiresConfirmation` | `boolean` | Whether bookings require admin confirmation | | `BookInAdvanceLimit` | `number \| null` | Max days in advance a booking can be made | | `LateBookingLimit` | `number \| null` | Min hours before a booking can start | | `LateCancellationLimit` | `number \| null` | Min hours before booking for free cancellation | | `IntervalLimit` | `number \| null` | Required gap between bookings (minutes) | | `MaxBookingLength` | `number \| null` | Maximum booking duration (minutes) | | `MinBookingLength` | `number \| null` | Minimum booking duration (minutes) | | `NoReturnPolicy` | `number \| null` | Hours before same resource can be rebooked | | `NoReturnPolicyAllResources` | `number \| null` | Hours before any resource can be rebooked | | `NoReturnPolicyAllUsers` | `number \| null` | Hours before any user can rebook | | `RepeatBookingQuantityLimit` | `number \| null` | Max quantity for repeat bookings | | `RepeatBookingPeriodLimitInMonths` | `number \| null` | Max period for repeat bookings (months) | #### Amenities | Field | Type | Description | | ---------------------- | --------- | ------------------------- | | `Projector` | `boolean` | Has projector | | `Internet` | `boolean` | Has internet | | `ConferencePhone` | `boolean` | Has conference phone | | `StandardPhone` | `boolean` | Has standard phone | | `WhiteBoard` | `boolean` | Has whiteboard | | `LargeDisplay` | `boolean` | Has large display | | `Catering` | `boolean` | Has catering | | `TeaAndCoffee` | `boolean` | Has tea and coffee | | `Drinks` | `boolean` | Has drinks | | `SecurityLock` | `boolean` | Has security lock | | `CCTV` | `boolean` | Has CCTV | | `VoiceRecorder` | `boolean` | Has voice recorder | | `AirConditioning` | `boolean` | Has air conditioning | | `Heating` | `boolean` | Has heating | | `NaturalLight` | `boolean` | Has natural light | | `StandingDesk` | `boolean` | Has standing desk | | `QuietZone` | `boolean` | Is in a quiet zone | | `WirelessCharger` | `boolean` | Has wireless charger | | `PrivacyScreen` | `boolean` | Has privacy screen | | `VideoConferencing` | `boolean` | Has video conferencing | | `DualDisplayScreen` | `boolean` | Has dual display screens | | `DisplayScreen` | `boolean` | Has display screen | | `WirelessPresentation` | `boolean` | Has wireless presentation | | `PaSystem` | `boolean` | Has PA system | | `DesktopMonitor` | `boolean` | Has desktop monitor | | `FlipChart` | `boolean` | Has flip chart | | `SecureStorage` | `boolean` | Has secure storage | | `Soundproof` | `boolean` | Is soundproofed | #### Media & Floor Plan | Field | Type | Description | | ---------------- | ---------------- | ----------------------------------- | | `HasImage` | `boolean` | Whether the resource has an image | | `FloorPlanDesks` | `object[]` | Available floor plan desk positions | | `FloorPlanId` | `number \| null` | Floor plan identifier | #### Availability (computed) | Field | Type | Description | | ---------------- | --------- | ----------------------------- | | `IsAvailable` | `boolean` | Whether currently available | | `AvailableUnits` | `number` | Number of available units | | `Price` | `number` | Computed booking price | | `PriceFormatted` | `string` | Price formatted with currency | | `Message` | `string` | Availability message | | `ErrorCode` | `string` | Error code if unavailable | #### Timestamps (from base) | Field | Type | Description | | -------------- | ---------------- | --------------------------------------- | | `CreatedOn` | `string` | Date created (business-local time) | | `UpdatedOn` | `string \| null` | Date last updated (business-local time) | | `CreatedOnUtc` | `string` | Date created (UTC) | | `UpdatedOnUtc` | `string \| null` | Date last updated (UTC) | ## Examples ### Fetch resource details ```http theme={null} GET /api/public/resources/published/details ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' const { resource: resources } = useTypedData(httpClient, endpoints.resources.details()) ``` # Get Resource Source: https://learn.nexudus.com/api/endpoints/resources/resource-one GET /api/public/resources/published/{resourceId} Returns the full details for a single published resource. # Get Resource Returns the complete details for a single published resource, including configuration, pricing, images, and custom fields. ## Authentication No authentication required. ## Path Parameters Numeric identifier of the resource. ## Query Parameters Comma-separated list of field paths to include in the response. When provided, only the specified fields are returned — useful for reducing payload size. Supports nested paths using dot notation. Example: `_shape=Name,Description,ResourceTypeName,Price,PriceFormatted,Allocation`. ## Response Returns a `Resource` object with the full resource configuration. See [Resource Details](/api/endpoints/resources/resource-details) for the complete field reference. #### Identity | Field | Type | Description | | ------------- | -------- | -------------------------------------------- | | `Id` | `number` | Unique identifier for the resource | | `UniqueId` | `string` | GUID identifier | | `Name` | `string` | Display name of the resource | | `Description` | `string` | Full resource description (may contain HTML) | #### Core | Field | Type | Description | | -------------------- | -------------- | --------------------------------- | | `ResourceTypeName` | `string` | Resource type name | | `ResourceType` | `ResourceType` | Resource type object (nested) | | `GroupName` | `string` | Group name for categorisation | | `SystemResourceType` | `number` | Internal resource type identifier | | `Visible` | `boolean` | Whether the resource is visible | | `DisplayOrder` | `number` | Sort order for display | | `HasImage` | `boolean` | Whether the resource has an image | | `Message` | `string` | Custom message for the resource | #### Location | Field | Type | Description | | -------------------- | --------- | -------------------- | | `BusinessId` | `number` | Business identifier | | `BusinessName` | `string` | Business name | | `BusinessWebAddress` | `string` | Business web address | | `Longitude` | `number?` | GPS longitude | | `Latitude` | `number?` | GPS latitude | #### Pricing | Field | Type | Description | | ---------------- | -------- | ---------------------- | | `Price` | `number` | Base price | | `PriceFormatted` | `string` | Locale-formatted price | #### Capacity & Booking Rules | Field | Type | Description | | ---------------------------------- | --------- | --------------------------------------- | | `Allocation` | `number?` | Maximum capacity | | `AllowMultipleBookings` | `boolean` | Whether multiple bookings are allowed | | `RequiresConfirmation` | `boolean` | Whether bookings require confirmation | | `BookInAdvanceLimit` | `number?` | How far in advance bookings can be made | | `LateBookingLimit` | `number?` | Latest a booking can be made | | `LateCancellationLimit` | `number?` | Cancellation deadline | | `IntervalLimit` | `number?` | Minimum interval between bookings | | `MaxBookingLength` | `number?` | Maximum booking duration | | `MinBookingLength` | `number?` | Minimum booking duration | | `NoReturnPolicy` | `number?` | No-return policy value | | `RepeatBookingQuantityLimit` | `number?` | Repeat booking quantity limit | | `RepeatBookingPeriodLimitInMonths` | `number?` | Repeat booking period limit | #### Amenities | Field | Type | Description | | ---------------------- | --------- | ------------------------- | | `Projector` | `boolean` | Has projector | | `Internet` | `boolean` | Has internet | | `ConferencePhone` | `boolean` | Has conference phone | | `StandardPhone` | `boolean` | Has standard phone | | `WhiteBoard` | `boolean` | Has whiteboard | | `LargeDisplay` | `boolean` | Has large display | | `Catering` | `boolean` | Catering available | | `TeaAndCoffee` | `boolean` | Tea and coffee available | | `Drinks` | `boolean` | Drinks available | | `SecurityLock` | `boolean` | Has security lock | | `CCTV` | `boolean` | Has CCTV | | `VoiceRecorder` | `boolean` | Has voice recorder | | `AirConditioning` | `boolean` | Has air conditioning | | `Heating` | `boolean` | Has heating | | `NaturalLight` | `boolean` | Has natural light | | `StandingDesk` | `boolean` | Has standing desk | | `QuietZone` | `boolean` | Is a quiet zone | | `WirelessCharger` | `boolean` | Has wireless charger | | `PrivacyScreen` | `boolean` | Has privacy screen | | `VideoConferencing` | `boolean` | Has video conferencing | | `DualDisplayScreen` | `boolean` | Has dual display screen | | `DisplayScreen` | `boolean` | Has display screen | | `WirelessPresentation` | `boolean` | Has wireless presentation | | `PaSystem` | `boolean` | Has PA system | | `DesktopMonitor` | `boolean` | Has desktop monitor | | `FlipChart` | `boolean` | Has flip chart | | `SecureStorage` | `boolean` | Has secure storage | | `Soundproof` | `boolean` | Is soundproof | #### Availability | Field | Type | Description | | ------------------ | --------- | ------------------------------------------- | | `IsAvailable` | `boolean` | Whether the resource is currently available | | `AvailableUnits` | `number` | Number of available units | | `Shifts` | `Shift[]` | Available shift definitions | | `ShiftsExpression` | `string` | Shift schedule expression | | `LastCleanedAt` | `string?` | When the resource was last cleaned | #### Floor Plan | Field | Type | Description | | ---------------- | ----------------- | ----------------------- | | `FloorPlanDesks` | `FloorPlanDesk[]` | Floor plan desk objects | | `FloorPlanId` | `number?` | Floor plan identifier | | `CustomFields` | `CustomField[]` | Custom field values | #### Timestamps (from base) | Field | Type | Description | | -------------- | -------- | ------------------------------------ | | `CreatedOn` | `string` | Record creation timestamp (local) | | `UpdatedOn` | `string` | Record last-update timestamp (local) | | `CreatedOnUtc` | `string` | Record creation timestamp (UTC) | | `UpdatedOnUtc` | `string` | Record last-update timestamp (UTC) | ## Examples ### Fetch a resource ```http theme={null} GET /api/public/resources/published/88 ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' const { resource: res } = useTypedData(httpClient, endpoints.resources.one(88)) ``` # Resource Search Fields Source: https://learn.nexudus.com/api/endpoints/resources/resource-search-fields GET /api/public/resources/fields/searchable Returns the custom fields available for filtering resources. # Resource Search Fields Returns the list of custom fields that the operator has made searchable for resources. Used to build dynamic filter UIs on the booking/resource pages. ## Authentication No authentication required. ## Response Array of searchable custom field definitions. ## Examples ### Fetch searchable fields ```http theme={null} GET /api/public/resources/fields/searchable ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' const { resource: fields } = useTypedData(httpClient, endpoints.resources.searchFields()) ``` # Resource Summary Source: https://learn.nexudus.com/api/endpoints/resources/resource-summary GET /api/public/resources/published/summary Returns a summary list of all published resources. # Resource Summary Returns a lightweight summary of all published resources (desks, meeting rooms, offices, etc.) for the current location. Used for resource selectors and quick listings where full detail is not needed. ## Authentication No authentication required. ## Query Parameters Comma-separated list of field paths to include in the response. When provided, only the specified fields are returned — useful for reducing payload size. Supports nested paths using dot notation. Example: `_shape=Name,ResourceTypeName,Id`. ## Response Returns a `ResourceSummaries` object containing a lightweight summary of each published resource. ### Resource Summary Fields #### Identity | Field | Type | Description | | ---------- | -------- | ------------------------------------------ | | `Id` | `number` | Unique numeric identifier for the resource | | `UniqueId` | `string` | Globally unique identifier | #### Core | Field | Type | Description | | ------------------ | --------- | ---------------------------------------- | | `Name` | `string` | Resource display name (localised) | | `Description` | `string` | Resource description (localised) | | `GroupName` | `string` | Resource group name | | `ResourceTypeName` | `string` | Resource type display name (localised) | | `Visible` | `boolean` | Whether the resource is publicly visible | | `DisplayOrder` | `number` | Sort order in listings | #### Location | Field | Type | Description | | -------------------- | -------- | --------------------- | | `BusinessId` | `number` | Location identifier | | `BusinessName` | `string` | Location display name | | `BusinessWebAddress` | `string` | Location subdomain | #### Media | Field | Type | Description | | ---------- | --------- | --------------------------------- | | `HasImage` | `boolean` | Whether the resource has an image | #### Timestamps (from base) | Field | Type | Description | | -------------- | ---------------- | --------------------------------------- | | `CreatedOn` | `string` | Date created (business-local time) | | `UpdatedOn` | `string \| null` | Date last updated (business-local time) | | `CreatedOnUtc` | `string` | Date created (UTC) | | `UpdatedOnUtc` | `string \| null` | Date last updated (UTC) | ## Examples ### Fetch resource summaries ```http theme={null} GET /api/public/resources/published/summary ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' const { resource: summaries } = useTypedData(httpClient, endpoints.resources.summary()) ``` # List Sensors Source: https://learn.nexudus.com/api/endpoints/sensors/list-sensors GET /api/public/sensors Returns the sensor data for the current location. # List Sensors Returns the list of IoT sensors and their current readings for the current location. Used to display environmental data (temperature, humidity, occupancy) on the dashboard. ## Authentication Requires a valid customer bearer token. ## Response Returns an array of sensor objects with current readings. ## Examples ### Fetch sensor data ```http theme={null} GET /api/public/sensors Authorization: Bearer {token} ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' const response = await httpClient.get(endpoints.sensors.list) ``` # Get Multiple Settings Source: https://learn.nexudus.com/api/endpoints/settings/get-many-settings GET /api/public/settings/values/{names} Returns multiple portal settings by comma-separated names. # Get Multiple Settings Returns multiple portal configuration settings in a single request. Setting names are provided as a comma-separated list. ## Authentication Requires a valid customer bearer token. ## Path Parameters Comma-separated setting names. URL-encoded. ## Response Array of requested settings. Setting name/key. Setting value. ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' const { resource: settings } = useTypedData(httpClient, endpoints.settings.getMany(['BookingMinDuration', 'BookingMaxDuration'])) ``` # Get Setting Source: https://learn.nexudus.com/api/endpoints/settings/get-setting GET /api/public/settings/value/{name} Returns a single portal setting by name. # Get Setting Returns the value of a specific portal configuration setting. ## Authentication Requires a valid customer bearer token. ## Path Parameters The setting name/key. URL-encoded. ## Response Setting name/key. Setting value. ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' const { resource: setting } = useTypedData(httpClient, endpoints.settings.get('BookingMinDuration')) ``` # Search Settings Source: https://learn.nexudus.com/api/endpoints/settings/search-settings GET /api/public/settings/search Searches portal settings by keyword. # Search Settings Searches the portal configuration settings by keyword. Returns matching setting name/value pairs. ## Authentication Requires a valid customer bearer token. ## Query Parameters Keyword to search for in setting names. URL-encoded. ## Response Array of matching settings. Setting name/key. Setting value. ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' const { resource: results } = useTypedData(httpClient, endpoints.settings.search('booking')) ``` # Update Multiple Settings Source: https://learn.nexudus.com/api/endpoints/settings/update-many-settings PUT /api/public/settings/values/{coworkerId} Updates multiple portal settings at once for a specific customer. # Update Multiple Settings Updates multiple portal configuration settings in a single request for a specific customer. ## Authentication Requires a valid customer bearer token. ## Path Parameters Numeric identifier of the customer to update settings for. ## Request Body Array or object of setting name/value pairs to update. ## Response Returns a `200 OK` on success. ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' await httpClient.put(endpoints.settings.setMany(42), settingsData) ``` # Update Setting Source: https://learn.nexudus.com/api/endpoints/settings/update-setting POST /api/public/settings/value/{name} Updates a single portal setting value. # Update Setting Updates the value of a specific portal configuration setting for the authenticated customer's context. ## Authentication Requires a valid customer bearer token. ## Path Parameters The setting name/key to update. URL-encoded. ## Request Body The new value for the setting. ## Response Returns a `200 OK` on success. ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' await httpClient.post(endpoints.settings.set('PreferredLanguage'), { Value: 'en', }) ``` # Get Business Colors Source: https://learn.nexudus.com/api/endpoints/system/business-colors GET /api/sys/businesses/{businessId}/colors Retrieve the custom brand color palette configured for a specific Nexudus location. # Get Business Colors Returns a key-value map of colour tokens configured for a specific location. The portal uses these values to apply the operator's brand palette at runtime, overriding the default theme. Colours are stored as CSS-compatible hex or RGB strings. ## Authentication Requires a valid customer bearer token. ## Path Parameters The numeric identifier of the location whose colour palette you want to retrieve. ## Response Returns a flat `Record` object where each key is a colour token name and each value is a CSS colour string. ```json theme={null} { "primaryColor": "#ff5100", "secondaryColor": "#001279", "backgroundColor": "#F9FAFB", "textColor": "#111827" } ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' import { useTypedData } from '@/api/fetchData' const endpoint = endpoints.system.colors(businessId) // endpoint.type is Record const { resource: colors } = useTypedData(httpClient, endpoint) ``` ## Usage in Portal | Context | Source file | | ----------------------------------- | ------------------------------------------ | | Location branding / theme injection | `src/states/useLocationByRouteContext.tsx` | ## Error Responses The bearer token is missing, expired, or invalid. No location with the given `businessId` was found. ## Related Endpoints | Method | Endpoint | Description | | ------ | -------------------------------- | ------------------------------------ | | `GET` | `/api/public/businesses/current` | Get the current location details | | `GET` | `/api/public/configuration` | Get portal configuration for a space | # Get Current Business Source: https://learn.nexudus.com/api/endpoints/system/business-current GET /api/public/businesses/current Retrieve the full profile and configuration for the Nexudus location associated with the current portal session. # Get Current Business Returns the full details of the Nexudus location (business) that the current portal session is operating under. This is the primary bootstrap call the portal makes when the application loads. The response drives theming, feature flags, localisation, and all location-specific configuration. ## Authentication Requires a valid customer bearer token, or can return public data for unauthenticated sessions depending on location configuration. ## Query Parameters Comma-separated list of field paths to include in the response. When provided, only the specified fields are returned — useful for reducing payload size. Supports nested paths using dot notation. Example: `_shape=Name,WebAddress,Currency.Code,TimeZone`. ## Response Returns a `Business` object. Key fields are described below. ### Identity Unique numeric identifier for the location. Globally unique identifier (GUID) for the location. Used in floor plan and booking requests. Display name of the coworking space. The subdomain identifier used in API requests (e.g. `"myspace"` in `myspace.spaces.nexudus.com`). ### Localisation Currency object for the location. ISO 4217 currency code (e.g. `"GBP"`, `"USD"`, `"EUR"`). Display name of the currency (e.g. `"British Pound"`). Currency format string. Default BCP 47 culture string for the location (e.g. `"en-GB"`). IANA time zone identifier for the location (e.g. `"Europe/London"`). ### Contact Street address of the location. City or town where the location is based. Postal code of the location. Country object with `Id`, `Name`, and `TwoDigitsCode` fields. ### Portal URLs Base URL of the Nexudus backend for this location (used to build authenticated redirects). Base URL including the default language prefix (e.g. `/en`). Used for authenticated redirect links. ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' import { useData } from '@/api/fetchData' import { Business } from '@/types/Business' const { resource: business } = useData(httpClient, endpoints.system.business.current) ``` ## Usage in Portal | Context | Source file | | ----------------------------------------- | ------------------------------------------ | | Location context provider (app bootstrap) | `src/states/useLocationByRouteContext.tsx` | | Business details throughout the portal | `src/states/useLocationByHostContext.tsx` | ## Error Responses Authentication is required and no valid token was supplied. No location could be resolved for the current session context. ## Related Endpoints | Method | Endpoint | Description | | ------ | ------------------------------------- | --------------------------------------------- | | `GET` | `/api/public/configuration` | Get portal feature configuration | | `GET` | `/api/public/businesses/all` | List all locations in the network | | `GET` | `/api/public/businesses/withVisitors` | List locations that have visitor registration | | `GET` | `/api/public/businesses/withTour` | List locations that offer space tours | # List All Businesses Source: https://learn.nexudus.com/api/endpoints/system/business-list GET /api/public/businesses/all Retrieve all Nexudus locations in the network, with options to include the root organisation and hidden locations. # List All Businesses Returns all locations (businesses) within the Nexudus network, optionally including the root organisation entry and locations that have been hidden from public views. Used by multi-location portals to build location pickers and network-wide navigation. ## Authentication Requires a valid customer bearer token. ## Query Parameters When `true`, the root organisation entry is included in the response alongside individual locations. When `true`, locations that have been marked as hidden (not publicly listed) are included in the results. Comma-separated list of field paths to include in the response. When provided, only the specified fields are returned — useful for reducing payload size. Supports nested paths using dot notation. Example: `_shape=Name,WebAddress,Address,TownCity`. ## Response Returns an array of location objects. Each entry follows the same shape as the `GET /api/public/businesses/current` response. ### Business Fields #### Identity | Field | Type | Description | | ---------- | -------- | ------------------------------------------ | | `Id` | `number` | Unique numeric identifier for the location | | `UniqueId` | `string` | Globally unique identifier | #### Core | Field | Type | Description | | ------------------- | -------- | --------------------------------------- | | `Name` | `string` | Display name of the coworking space | | `WebAddress` | `string` | Subdomain identifier (e.g. `"myspace"`) | | `Address` | `string` | Street address | | `TownCity` | `string` | Town or city | | `State` | `string` | State or province | | `Phone` | `string` | Phone number | | `Fax` | `string` | Fax number | | `EmailContact` | `string` | Contact email address | | `WebContact` | `string` | Contact website URL | | `Quote` | `string` | Location tagline / quote | | `AboutUs` | `string` | About Us text | | `ShortIntroduction` | `string` | Short intro text | #### Localisation | Field | Type | Description | | ---------------- | -------- | ---------------------------------------------- | | `Country` | `object` | Country object (`Id`, `Name`, `TwoDigitsCode`) | | `Currency` | `object` | Currency object (`Code`, `Name`, `Format`) | | `SimpleTimeZone` | `object` | Timezone object | #### Location | Field | Type | Description | | ----------- | ---------------- | -------------------- | | `Longitude` | `number \| null` | Longitude coordinate | | `Latitude` | `number \| null` | Latitude coordinate | #### Branding | Field | Type | Description | | ------------------ | --------- | ----------------------------- | | `HasLogo` | `boolean` | Whether location has a logo | | `HasBanner` | `boolean` | Whether location has a banner | | `CurrentThemeName` | `string` | Active theme name | #### Policies | Field | Type | Description | | -------------------- | -------- | -------------------- | | `CookiePolicyUrl` | `string` | Cookie policy URL | | `PrivacyPolicyUrl` | `string` | Privacy policy URL | | `TermsAndConditions` | `string` | Terms and conditions | #### Network | Field | Type | Description | | ----------------- | ---------------- | -------------------------------- | | `IsChildLocation` | `boolean` | Whether this is a child location | | `RootBusinessId` | `number \| null` | Parent location identifier | | `Businesses` | `object[]` | Child locations (if any) | #### Timestamps (from base) | Field | Type | Description | | -------------- | ---------------- | --------------------------------------- | | `CreatedOn` | `string` | Date created (business-local time) | | `UpdatedOn` | `string \| null` | Date last updated (business-local time) | | `CreatedOnUtc` | `string` | Date created (UTC) | | `UpdatedOnUtc` | `string \| null` | Date last updated (UTC) | ```` ## TypeScript Integration ```typescript import endpoints from '@/api/endpoints' const url = endpoints.system.business.businesses(false, false) // => '/api/public/businesses/all?includeRoot=false&includeHidden=false' const response = await httpClient.get(url) ```` ## Usage in Portal | Context | Source file | | ---------------------------------------- | ---------------------------------- | | Multi-location switcher / network picker | `src/components/LocationSwitcher/` | | Passport / map view | `src/views/passport/` | ## Error Responses The bearer token is missing, expired, or invalid. ## Related Endpoints | Method | Endpoint | Description | | ------ | ------------------------------------- | ----------------------------------------------- | | `GET` | `/api/public/businesses/current` | Get the current location | | `GET` | `/api/public/businesses/withVisitors` | Get locations with visitor registration enabled | | `GET` | `/api/public/businesses/withTour` | Get locations that offer space tours | # List Businesses with Tour Source: https://learn.nexudus.com/api/endpoints/system/business-with-tour GET /api/public/businesses/withTour Retrieve all Nexudus locations that have the space tour booking feature enabled. # List Businesses with Tour Returns all locations in the network where the space tour feature is active. The portal uses this to determine which locations a prospective member can book a tour at, and to build location pickers in the tour booking flow. ## Authentication Requires a valid customer bearer token. ## Query Parameters Comma-separated list of field paths to include in the response. When provided, only the specified fields are returned — useful for reducing payload size. Supports nested paths using dot notation. Example: `_shape=Businesses.Name,Businesses.WebAddress`. ## Response Array of location objects for locations that have the tour feature enabled. Unique numeric identifier for the location. Globally unique identifier (GUID) for the location. Display name of the location. Subdomain identifier for the location (e.g. `"myspace"`). ## Example Response ```json theme={null} { "Businesses": [ { "Id": 1, "UniqueId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "Name": "Main Location", "WebAddress": "mainlocation" } ] } ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' import { useTypedData } from '@/api/fetchData' import { AllLocations } from '@/types/AllLocations' const endpoint = endpoints.system.business.withTour() // endpoint.type is { Businesses: AllLocations[] } const { resource } = useTypedData(httpClient, endpoint) const tourLocations = resource?.Businesses ?? [] ``` ## Usage in Portal | Context | Source file | | ---------------------------------- | ----------------------------------- | | Space tour booking location picker | `src/views/tours/` or checkout flow | ## Error Responses The bearer token is missing, expired, or invalid. ## Related Endpoints | Method | Endpoint | Description | | ------ | ------------------------------------- | ---------------------------------------- | | `GET` | `/api/public/businesses/current` | Get the current location | | `GET` | `/api/public/businesses/all` | List all locations in the network | | `GET` | `/api/public/businesses/withVisitors` | List locations with visitor registration | # List Businesses with Visitor Registration Source: https://learn.nexudus.com/api/endpoints/system/business-with-visitors GET /api/public/businesses/withVisitors Retrieve all Nexudus locations that have the visitor registration feature enabled. # List Businesses with Visitor Registration Returns all locations in the network where the visitor registration feature is active. The portal uses this to determine which locations a member can register a visitor for, and to build location pickers in the visitor registration flow. ## Authentication Requires a valid customer bearer token. ## Query Parameters Comma-separated list of field paths to include in the response. When provided, only the specified fields are returned — useful for reducing payload size. Supports nested paths using dot notation. Example: `_shape=Businesses.Name,Businesses.WebAddress`. ## Response Array of location objects for locations that have visitor registration enabled. Unique numeric identifier for the location. Globally unique identifier (GUID) for the location. Display name of the location. Subdomain identifier for the location (e.g. `"myspace"`). ## Example Response ```json theme={null} { "Businesses": [ { "Id": 1, "UniqueId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "Name": "Main Location", "WebAddress": "mainlocation" } ] } ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' import { useTypedData } from '@/api/fetchData' import { AllLocations } from '@/types/AllLocations' const endpoint = endpoints.system.business.withVisitors() // endpoint.type is { Businesses: AllLocations[] } const { resource } = useTypedData(httpClient, endpoint) const businesses = resource?.Businesses ?? [] ``` ## Usage in Portal | Context | Source file | | ------------------------------------ | --------------------- | | Visitor registration location picker | `src/views/visitors/` | ## Error Responses The bearer token is missing, expired, or invalid. ## Related Endpoints | Method | Endpoint | Description | | ------ | --------------------------------- | ----------------------------------------------- | | `GET` | `/api/public/businesses/current` | Get the current location | | `GET` | `/api/public/businesses/all` | List all locations in the network | | `GET` | `/api/public/businesses/withTour` | List locations offering space tours | | `GET` | `api/public/visitors/my` | List the current customer's registered visitors | # Complete Password Reset Source: https://learn.nexudus.com/api/endpoints/system/complete-password-reset POST /api/sys/users/completePasswordReset Set a new password for a customer account using the token received in the password-reset email. # Complete Password Reset Validates the one-time reset token sent to the customer's email and sets the new password. On success, Nexudus returns a JWT that the portal immediately exchanges for a bearer token, signing the customer in automatically without an extra login step. ## Authentication No authentication required. The `token` in the request body acts as the credential. ## Request Body The one-time reset token extracted from the password-reset link sent to the customer's email. This token is single-use and expires after a short period. The new password the customer wants to set. Must satisfy the location's password policy. The numeric ID of the business/location. Obtained from the current location context. ## Response Returns an `ActionConfirmation` envelope. On success, `Value` contains a JWT that can be exchanged for a bearer token via `POST /api/sys/users/exchange`. `true` when the password was changed successfully. One-time JWT to exchange for a bearer token via `POST /api/sys/users/exchange`. Pass this directly to `endpoints.system.auth.login(Value)`. HTTP-style status code mirrored in the body. `200` on success. Human-readable message or error description. Validation errors object. `null` on success. ## Example Response ```json theme={null} { "WasSuccessful": true, "Value": "eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiI0MiIsImV4cCI6MTcw...", "Status": 200, "Message": null, "Errors": null } ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' import { ActionConfirmation } from '@/types/ActionConfirmation' const url = endpoints.system.users.completePasswordReset // => '/api/sys/users/completePasswordReset' const response = await httpClient.post(url, { Token: resetToken, Password: newPassword, BusinessId: business.Id, }) if (response.data.WasSuccessful && response.data.Value) { // Exchange the JWT for a bearer token and sign the customer in const exchangeUrl = endpoints.system.auth.login(response.data.Value) await httpClient.post(exchangeUrl) } ``` ## Usage in Portal | Context | Source file | | -------------------------- | ------------------------------- | | Reset password page / flow | `src/views/auth/ResetPassword/` | ## Error Responses The token is invalid, expired, or already used. The customer must restart the password-reset flow via `POST /api/sys/users/startPasswordReset`. The new password does not meet the location's password requirements. Check `Errors` in the response body. ## Related Endpoints | Method | Endpoint | Description | | ------ | ----------------------------------- | -------------------------------------------- | | `POST` | `/api/sys/users/startPasswordReset` | Trigger the password-reset email | | `POST` | `/api/sys/users/exchange` | Exchange the returned JWT for a bearer token | | `POST` | `/api/token` | Standard credential-based sign-in | # List Countries Source: https://learn.nexudus.com/api/endpoints/system/countries GET /api/public/countries Retrieve the full list of countries supported by the Nexudus platform, including culture codes and ISO identifiers. # List Countries Returns all countries supported by the Nexudus platform. Used by address and profile forms across the portal to populate country dropdowns and map culture codes to display names. ## Authentication No authentication required. This is a public endpoint. ## Query Parameters Comma-separated list of field paths to include in the response. When provided, only the specified fields are returned — useful for reducing payload size. Supports nested paths using dot notation. Example: `_shape=Countries.Name,Countries.TwoDigitsCode`. ## Response Array of country objects. Numeric identifier for the country. Display name of the country in English. ISO 3166-1 alpha-2 two-letter country code (e.g. `"GB"`, `"US"`, `"DE"`). BCP 47 culture/locale string for the country (e.g. `"en-GB"`, `"en-US"`, `"de-DE"`). ## Example Response ```json theme={null} { "Countries": [ { "Id": 1, "Name": "United Kingdom", "TwoDigitsCode": "GB", "Culture": "en-GB" }, { "Id": 2, "Name": "United States", "TwoDigitsCode": "US", "Culture": "en-US" } ] } ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' import { useTypedData } from '@/api/fetchData' const endpoint = endpoints.system.countries // endpoint.type is { Countries: { Culture: string; Id: number; Name: string; TwoDigitsCode: string }[] } const { resource } = useTypedData(httpClient, endpoint) const countries = resource?.Countries ?? [] ``` ## Usage in Portal | Context | Source file | | -------------------------------- | -------------------------- | | Profile / address country picker | `src/views/profile/` | | Checkout country selector | `src/views/checkout/` | | Virtual Office form | `src/views/virtualOffice/` | ## Error Responses Unexpected server-side error. Retry with exponential back-off. ## Related Endpoints | Method | Endpoint | Description | | ------ | -------------------------------- | ------------------------ | | `GET` | `/api/public/businesses/current` | Get the current location | | `GET` | `/api/public/configuration` | Get portal configuration | # Get Enum Values Source: https://learn.nexudus.com/api/endpoints/system/enum-values GET /api/utils/enums Retrieve the list of valid values for a named Nexudus enumeration type. # Get Enum Values Returns all valid values for a named Nexudus enumeration. Enums are used throughout the platform to represent fixed sets of choices — for example, invoice status, resource types, booking states, or delivery status. The portal uses this endpoint to build dropdowns and validate field values dynamically. ## Authentication Requires a valid customer bearer token. ## Query Parameters The name of the enumeration to retrieve. This must match the exact server-side enum name (e.g. `"InvoiceStatus"`, `"ResourceType"`). ## Response Returns an array of enum entry objects. The exact shape depends on the enum requested, but each entry typically includes: Numeric value of the enum entry (as stored in the database). Machine-readable key for the enum entry. Human-readable localised label for display in the UI. ## Example Response ```json theme={null} [ { "Id": 1, "Name": "Draft", "Label": "Draft" }, { "Id": 2, "Name": "Sent", "Label": "Sent" }, { "Id": 3, "Name": "Paid", "Label": "Paid" }, { "Id": 4, "Name": "Cancelled", "Label": "Cancelled" } ] ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' const url = endpoints.system.enum('InvoiceStatus') // => '/api/utils/enums?name=InvoiceStatus' const response = await httpClient.get<{ Id: number; Name: string; Label: string }[]>(url) const enumValues = response.data ``` ## Usage in Portal | Context | Source file | | ------------------------------------- | --------------------- | | Dynamic dropdowns for resource fields | `src/views/bookings/` | | Checkout and product configuration | `src/views/checkout/` | ## Error Responses The `name` parameter is missing or does not match a known server-side enum. The bearer token is missing, expired, or invalid. ## Related Endpoints | Method | Endpoint | Description | | ------ | ----------------------------------------- | ------------------------------------------------ | | `GET` | `/api/public/configuration` | Get full portal configuration including settings | | `GET` | `/api/public/resources/fields/searchable` | Get searchable custom fields for resources | # Get Impersonation Token Source: https://learn.nexudus.com/api/endpoints/system/impersonation-token GET /api/sys/users/impersonate Issue an impersonation token that allows an admin user to act as a specific customer within the portal. # Get Impersonation Token Generates a short-lived token that an operator or admin can use to sign in as a specific customer without knowing their password. This is useful for customer support scenarios where an operator needs to view the portal exactly as a member sees it. This endpoint requires elevated (admin/operator) privileges. It is not available to standard customer sessions. ## Authentication Requires a valid admin or operator bearer token. Standard customer sessions will receive a `401 Unauthorized` response. ## Query Parameters The numeric identifier of the customer to impersonate. ## Response This endpoint is registered in `endpoints.ts` but **not invoked** anywhere in the portal frontend. The response shape below is inferred from the sibling endpoint `GET /api/public/coworkers/{coworkerId}/impersonate`, which returns the same structure and is actively used. Returns a JSON object containing a short-lived impersonation token. Pass the token to the `/api/sys/users/exchange` endpoint to obtain a full bearer session. A short-lived JWT that can be exchanged for a full authentication session via the token exchange endpoint. ### Example Response ```json theme={null} { "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." } ``` ## TypeScript Integration The endpoint is defined in `endpoints.ts` but has no callers in the portal. The public sibling endpoint (`/api/public/coworkers/{coworkerId}/impersonate`) is used instead for team-admin impersonation flows: ```typescript theme={null} import endpoints from '@/api/endpoints' // Admin-level URL builder (defined but unused in the portal) const adminUrl = endpoints.system.getImpersonationToken(coworkerId) // => '/api/sys/users/impersonate?coworkerId=42' // The portal uses the public impersonation endpoint instead: const response = await httpClient.get<{ token: string }>(endpoints.coworkers.impersonate(coworkerId)) await exchangeToken(response.data.token, true) ``` ## Usage in Portal This endpoint has **no active callers** in the portal codebase. Team-admin impersonation is handled by `GET /api/public/coworkers/{coworkerId} /impersonate` via `useSignIn().impersonate()`. | Context | Source file | | ------------------------------------------ | -------------------------------------------------------------------- | | Endpoint definition (unused) | `src/api/endpoints.ts` | | Team member impersonation (public sibling) | `src/views/auth/SignIn/useSignIn.ts` | | Impersonate button in team management | `src/views/user/team/permissions/components/TeamPermissionTable.tsx` | ## Error Responses The caller does not have admin or operator privileges. No customer with the given `coworkerId` was found in this location. ## Related Endpoints | Method | Endpoint | Description | | ------ | ------------------------------------------------ | ------------------------------------------------------------------ | | `GET` | `/api/public/coworkers/{coworkerId}/impersonate` | Public impersonation — used by team admins in the portal | | `POST` | `/api/sys/users/exchange` | Exchange a JWT for a bearer token | | `GET` | `/api/public/coworkers/profiles` | List all profiles for the current session (source of `coworkerId`) | | `PUT` | `/api/public/coworkers/profiles/current` | Switch the active profile without impersonation | # Accept Legal Terms Source: https://learn.nexudus.com/api/endpoints/system/legal-accept POST /api/public/legal/accept Record the customer's acceptance of the general terms and any pending contract terms. # Accept Legal Terms Records that the authenticated customer has accepted the current general terms and conditions, and optionally any pending contract-specific terms. The portal calls this endpoint when a customer clicks "Accept" on the legal terms modal that is shown when `MustAgreeToTerms` is `true` on the `/api/public/legal/status` response. ## Authentication Requires a valid customer bearer token. ## Request Body Send an empty body or a JSON object indicating the accepted terms. The portal typically posts with no body after the customer explicitly accepts on-screen. ```http theme={null} POST /api/public/legal/accept Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9... Content-Type: application/json ``` ## Response Returns an `ActionConfirmation` envelope. `true` when the acceptance was recorded. The terms modal should be dismissed and the customer should be granted access to the portal. Usually `null` on success. HTTP-style status code mirrored in the body. `200` on success. Human-readable message. Usually `null` on success. Validation errors. `null` on success. ## Example Response ```json theme={null} { "WasSuccessful": true, "Value": null, "Status": 200, "Message": null, "Errors": null } ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' import { ActionConfirmation } from '@/types/ActionConfirmation' const url = endpoints.system.accept_terms() // => '/api/public/legal/accept' const response = await httpClient.post(url) if (response.data.WasSuccessful) { // Dismiss the legal terms modal and continue } ``` ## Usage in Portal | Context | Source file | | ---------------------------- | --------------------------------------------- | | Legal terms acceptance modal | `src/components/LegalTerms/` or app bootstrap | ## Error Responses The bearer token is missing, expired, or invalid. The request is malformed or there are no pending terms to accept. ## Related Endpoints | Method | Endpoint | Description | | ------ | -------------------------- | ---------------------------------------------- | | `GET` | `/api/public/legal/status` | Check whether the customer must agree to terms | # Get Legal Status Source: https://learn.nexudus.com/api/endpoints/system/legal-status GET /api/public/legal/status Check whether the authenticated customer must accept general or contract-specific terms and conditions before using the portal. # Get Legal Status Returns the legal terms acceptance status for the current customer. The portal checks this on every authenticated session bootstrap. If `MustAgreeToTerms` is `true`, a blocking modal is shown with the full terms text before the customer can continue. ## Authentication Requires a valid customer bearer token. ## Response `true` when the customer must accept one or more outstanding terms before accessing the portal. Show the acceptance modal when this is `true`. Whether the customer has already accepted the space's general terms and conditions. HTML or plain-text content of the general terms and conditions to display to the customer. Array of contract-specific terms the customer must accept. Present only when there are pending contract terms. Each entry contains: Unique identifier of the contract. ISO 8601 date when the contract starts. Display name of the plan associated with this contract. HTML or plain-text content of the contract-specific terms to display. ## Example Response ```json theme={null} { "MustAgreeToTerms": true, "GeneralTermsAccepted": false, "GeneralTerms": "

By using this portal you agree to our terms.

", "ContractTerms": [ { "Id": 101, "StartDate": "2026-04-01T00:00:00Z", "TariffName": "Hot Desk Monthly", "TermsAndConditions": "

These terms govern your Hot Desk Monthly membership...

" } ] } ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' import { useTypedData } from '@/api/fetchData' const endpoint = endpoints.system.legal_status() const { resource: legalStatus } = useTypedData(httpClient, endpoint) if (legalStatus?.MustAgreeToTerms) { // Show the legal terms modal } ``` ## Usage in Portal | Context | Source file | | ------------------------------------ | ----------------------------- | | Session bootstrap — legal terms gate | `src/App.tsx` or auth context | | Legal terms acceptance modal | `src/components/LegalTerms/` | ## Error Responses The bearer token is missing, expired, or invalid. The customer must sign in. ## Related Endpoints | Method | Endpoint | Description | | ------ | -------------------------- | -------------------------------------- | | `POST` | `/api/public/legal/accept` | Record acceptance of outstanding terms | # Get Media Token Source: https://learn.nexudus.com/api/endpoints/system/media-token GET /api/auth/media/customer Obtain a short-lived JWT that authorises access to protected media files hosted by Nexudus. # Get Media Token Issues a short-lived JWT scoped to the authenticated customer that can be appended to media URLs (as the `t` query parameter) to access protected files — such as invoice PDFs, uploaded documents, and other customer-specific media stored by Nexudus. This token is distinct from the bearer token used for API calls. It is a lightweight media-access credential with a short expiry and must be refreshed before downloading files in long-lived sessions. ## Authentication Requires a valid customer bearer token in the `Authorization` header. ## Request No request body or query parameters are required. ```http theme={null} GET /api/auth/media/customer Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9... ``` ## Response Returns a `JwtMedia` object. Short-lived JWT to append as `?t={jwt}` when constructing authenticated media URLs. For example: `/api/public/billing/invoices/{id}/pdf?t={jwt}`. ## Example Response ```json theme={null} { "jwt": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0MiIsIm..." } ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' import { useData } from '@/api/fetchData' import { JwtMedia } from '@/types/JwtMedia' // The endpoint value is the raw URL string const mediaTokenUrl = endpoints.system.mediaToken // => '/api/auth/media/customer' const { resource: mediaJwt } = useData(httpClient, mediaTokenUrl) // Use the JWT when building a PDF link const pdfUrl = endpoints.billing.invoices.pdf(invoiceId, mediaJwt) ``` ## Usage in Portal | Context | Source file | | ---------------------------------------- | -------------------------------------- | | Invoice PDF download | `src/views/billing/invoices/` | | File downloads (authenticated documents) | `src/components/AuthenticatedLink.tsx` | ## Error Responses The bearer token is missing, expired, or invalid. The customer must sign in again. ## Related Endpoints | Method | Endpoint | Description | | ------ | ---------------------------------------------- | --------------------------------------------- | | `GET` | `/api/public/billing/invoices/{invoiceId}/pdf` | Download an invoice PDF (requires this token) | | `POST` | `/api/sys/users/token/refresh` | Obtain an authenticated redirect token | | `GET` | `/api/public/files/my` | List files accessible to the current customer | # Get Navigation Outline Source: https://learn.nexudus.com/api/endpoints/system/outline-navigation GET /api/public/outlines/navigation Retrieve the navigation structure that defines the portal menu, routes, and page layout. # Get Navigation Outline Returns the navigation outline that defines the portal's top-level menu structure, sidebar navigation, and page hierarchy. Operators customise this outline in the Nexudus dashboard. The portal renders its navigation tree directly from this response, making it the single source of truth for what menu items and pages are visible. ## Authentication Requires a valid customer bearer token. ## Response Returns an object with a single `Json` property containing the navigation structure as a serialised JSON string. Consumers must `JSON.parse()` the value to get the navigation tree. Serialised JSON string containing the navigation tree structure. Parse this to get the navigation items, routes, and page hierarchy. ## Example Response ```json theme={null} { "Json": "{\"Items\":[{\"Name\":\"Dashboard\",\"Url\":\"/\",\"Icon\":\"home\"}]}" } ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' import { useData } from '@/api/fetchData' const { resource: navResource } = useData<{ Json: string }>(httpClient, endpoints.system.outlines.navigation) const navigation = JSON.parse(navResource.Json) // -> NavigationConfig ``` ## Usage in Portal | Context | Source file | | ------------------------------- | ------------------------------- | | Portal sidebar / top navigation | `src/layouts/DefaultLayout.tsx` | | Route generation | `src/routes/` | ## Error Responses The bearer token is missing, expired, or invalid. ## Related Endpoints | Method | Endpoint | Description | | ------ | --------------------------------------- | ------------------------------------------- | | `GET` | `/api/public/outlines/all` | Get all system outlines | | `GET` | `/api/public/outlines/custom` | Get custom outlines created by the operator | | `GET` | `/api/public/outlines/custom/published` | Get published custom outlines | | `GET` | `/api/public/configuration` | Get portal feature configuration | # Outline Management Source: https://learn.nexudus.com/api/endpoints/system/outlines Endpoints for managing system and custom portal outlines — the structured definitions that control portal pages and navigation. # Outline Management Outlines are the structured page and navigation definitions that control what appears in the portal. The Nexudus platform provides built-in system outlines and allows operators to create custom outlines. These endpoints cover listing, retrieving, creating, updating, and deleting outlines. *** ## List All System Outlines GET /api/public/outlines/all Returns all system outlines available for the current portal. System outlines are the built-in page definitions provided by the Nexudus platform. ### Authentication Requires a valid customer bearer token. ### TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' const url = endpoints.system.outlines.all // => '/api/public/outlines/all' const response = await httpClient.get(url) ``` *** ## List Custom Outlines GET /api/public/outlines/custom Returns all custom outlines created by the operator for the current portal. ### Authentication Requires a valid customer bearer token. ### TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' const url = endpoints.system.outlines.custom // => '/api/public/outlines/custom' ``` *** ## Get Custom Outline by ID GET /api/public/outlines/custom/ Returns a specific custom outline by its numeric file identifier. ### Path Parameters The numeric identifier of the custom outline to retrieve. ### TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' const url = endpoints.system.outlines.getCustom(fileId) // => '/api/public/outlines/custom/42' ``` *** ## Get Published Custom Outline by ID GET /api/public/outlines/custom/published/ Returns the published version of a specific custom outline. Only published outlines are shown to members. ### Path Parameters The numeric identifier of the published custom outline. ### TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' const url = endpoints.system.outlines.getCustomPublished(fileId) // => '/api/public/outlines/custom/published/42' ``` *** ## List Published Custom Outlines GET /api/public/outlines/custom/published Returns all published custom outlines for the current portal. ### TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' const url = endpoints.system.outlines.customPublished // => '/api/public/outlines/custom/published' ``` *** ## Update a System Outline PUT /api/public/outlines/ Updates a named system outline. Requires operator-level permissions. ### Path Parameters The machine-readable name of the system outline to update. ### TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' const url = endpoints.system.outlines.update('navigation') // => '/api/public/outlines/navigation' await httpClient.put(url, updatedOutlineData) ``` *** ## Delete a System Outline DELETE /api/public/outlines/ Deletes a named system outline. Requires operator-level permissions. ### Path Parameters The machine-readable name of the system outline to delete. ### TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' const url = endpoints.system.outlines.delete('my-custom-page') // => '/api/public/outlines/my-custom-page' await httpClient.delete(url) ``` *** ## Create a Custom Outline POST /api/public/outlines/custom Creates a new custom outline for the portal. ### TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' const url = endpoints.system.outlines.createCustom() // => '/api/public/outlines/custom' await httpClient.post(url, newOutlineData) ``` *** ## Update a Custom Outline PUT /api/public/outlines/custom/ Updates an existing custom outline by its numeric ID. ### Path Parameters The numeric identifier of the custom outline to update. ### TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' const url = endpoints.system.outlines.updateCustom(42) // => '/api/public/outlines/custom/42' await httpClient.put(url, updatedData) ``` *** ## Delete a Custom Outline DELETE /api/public/outlines/custom/ Deletes a custom outline by its numeric ID. ### Path Parameters The numeric identifier of the custom outline to delete. ### TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' const url = endpoints.system.outlines.deleteCustom(42) // => '/api/public/outlines/custom/42' await httpClient.delete(url) ``` *** ## Error Responses The bearer token is missing, expired, or invalid. The authenticated user does not have operator-level permission to manage outlines. No outline with the given name or ID was found. ## Related Endpoints | Method | Endpoint | Description | | ------ | --------------------------------- | --------------------------------- | | `GET` | `/api/public/outlines/navigation` | Get the portal navigation outline | | `GET` | `/api/public/configuration` | Get portal feature configuration | # Get Portal Configuration Source: https://learn.nexudus.com/api/endpoints/system/portal-configuration GET /api/public/configuration Retrieve the full portal feature configuration for the current Nexudus location. # Get Portal Configuration Returns the complete portal configuration object for the current location. This includes feature flags, payment provider settings, branding configuration, checkout options, module availability, and all other operator-controlled settings that determine how the Members Portal behaves. The portal fetches this on startup and re-fetches when switching locations. ## Authentication Requires a valid customer bearer token, or returns public configuration for unauthenticated sessions depending on space settings. ## Response Returns `BusinessSetting[]` — a flat array of name–value pairs. Each setting corresponds to a portal configuration option set by the operator. The setting key (e.g. `"PublicWebSite.Tour.TimeSlots.Enabled"`, `"PaymentProvider"`, `"AllowSelfSignup"`). The setting value as a string. Boolean settings use `"True"`/`"False"`. Numeric settings are stringified. ## Example Response ```json theme={null} [ { "Name": "PaymentProvider", "Value": "Stripe" }, { "Name": "AllowSelfSignup", "Value": "True" }, { "Name": "DefaultLanguage", "Value": "en" }, { "Name": "PublicWebSite.Tour.TimeSlots.Enabled", "Value": "False" } ] ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' import { useData } from '@/api/fetchData' import { BusinessSetting } from '@/types/sys/BusinessSetting' const { resource: settings } = useData(httpClient, endpoints.system.business.configuration) const getSetting = (name: string) => settings?.find((x) => x.Name?.toLocaleLowerCase() === name.toLocaleLowerCase())?.Value if (getSetting('AllowSelfSignup') === 'True') { // Show signup flow } ``` ## Usage in Portal | Context | Source file | | ------------------------------------- | ------------------------------------------ | | App bootstrap / feature flag provider | `src/states/useLocationByRouteContext.tsx` | | Payment provider initialisation | `src/views/checkout/` | | Navigation and route guard | `src/routes/` | ## Error Responses Authentication is required and no valid token was supplied. No configuration found for the resolved location. ## Related Endpoints | Method | Endpoint | Description | | ------ | --------------------------------- | --------------------------------- | | `GET` | `/api/public/businesses/current` | Get the current location profile | | `GET` | `/api/sys/businesses/{id}/colors` | Get the brand colour palette | | `GET` | `/api/public/outlines/navigation` | Get the portal navigation outline | # Send OTP Source: https://learn.nexudus.com/api/endpoints/system/send-otp GET /api/sys/users/sendOtp Send a one-time password (OTP) to a customer email address for passwordless sign-in. # Send OTP Sends a one-time password to the provided email address for passwordless authentication. The customer enters the OTP in the portal to obtain a bearer token without needing their full password. This supports magic-link and OTP-based sign-in flows. ## Authentication No authentication required. This is a public endpoint. ## Query Parameters The email address of the customer to send the OTP to. URL-encode this value. The numeric identifier of the location. Ensures the OTP email uses the correct branding and is associated with the right space. ## Response Returns an `ActionConfirmation` envelope. As with the password-reset flow, the response does not reveal whether the email address is registered. `true` when the OTP was dispatched (or when no account was found — intentionally the same to prevent enumeration). Usually `null`. HTTP-style status code mirrored in the body. `200` on success. Human-readable message. Usually `null` on success. Validation errors. `null` on success. ## Example Response ```json theme={null} { "WasSuccessful": true, "Value": null, "Status": 200, "Message": null, "Errors": null } ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' const url = endpoints.system.users.sendOtp(email, businessId) // => '/api/sys/users/sendOtp?email=jane.doe%40example.com&businessId=7' await httpClient.get(url) ``` ## Usage in Portal | Context | Source file | | ----------------------------- | ------------------------ | | OTP / magic-link sign-in flow | `src/views/auth/SignIn/` | ## Error Responses The `email` or `businessId` parameter is missing or malformed. OTP requests are rate-limited. The customer must wait before requesting another code. ## Related Endpoints | Method | Endpoint | Description | | ------ | ----------------------------------- | ------------------------------------------------- | | `POST` | `/api/sys/users/startPasswordReset` | Trigger a full password-reset email | | `POST` | `/api/sys/users/exchange` | Exchange a JWT (including OTP result) for a token | | `POST` | `/api/token` | Standard credential-based sign-in | # Start Password Reset Source: https://learn.nexudus.com/api/endpoints/system/start-password-reset POST /api/sys/users/startPasswordReset Trigger a password-reset email for a customer account. # Start Password Reset Sends a password-reset email to the customer's registered email address. The email contains a one-time link that the customer can follow to set a new password. The portal calls this from the "Forgot your password?" flow on the sign-in page. ## Authentication No authentication required. This is a public endpoint. ## Request Body The email address of the account for which the password reset should be triggered. The numeric identifier of the location the customer belongs to. Providing this ensures the correct branded email template is used. ## Response Returns an `ActionConfirmation` envelope. The portal treats any successful response as confirmation that the email was sent — it does not reveal whether the email address is registered, to prevent enumeration attacks. `true` when the reset email was dispatched (or when no account was found — the response is intentionally the same to prevent user enumeration). Usually `null`. HTTP-style status code mirrored in the body. `200` on success. Human-readable message. Usually `null` on success. Validation errors. `null` on success. ## Example Response ```json theme={null} { "WasSuccessful": true, "Value": null, "Status": 200, "Message": null, "Errors": null } ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' const url = endpoints.system.users.startPasswordReset // => '/api/sys/users/startPasswordReset' await httpClient.post(url, { email: userEmail, businessId }) ``` ## Usage in Portal | Context | Source file | | ---------------------------- | -------------------------------- | | Forgot password page / modal | `src/views/auth/ForgotPassword/` | ## Error Responses The email field is missing or the request body is malformed. ## Related Endpoints | Method | Endpoint | Description | | ------ | -------------------------------------- | ----------------------------------------------------- | | `POST` | `/api/sys/users/completePasswordReset` | Complete the reset flow with the token from the email | | `POST` | `/api/token` | Sign in after completing the password reset | | `GET` | `/api/sys/users/sendOtp` | Send a one-time password for passwordless sign-in | # Add Team Members Source: https://learn.nexudus.com/api/endpoints/teams/add-team-members POST /api/public/teams/{teamId}/members Adds one or more new members to a team by email address. # Add Team Members Adds one or more members to a team by providing their full names and email addresses. Each new member is assigned the specified membership plan with the given start date. A maximum of 25 members can be added in a single request. ## Authentication Requires a valid customer bearer token. The customer must be a team administrator of the specified team. ## Path Parameters Numeric identifier of the team. Returned as `Id` from [`GET /api/public/teams/my`](/api/endpoints/teams/list-teams). ## Request Body ID of the membership plan to assign to the new members. Obtain available plans from the team's default tariff or from the plans list. Array of full names for each new member. Must have the same number of entries as `Emails`. Array of email addresses for each new member. Must have the same number of entries as `FullNames`. Each entry must be a valid email address. ISO 8601 date for when the new members' plans should begin. ## Response Returns HTTP `200 OK` with an empty body on success. ## Examples ### Add two members to a team ```http theme={null} POST /api/public/teams/55/members Authorization: Bearer {token} Content-Type: application/json ``` ```json theme={null} { "TariffId": 301, "FullNames": ["Alice Johnson", "Carlos Rivera"], "Emails": ["alice@example.com", "carlos@example.com"], "StartDate": "2025-02-01T00:00:00.000Z" } ``` ``` Status: 200 OK Body: (empty) ``` ## TypeScript Integration ```typescript theme={null} import { endpoints } from '@/api/endpoints' await httpClient.post(endpoints.teams.addMembers(teamId), { TariffId: 301, FullNames: ['Alice Johnson'], Emails: ['alice@example.com'], StartDate: new Date().toISOString(), }) ``` ## Usage in Portal | Context | Source file | | ------------------------------------------- | --------------------------------------------------------------- | | Add member modal (`/team/members/{teamId}`) | `src/views/user/team/members/components/TeamMemberAddModal.tsx` | ## Error Responses The customer is not authenticated or the session has expired. The customer is not an administrator of the specified team. Validation error — for example, mismatched array lengths for `FullNames` and `Emails`, more than 25 members, or invalid email format. Team with the specified ID does not exist. ## Related Endpoints | Method | Endpoint | Description | | -------- | --------------------------------------------------- | --------------------------- | | `DELETE` | `/api/public/teams/{teamId}/members/{coworkerId}` | Remove a member from a team | | `GET` | `/api/public/teams/my` | List the customer's teams | | `GET` | `/api/public/teams/{teamId}/profile` | Full team profile | | `PUT` | `/api/public/teams/{teamId}/permissions/{memberId}` | Update member permissions | # List Published Teams Source: https://learn.nexudus.com/api/endpoints/teams/directory-list GET /api/public/teams/published Returns a paginated list of teams with public profiles, filterable by search query and tags. # List Published Teams Returns a paginated list of teams whose profiles are publicly visible in the member directory. Supports full-text search by name and filtering by profile tag. Used by the community directory page to render team cards alongside member profiles. ## Authentication Requires a valid customer bearer token. ## Query Parameters Full-text search string matched against team names and descriptions. **Default**: `""` (no filter). Filter results to teams that have this tag in their `ProfileTags`. **Default**: `""` (no filter). Sort order. **Default**: `1`. Comma-separated dot-notated field paths to include in the response. When provided, only the specified fields are returned — useful for reducing payload size. **Example**: `_shape=Records.Id,Records.Name,Records.ProfileSummary` 1-based page number. **Default**: `1` Records per page. **Default**: `25` · **Maximum**: `100` ## Response Returns the standard `ApiListResult` envelope (see [API Overview](/api/overview) for pagination fields). The `Records` array contains team objects with the same shape as [`GET /api/public/teams/my`](/api/endpoints/teams/list-teams). See that endpoint for the full field breakdown. ### Key Team Fields | Field | Type | Description | | ------------------ | --------- | --------------------------------------- | | `Id` | `number` | Unique numeric identifier for the team | | `Name` | `string` | Team display name | | `ProfileSummary` | `string` | Short team bio | | `ProfileIsPublic` | `boolean` | Whether the profile is publicly visible | | `ProfileWebsite` | `string` | Team website URL | | `HasTeamLogo` | `boolean` | Whether the team has a logo image | | `TeamMembersCount` | `number` | Number of team members | | `BusinessName` | `string` | Location display name | | `Twitter` | `string` | Twitter handle/URL | | `Linkedin` | `string` | LinkedIn URL | | `Github` | `string` | GitHub URL | | `Instagram` | `string` | Instagram URL | ## Examples ### Search published teams ```http theme={null} GET /api/public/teams/published?query=tech&tag=innovation&order=1 Authorization: Bearer {token} ``` ```json theme={null} { "Records": [ { "Id": 55, "Name": "Tech Innovators", "ProfileSummary": "Building the future, one innovation at a time", "ProfileIsPublic": true, "ProfileTags": "technology startup innovation", "ProfileTagsList": ["technology", "startup", "innovation"], "HasTeamLogo": true, "TeamMembersCount": 12, "BusinessName": "Downtown Coworking Hub" } ], "CurrentPageSize": 1, "CurrentPage": 1, "HasNextPage": false, "HasPreviousPage": false, "TotalItems": 1, "TotalPages": 1 } ``` ## TypeScript Integration ```typescript theme={null} import { endpoints } from '@/api/endpoints' import { useData } from '@/hooks/useData' const { resource: teams } = useData(httpClient, endpoints.teams.directory.published_list(query, tag, order)) ``` ## Usage in Portal | Context | Source file | | -------------------------------------------- | -------------------------------------------------------------- | | Community directory (`/community/directory`) | `src/views/community/directory/components/useDirectoryData.ts` | ## Error Responses The customer is not authenticated or the session has expired. ## Related Endpoints | Method | Endpoint | Description | | ------ | -------------------------------------- | --------------------------------------- | | `GET` | `/api/public/teams/published/{teamId}` | Full profile of a single published team | | `GET` | `/api/public/teams/directory/meta` | Directory metadata (tags, config) | | `GET` | `/api/public/teams/my` | List the customer's own teams | # Get Directory Meta Source: https://learn.nexudus.com/api/endpoints/teams/directory-meta GET /api/public/teams/directory/meta Returns directory configuration and tag cloud data for the team and member directory. # Get Directory Meta Returns metadata that controls how the community directory behaves — including whether the directory is enabled, what content it shows (teams only, members only, or both), the tag cloud for filtering, and any custom fields configured for directory search. ## Authentication Requires a valid customer bearer token. ## Response The directory metadata object. ### Meta Fields When `true`, the community directory is enabled for this location. Controls which profiles appear in the directory: `1` = Published profiles, `2` = Published profiles with a price plan, `3` = Everyone, `4` = Everyone with a price plan. Controls the record types shown: `1` = Teams and members, `2` = Only teams, `3` = Only members. When `true`, only members from the invoicing space are shown. When `true`, members who are currently checked in are highlighted. Tag cloud entries derived from all published profiles. The tag text. Number of profiles using this tag. Relative weight of this tag as a percentage — used to size tags in a tag cloud UI. Custom fields configured for directory search. Unique identifier of the custom field. Display name of the custom field. Field type (e.g., `"Text"`, `"Dropdown"`). Index used to map the field to the correct slot. When `true`, this field appears as a search filter in the directory UI. Label shown in the search filter UI. Available values for dropdown-type fields. ## Examples ### Fetch directory metadata ```http theme={null} GET /api/public/teams/directory/meta Authorization: Bearer {token} ``` ```json theme={null} { "Meta": { "DirectoryEnabled": true, "DirectoryContents": 1, "DirectoryRecords": 1, "OnlyInvoicingSpace": false, "ShowCheckInMembers": true, "Tags": [ { "Tag": "technology", "Count": 8, "Percentage": 40 }, { "Tag": "design", "Count": 5, "Percentage": 25 }, { "Tag": "marketing", "Count": 4, "Percentage": 20 } ], "CustomFields": [ { "Id": 1, "Name": "Industry", "FieldType": "Dropdown", "CustomFieldIndex": 0, "DisplayInDirectorySearch": true, "NameInSearch": "Industry", "AvailableOptions": ["Technology", "Finance", "Design", "Marketing"] } ] } } ``` ## TypeScript Integration ```typescript theme={null} import { endpoints } from '@/api/endpoints' import { DirectoryMetaData } from '@/types/endpoints/DirectoryMeta' import { useData } from '@/hooks/useData' const { resource: meta } = useData(httpClient, endpoints.teams.directory.meta) ``` ## Usage in Portal | Context | Source file | | -------------------------------------------- | -------------------------------------------------------------- | | Community directory (`/community/directory`) | `src/views/community/directory/components/useDirectoryData.ts` | ## Error Responses The customer is not authenticated or the session has expired. ## Related Endpoints | Method | Endpoint | Description | | ------ | -------------------------------------- | ------------------------------------- | | `GET` | `/api/public/teams/published` | List published teams in the directory | | `GET` | `/api/public/teams/published/{teamId}` | Get a single published team profile | | `GET` | `/api/public/teams/my` | List the customer's own teams | # Get Published Team Source: https://learn.nexudus.com/api/endpoints/teams/directory-team GET /api/public/teams/published/{teamId} Returns the full public profile of a single published team from the directory. # Get Published Team Returns the full public profile for a single team in the member directory. Used when a customer clicks on a team card in the directory to view its detailed profile in a modal. ## Authentication Requires a valid customer bearer token. ## Path Parameters Numeric identifier of the team. Returned as `Id` in the `Records` array from [`GET /api/public/teams/published`](/api/endpoints/teams/directory-list). ## Query Parameters Comma-separated dot-notated field paths to include in the response. When provided, only the specified fields are returned — useful for reducing payload size. ## Response Returns a team profile object with the same fields as [`GET /api/public/teams/{teamId}/profile`](/api/endpoints/teams/team-details), but scoped to publicly visible information. See that endpoint for the full field breakdown. ### Key Team Profile Fields | Field | Type | Description | | ------------------- | --------- | --------------------------------------- | | `Id` | `number` | Unique numeric identifier for the team | | `Name` | `string` | Team display name | | `Description` | `string` | Team description | | `ProfileSummary` | `string` | Short team bio | | `ProfileIsPublic` | `boolean` | Whether the profile is publicly visible | | `ProfileWebsite` | `string` | Team website URL | | `HasTeamLogo` | `boolean` | Whether the team has a logo image | | `TeamMembersCount` | `number` | Number of team members | | `BusinessName` | `string` | Location display name | | `HasCommunityGroup` | `boolean` | Whether the team has a discussion group | | `Twitter` | `string` | Twitter handle/URL | | `Linkedin` | `string` | LinkedIn URL | ## Examples ### Fetch a published team profile ```http theme={null} GET /api/public/teams/published/55 Authorization: Bearer {token} ``` ```json theme={null} { "Id": 55, "Name": "Tech Innovators", "ProfileSummary": "Building the future, one innovation at a time", "ProfileIsPublic": true, "ProfileWebsite": "https://techinnovators.example.com", "ProfileTags": "technology startup innovation", "ProfileTagsList": ["technology", "startup", "innovation"], "BusinessName": "Downtown Coworking Hub", "Twitter": "https://twitter.com/techinnovators", "Linkedin": "https://linkedin.com/company/techinnovators", "Github": "https://github.com/techinnovators", "HasTeamLogo": true, "TeamMembersCount": 12 } ``` ## TypeScript Integration ```typescript theme={null} import { endpoints } from '@/api/endpoints' import { useData } from '@/hooks/useData' const { resource: team } = useData(httpClient, endpoints.teams.directory.published_one(teamId)) ``` ## Usage in Portal | Context | Source file | | -------------------------------------------------------- | ------------------------------------------------------------------------ | | Team profile modal in directory (`/community/directory`) | `src/views/community/directory/components/TeamDirectoryProfileModal.tsx` | ## Error Responses The customer is not authenticated or the session has expired. Team with the specified ID does not exist or is not publicly visible. ## Related Endpoints | Method | Endpoint | Description | | ------ | ------------------------------------ | --------------------------------- | | `GET` | `/api/public/teams/published` | List all published teams | | `GET` | `/api/public/teams/directory/meta` | Directory metadata (tags, config) | | `GET` | `/api/public/teams/{teamId}/profile` | Full team profile (member access) | # List User Teams Source: https://learn.nexudus.com/api/endpoints/teams/list-teams GET /api/public/teams/my Returns the teams the authenticated customer belongs to, optionally filtered to admin-only teams. # List User Teams Returns a paginated list of teams the authenticated customer belongs to. Pass `isTeamAdmin=true` to restrict the results to teams where the customer has admin rights — used across the portal to gate management interfaces. Pass `isTeamAdmin=false` to return all teams regardless of role. A **team** is a group of customers within a coworking location that can share resources, bookings, and billing. The portal maps teams to companies or departments that co-habit a space. ## Authentication Requires a valid customer bearer token. The response is automatically scoped to the authenticated customer — no additional filtering is needed. ## Query Parameters `true` — return only teams where the customer is an administrator. `false` — return all teams the customer belongs to (admins and members). Filter results to a single team by its numeric ID. When omitted, returns all teams matching the `isTeamAdmin` filter. Comma-separated dot-notated field paths to include in the response. When provided, only the specified fields are returned — useful for reducing payload size. **Example**: `_shape=Records.Id,Records.Name,Records.TeamMembersCount` 1-based page number. **Default**: `1` Records per page. **Default**: `25` · **Maximum**: `100` Response field to sort by. **Default**: `Name` `asc` or `desc`. **Default**: `asc` ## Response Returns the standard `ApiListResult` envelope (see [API Overview](/api/overview) for pagination fields). The `Records` array contains team objects. ### Core Fields Unique integer identifier for the team. Use this as `{teamId}` in all team-scoped endpoints. Display name of the team. UUID for the team — stable across renames and useful as a cache key. String cast of `Id`. Provided for environments that lose integer precision (e.g., JavaScript `JSON.parse` on 64-bit IDs). ### Profile Fields Full-length team description. May contain HTML. Short tagline shown in team cards and selectors. When `true`, the team profile is visible in the public member directory. Team website URL. Space-separated tag string. Use `ProfileTagsList` for array access. Pre-split array of tag strings derived from `ProfileTags`. ### Location Name of the coworking location this team belongs to. URL of the coworking location's home page. ### Social Media All social fields are `string | null`. Provide a full URL (e.g., `https://twitter.com/handle`) unless stated otherwise. | Field | Description | | ----------- | ------------------------- | | `Twitter` | X / Twitter profile URL | | `Facebook` | Facebook page URL | | `Linkedin` | LinkedIn company page URL | | `Instagram` | Instagram profile URL | | `Github` | GitHub org or user URL | | `Pinterest` | Pinterest profile URL | | `Skype` | Skype username | | `Telegram` | Telegram handle | | `Flickr` | Flickr profile URL | | `Vimeo` | Vimeo channel URL | | `Tumblr` | Tumblr blog URL | | `Blogger` | Blogger profile URL | ### Members Total count of active members (admins + regular members). Display names of all team admins — useful for a quick summary without loading full `Customer` objects. Full `Coworker` objects for admins only. Full `Coworker` objects for non-admin members. Combined `Coworker` objects for all members (admins + regular). Use this instead of merging the two arrays above. ### Billing & Configuration Customer ID of the member who receives consolidated invoices, if `CreateSingleInvoiceForTeam` is `true`. When `true`, all team charges are rolled into a single invoice addressed to `PayingMemberId`. Maximum allowed members. `null` means unlimited. Whether billing/contact details have been configured for this team. Whether the team has a default membership plan assigned. ID of the default membership plan assigned to new team members. `null` if no default plan is set. Display name of the default membership plan. When `true`, new members added to the team are placed on hold until manually activated. When `true`, the attendance dashboard is hidden for this team. Note the typo in the field name (`Attendace`) — it is preserved as-is in the API. Percentage discount applied to charges for team members. Percentage discount applied to extra services for team members. Percentage discount applied to membership plans for team members. Percentage discount applied to time passes for team members. When `true`, the team has an associated community discussion group. Google Maps link for the team's location. ### Media `true` if the team has an uploaded logo. Construct the logo URL as: `https://[space].spaces.nexudus.com/api/public/teams/{Id}/logo` `true` if profile image 1 has been uploaded. `true` if profile image 2 has been uploaded. `true` if profile image 3 has been uploaded. Convenience flag — `true` if any of the three profile images are present. ### Timestamps All datetime fields are ISO 8601 strings. `*On` fields are in the location's local timezone; `*OnUtc` fields are UTC. Local datetime the team was created. UTC datetime the team was created. Local datetime of the last update. UTC datetime of the last update. ## Examples ### Fetch admin teams (full payload) ```http theme={null} GET /api/public/teams/my?isTeamAdmin=true Authorization: Bearer {token} ``` ```json theme={null} { "Records": [ { "Id": 55, "Name": "Tech Innovators", "Description": "A collaborative team focused on cutting-edge technology solutions", "ProfileSummary": "Building the future, one innovation at a time", "ProfileIsPublic": true, "ProfileWebsite": "https://techinnovators.example.com", "ProfileTags": "technology startup innovation collaboration", "ProfileTagsList": ["technology", "startup", "innovation", "collaboration"], "BusinessName": "Downtown Coworking Hub", "BusinessHomeUrl": "https://downtown-hub.example.com", "Twitter": "https://twitter.com/techinnovators", "Facebook": null, "Linkedin": "https://linkedin.com/company/techinnovators", "Instagram": null, "Github": "https://github.com/techinnovators", "Pinterest": null, "Skype": null, "Telegram": null, "Flickr": null, "Vimeo": null, "Tumblr": null, "Blogger": null, "TeamMembersCount": 12, "TeamAdministratorsFullNames": ["Jane Smith", "John Doe"], "TeamAdministrators": [{ "Id": 101, "FullName": "Jane Smith", "Email": "jane@techinnovators.com" }], "TeamMembers": [{ "Id": 102, "FullName": "Bob Wilson", "Email": "bob@techinnovators.com" }], "AllTeamMembers": [ { "Id": 101, "FullName": "Jane Smith", "Email": "jane@techinnovators.com" }, { "Id": 102, "FullName": "Bob Wilson", "Email": "bob@techinnovators.com" } ], "PayingMemberId": 101, "CreateSingleInvoiceForTeam": true, "HasContactDetails": true, "HasDefaultPlan": true, "MaxTeamMemberCount": 20, "DisableAttendaceDashboard": false, "HasTeamLogo": true, "HasImage1": true, "HasImage2": false, "HasImage3": false, "HasImages": true, "Id": 55, "IdString": "55", "UniqueId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "CreatedOn": "2024-01-15T09:30:00", "UpdatedOn": "2024-07-20T14:22:33", "CreatedOnUtc": "2024-01-15T09:30:00Z", "UpdatedOnUtc": "2024-07-20T14:22:33Z" } ], "CurrentPageSize": 1, "CurrentPage": 1, "CurrentOrderField": "Name", "CurrentSortDirection": "asc", "FirstItem": 1, "HasNextPage": false, "HasPreviousPage": false, "LastItem": 1, "PageNumber": 1, "PageSize": 25, "TotalItems": 1, "TotalPages": 1 } ``` ### Fetch all teams with a minimal field set Use `_shape` to return only the fields your UI needs, reducing payload size significantly. ```http theme={null} GET /api/public/teams/my?isTeamAdmin=false&_shape=Records.Id,Records.Name,Records.TeamMembersCount Authorization: Bearer {token} ``` ```json theme={null} { "Records": [ { "Id": 55, "Name": "Tech Innovators", "TeamMembersCount": 12 }, { "Id": 67, "Name": "Marketing Team", "TeamMembersCount": 8 }, { "Id": 89, "Name": "Design Studio", "TeamMembersCount": 5 } ], "CurrentPageSize": 3, "CurrentPage": 1, "CurrentOrderField": "Name", "CurrentSortDirection": "asc", "FirstItem": 1, "HasNextPage": false, "HasPreviousPage": false, "LastItem": 3, "PageNumber": 1, "PageSize": 25, "TotalItems": 3, "TotalPages": 1 } ``` ## TypeScript Integration The portal types this response as `TeamList` (from `src/types/endpoints/TeamList.ts`) and accesses it through the `endpoints.teams` helper: ```typescript theme={null} import { endpoints } from '@/api/endpoints' import { TeamList } from '@/types/endpoints/TeamList' import { useData } from '@/hooks/useData' // Minimal selector data (team switcher dropdowns, nav menus) const { resource: adminTeams } = useData( httpClient, endpoints.teams.list(true), // isTeamAdmin=true { shape: { fields: ['Records.Id', 'Records.Name'] } }, ) // Richer data for management pages const { resource: allTeams } = useData( httpClient, endpoints.teams.list(false), // isTeamAdmin=false { shape: { fields: ['Records.Id', 'Records.Name', 'Records.ProfileSummary', 'Records.TeamMembersCount'], }, }, ) ``` ## Usage in Portal The `isTeamAdmin` flag drives a clear permission split across the portal: | Context | `isTeamAdmin` | Source file | | ---------------------------- | :-----------: | ---------------------------------------------------------------------------------------------------- | | Team Dashboard team-switcher | `true` | `src/views/user/dashboards/team/TeamDashboardPage.tsx` | | Team Profile editor | `true` | `src/views/user/team/profile/TeamProfessionalProfilePage.tsx` | | Team Permissions management | `true` | `src/views/user/team/permissions/TeamPermissionsPage.tsx` | | Team Attendance management | `true` | `src/views/user/team/attendance/AttendanceManagementPage.tsx` | | Global navigation menu | `true` | `src/states/useMenuItems.tsx` | | Team Attendance dashboard | `false` | `src/views/user/team/attendance/AttendanceDashboardPage.tsx` | | Attendance management | `true` | `src/views/user/team/attendance/AttendanceManagementPage.tsx` | | My Bookings team selector | `false` | `src/views/user/activity/bookings/MyBookingsSection.tsx` | | Booking visitors | `false` | `src/views/public/checkout/booking/components/BookingVisitors.tsx` | | Onboarding profile action | `false` | `src/views/user/dashboards/personal/components/OnBoarding/components/CompleteProfileActionPanel.tsx` | | Team members section | `false` | `src/views/user/team/members/TeamMembersSection.tsx` | ## Error Responses The customer is not authenticated or the session has expired. Re-authenticate and retry. A query parameter value is invalid — for example, a non-boolean `isTeamAdmin` or an out-of-range `_pageSize`. ## Related Endpoints | Method | Endpoint | Description | | -------- | ------------------------------------------------- | -------------------------------- | | `GET` | `/api/public/teams/{teamId}/profile` | Full profile for a single team | | `PUT` | `/api/public/teams/{teamId}/profile` | Update team profile (admin only) | | `GET` | `/api/public/teams/{teamId}/kpi` | Team KPI metrics | | `GET` | `/api/public/teams/{teamId}/attendance` | Team attendance data | | `GET` | `/api/public/teams/{teamId}/metrics` | Team performance metrics | | `POST` | `/api/public/teams/{teamId}/members` | Add members to a team | | `DELETE` | `/api/public/teams/{teamId}/members/{coworkerId}` | Remove a member from a team | # Remove Team Member Source: https://learn.nexudus.com/api/endpoints/teams/remove-team-member DELETE /api/public/teams/{teamId}/members/{coworkerId} Removes a member from a team by their customer ID. # Remove Team Member Removes a single member from a team. The customer cannot remove themselves — attempting to do so returns a `CANNOT_REMOVE_ITSELF` error. Members with active contracts should have their contracts cancelled before removal. ## Authentication Requires a valid customer bearer token. The customer must be a team administrator of the specified team. ## Path Parameters Numeric identifier of the team. Returned as `Id` from [`GET /api/public/teams/my`](/api/endpoints/teams/list-teams). Numeric identifier of the customer to remove. Returned as `Id` in the `AllTeamMembers` array from [`GET /api/public/teams/{teamId} /profile`](/api/endpoints/teams/team-details). ## Response Returns HTTP `200 OK` with an empty body on success. ## Examples ### Remove a member ```http theme={null} DELETE /api/public/teams/55/members/102 Authorization: Bearer {token} ``` ``` Status: 200 OK Body: (empty) ``` ## TypeScript Integration ```typescript theme={null} import { endpoints } from '@/api/endpoints' await httpClient.delete(endpoints.teams.removeMember(teamId, coworkerId)) ``` ## Usage in Portal | Context | Source file | | --------------------------------------------- | -------------------------------------------------------------------- | | Team members table (`/team/members/{teamId}`) | `src/views/user/team/members/components/TeamMembersTableSection.tsx` | ## Error Responses The customer is not authenticated or the session has expired. The customer is not an administrator of the specified team. The request is invalid — for example, the member has active contracts, or the response message is `CANNOT_REMOVE_ITSELF` when attempting self-removal. Team or member with the specified ID does not exist. ## Related Endpoints | Method | Endpoint | Description | | ------ | --------------------------------------------------- | ------------------------- | | `POST` | `/api/public/teams/{teamId}/members` | Add members to a team | | `GET` | `/api/public/teams/{teamId}/profile` | Full team profile | | `GET` | `/api/public/teams/my` | List the customer's teams | | `PUT` | `/api/public/teams/{teamId}/permissions/{memberId}` | Update member permissions | # Get Team Attendance Source: https://learn.nexudus.com/api/endpoints/teams/team-attendance GET /api/public/teams/{teamId}/attendance Returns attendance data for a team on a given week, including per-member schedules and bookings. # Get Team Attendance Returns the attendance matrix for a team centred on a given date. Includes per-member day-of-week attendance preferences (office, home, abroad, not working), aggregate statistics, and any bookings overlapping the requested week. ## Authentication Requires a valid customer bearer token. The customer must be a member or administrator of the specified team. ## Path Parameters Numeric identifier of the team. Returned as `Id` from [`GET /api/public/teams/my`](/api/endpoints/teams/list-teams). ## Query Parameters ISO 8601 UTC datetime specifying the week to retrieve. The API returns the full week containing this date. Comma-separated list of field paths to include in the response. When provided, only the specified fields are returned — useful for reducing payload size. Supports nested paths using dot notation. ## Response Whether the authenticated customer is an administrator of this team. Used by the portal to show or hide the attendance editing UI. The attendance data object. ### Attendance Details Numeric identifier of the team. Display name of the team. Average booked minutes per week across all members. Average number of members with bookings per day. Average number of members checked in per day. Average check-in days per week. ### Attendance.Coworkers\[] Numeric identifier of the member. Display name of the member. Member type code. Company name associated with the member, if any. Monday attendance status: `1` = Office, `2` = Home, `3` = Abroad, `4` = Not Working, `5` = Undefined. Tuesday attendance status (same values as Monday). Wednesday attendance status. Thursday attendance status. Friday attendance status. Saturday attendance status. Sunday attendance status. ### Attendance.Days\[] ISO 8601 date for this day. Bookings on this day. Booking identifier. Booking start time. Booking end time. Identifier of the booked resource. Name of the booked resource. Customer who owns the booking, if applicable. ## Examples ### Fetch attendance for a week ```http theme={null} GET /api/public/teams/55/attendance?date=2025-01-20T00:00:00.000Z Authorization: Bearer {token} ``` ```json theme={null} { "IsTeamAdministrator": true, "Attendance": { "TeamId": 55, "TeamName": "Tech Innovators", "AvgBookedMinutesPerWeek": 480, "AvgBookingsCoworkersPerDay": 3, "AvgCheckedinCoworkersPerDay": 5, "AvgCheckinsDaysPerWeek": 4.2, "Coworkers": [ { "CoworkerId": 101, "CoworkerFullName": "Jane Smith", "CoworkerType": 1, "CoworkerCompanyName": "Tech Innovators Ltd", "MondayAttendance": 1, "TuesdayAttendance": 1, "WednesdayAttendance": 2, "ThursdayAttendance": 1, "FridayAttendance": 2, "SaturdayAttendance": 4, "SundayAttendance": 4 } ], "Days": [ { "Date": "2025-01-20T00:00:00", "Bookings": [ { "Id": 5001, "FromTime": "09:00", "ToTime": "17:00", "ResourceId": 201, "ResourceName": "Meeting Room A", "CoworkerId": 101 } ] } ] } } ``` ## TypeScript Integration ```typescript theme={null} import { endpoints } from '@/api/endpoints' import { TeamAttendance } from '@/types/endpoints/TeamAttandance' import { useData } from '@/hooks/useData' import { DateTime } from 'luxon' const { resource: attendance } = useData(httpClient, endpoints.teams.attendance(teamId, DateTime.now())) ``` ## Usage in Portal | Context | Source file | | ----------------------------------------------------------- | --------------------------------------------------------------------------- | | Team dashboard attendance KPIs (`/dashboard/team/{teamId}`) | `src/views/user/dashboards/team/components/TeamAttendanceKpiSection.tsx` | | Team attendance section (`/team/attendance/{teamId}`) | `src/views/user/team/attendance/components/TeamAttedanceSection.tsx` | | Attendance management (`/team/attendance/{teamId}`) | `src/views/user/team/attendance/components/AttendanceManagementSection.tsx` | ## Error Responses The customer is not authenticated or the session has expired. Team with the specified ID does not exist. ## Related Endpoints | Method | Endpoint | Description | | ------ | --------------------------------------- | ------------------------------------ | | `PUT` | `/api/public/teams/{teamId}/attendance` | Update member attendance preferences | | `GET` | `/api/public/teams/{teamId}/kpi` | Team KPI data | | `GET` | `/api/public/teams/{teamId}/metrics` | Team performance metrics | | `GET` | `/api/public/teams/{teamId}/profile` | Full team profile | # Update Team Attendance Source: https://learn.nexudus.com/api/endpoints/teams/team-attendance-update PUT /api/public/teams/{teamId}/attendance Updates per-member weekly attendance preferences for a team. # Update Team Attendance Updates the weekly attendance preferences for one or more team members. Each entry specifies a member and their day-of-week attendance status (office, home, abroad, not working). Only team administrators can update attendance. ## Authentication Requires a valid customer bearer token. The customer must be a team administrator of the specified team. ## Path Parameters Numeric identifier of the team. Returned as `Id` from [`GET /api/public/teams/my`](/api/endpoints/teams/list-teams). ## Request Body The request body is an **array** of attendance update objects. Each object specifies a member and one or more day-of-week attendance values. Numeric identifier of the team member whose attendance is being updated. Monday attendance status: `1` = Office, `2` = Home, `3` = Abroad, `4` = Not Working, `5` = Undefined. Tuesday attendance status (same values). Wednesday attendance status. Thursday attendance status. Friday attendance status. Saturday attendance status. Sunday attendance status. ## Response Returns HTTP `200 OK` with an empty body on success. ## Examples ### Update attendance for two members ```http theme={null} PUT /api/public/teams/55/attendance Authorization: Bearer {token} Content-Type: application/json ``` ```json theme={null} [ { "CoworkerId": 101, "MondayAttendance": 1, "TuesdayAttendance": 1, "WednesdayAttendance": 2, "ThursdayAttendance": 1, "FridayAttendance": 2, "SaturdayAttendance": 4, "SundayAttendance": 4 }, { "CoworkerId": 102, "WednesdayAttendance": 1, "FridayAttendance": 3 } ] ``` ``` Status: 200 OK Body: (empty) ``` ## TypeScript Integration ```typescript theme={null} import { endpoints } from '@/api/endpoints' const data = Object.entries(updatedAttendance).map(([coworkerId, updates]) => ({ CoworkerId: Number(coworkerId), ...updates, })) await httpClient.put(endpoints.teams.attendanceUpdate(teamId), data) ``` ## Usage in Portal | Context | Source file | | ------------------------------------------------------ | -------------------------------------------------------------------- | | Attendance matrix editor (`/team/attendance/{teamId}`) | `src/views/user/team/attendance/components/TeamAttendanceMatrix.tsx` | ## Error Responses The customer is not authenticated or the session has expired. The customer is not an administrator of the specified team. Invalid request data — for example, an invalid attendance value or unknown member ID. Team with the specified ID does not exist. ## Related Endpoints | Method | Endpoint | Description | | ------ | --------------------------------------- | --------------------------- | | `GET` | `/api/public/teams/{teamId}/attendance` | Get current attendance data | | `GET` | `/api/public/teams/{teamId}/kpi` | Team KPI data | | `GET` | `/api/public/teams/{teamId}/profile` | Full team profile | | `GET` | `/api/public/teams/my` | List the customer's teams | # Get Team Profile Source: https://learn.nexudus.com/api/endpoints/teams/team-details GET /api/public/teams/{teamId}/profile Returns the full profile for a single team, including members, billing settings, and social links. # Get Team Profile Returns the complete profile for a specific team, including member lists, billing configuration, social media links, and media flags. Team administrators use this to manage the team's public profile; regular members use it for read-only access. A **team** is a group of customers within a coworking location that can share resources, bookings, and billing. The portal maps teams to companies or departments that co-habit a space. ## Authentication Requires a valid customer bearer token. The customer must be a member or administrator of the requested team. ## Path Parameters Numeric identifier of the team. Returned as `Id` in the `Records` array from [`GET /api/public/teams/my`](/api/endpoints/teams/list-teams). ## Query Parameters Comma-separated dot-notated field paths to include in the response. When provided, only the specified fields are returned — useful for reducing payload size. **Example**: `_shape=Name,ProfileSummary,ProfileIsPublic,TeamMembers` ## Response Returns a single team profile object (not wrapped in a list envelope). ### Core Fields Unique integer identifier. Use as `{teamId}` in all team-scoped endpoints. UUID for the team — stable across renames and useful as a cache key. String cast of `Id`. Provided for environments that lose integer precision. Display name of the team. ### Profile Full-length team description. May contain HTML. Short tagline shown in team cards and selectors. When `true`, the team profile is visible in the public member directory. Team website URL. Space-separated tag string. Use `ProfileTagsList` for array access. Pre-split array of tag strings derived from `ProfileTags`. ### Location Name of the coworking location this team belongs to. URL of the coworking location's home page. ### Social Media All social fields are `string | null`. Provide a full URL unless stated otherwise. | Field | Description | | ----------- | ------------------------- | | `Twitter` | X / Twitter profile URL | | `Facebook` | Facebook page URL | | `Linkedin` | LinkedIn company page URL | | `Instagram` | Instagram profile URL | | `Github` | GitHub org or user URL | | `Pinterest` | Pinterest profile URL | | `Skype` | Skype username | | `Telegram` | Telegram handle | | `Flickr` | Flickr profile URL | | `Vimeo` | Vimeo channel URL | | `Tumblr` | Tumblr blog URL | | `Blogger` | Blogger profile URL | ### Members Total count of active members (admins + regular members). Display names of all team admins. Full `Customer` objects for admins only. Full `Customer` objects for non-admin members. Combined `Customer` objects for all members (admins + regular). Use this instead of merging the two arrays above. ### Billing & Configuration Customer ID of the member who receives consolidated invoices, if `CreateSingleInvoiceForTeam` is `true`. When `true`, all team charges are rolled into a single invoice addressed to `PayingMemberId`. Maximum allowed members. `null` means unlimited. Whether billing/contact details have been configured for this team. Whether the team has a default membership plan assigned. ID of the default membership plan assigned to new team members. Display name of the default membership plan. When `true`, new members added to the team are placed on hold until manually activated. When `true`, the attendance dashboard is hidden for this team. Note the typo in the field name (`Attendace`) — it is preserved as-is in the API. Percentage discount applied to charges for team members. Percentage discount applied to extra services for team members. Percentage discount applied to membership plans for team members. Percentage discount applied to time passes for team members. When `true`, the team has an associated community discussion group. Google Maps link for the team's location. ### Media `true` if the team has an uploaded logo. Construct the logo URL as: `https://[space].spaces.nexudus.com/api/public/teams/{Id}/logo` `true` if profile image 1 has been uploaded. `true` if profile image 2 has been uploaded. `true` if profile image 3 has been uploaded. Convenience flag — `true` if any of the three profile images are present. ### Timestamps All datetime fields are ISO 8601 strings. `*On` fields are in the location's local timezone; `*OnUtc` fields are UTC. Local datetime the team was created. UTC datetime the team was created. Local datetime of the last update. UTC datetime of the last update. ## Examples ### Fetch full team profile ```http theme={null} GET /api/public/teams/55/profile Authorization: Bearer {token} ``` ```json theme={null} { "Id": 55, "IdString": "55", "UniqueId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "Name": "Tech Innovators", "Description": "A collaborative team focused on cutting-edge technology solutions", "ProfileSummary": "Building the future, one innovation at a time", "ProfileIsPublic": true, "ProfileWebsite": "https://techinnovators.example.com", "ProfileTags": "technology startup innovation collaboration", "ProfileTagsList": ["technology", "startup", "innovation", "collaboration"], "BusinessName": "Downtown Coworking Hub", "BusinessHomeUrl": "https://downtown-hub.example.com", "Twitter": "https://twitter.com/techinnovators", "Facebook": null, "Linkedin": "https://linkedin.com/company/techinnovators", "Instagram": null, "Github": "https://github.com/techinnovators", "Pinterest": null, "Skype": null, "Telegram": null, "Flickr": null, "Vimeo": null, "Tumblr": null, "Blogger": null, "TeamMembersCount": 12, "TeamAdministratorsFullNames": ["Jane Smith", "John Doe"], "TeamAdministrators": [ { "Id": 101, "FullName": "Jane Smith", "Email": "jane@techinnovators.com" } ], "TeamMembers": [ { "Id": 102, "FullName": "Bob Wilson", "Email": "bob@techinnovators.com" } ], "AllTeamMembers": [ { "Id": 101, "FullName": "Jane Smith", "Email": "jane@techinnovators.com" }, { "Id": 102, "FullName": "Bob Wilson", "Email": "bob@techinnovators.com" } ], "PayingMemberId": 101, "CreateSingleInvoiceForTeam": true, "HasContactDetails": true, "HasDefaultPlan": true, "MaxTeamMemberCount": 20, "DisableAttendaceDashboard": false, "HasTeamLogo": true, "HasImage1": true, "HasImage2": false, "HasImage3": false, "HasImages": true, "CreatedOn": "2024-01-15T09:30:00", "UpdatedOn": "2024-07-20T14:22:33", "CreatedOnUtc": "2024-01-15T09:30:00Z", "UpdatedOnUtc": "2024-07-20T14:22:33Z" } ``` ### Fetch profile with a minimal field set Use `_shape` to request only the fields your UI needs, reducing payload size. ```http theme={null} GET /api/public/teams/55/profile?_shape=Name,ProfileSummary,ProfileIsPublic,TeamMembersCount Authorization: Bearer {token} ``` ```json theme={null} { "Name": "Tech Innovators", "ProfileSummary": "Building the future, one innovation at a time", "ProfileIsPublic": true, "TeamMembersCount": 12 } ``` ## TypeScript Integration ```typescript theme={null} import { endpoints } from '@/api/endpoints' import { Team } from '@/types/endpoints/TeamList' import { useData } from '@/hooks/useData' const { resource: team } = useData(httpClient, endpoints.teams.one(teamId), { shape: { fields: ['Name', 'ProfileWebsite', 'ProfileSummary', 'ProfileTagsList', 'ProfileIsPublic', 'TeamMembers'], }, }) ``` ## Usage in Portal | Context | Source file | | --------------------------------------------------------- | ------------------------------------------------------------- | | Team Professional Profile Page (`/team/profile/{teamId}`) | `src/views/user/team/profile/TeamProfessionalProfilePage.tsx` | | Team Dashboard (`/dashboard/team/{teamId}`) | `src/views/user/dashboards/team/TeamDashboardPage.tsx` | | Team Permissions (`/team/permissions/{teamId}`) | `src/views/user/team/permissions/TeamPermissionsPage.tsx` | | Team Bookings (`/team/bookings/{teamId}`) | `src/views/user/team/bookings/TeamBookingsPage.tsx` | ## Error Responses The customer is not authenticated, the session has expired, or the customer is not a member of the specified team. Team with the specified ID does not exist. ## Related Endpoints | Method | Endpoint | Description | | ------ | --------------------------------------- | -------------------------------- | | `GET` | `/api/public/teams/my` | List the customer's teams | | `PUT` | `/api/public/teams/{teamId}/profile` | Update team profile (admin only) | | `GET` | `/api/public/teams/{teamId}/kpi` | Team KPI metrics | | `GET` | `/api/public/teams/{teamId}/attendance` | Team attendance data | | `GET` | `/api/public/teams/{teamId}/metrics` | Team performance metrics | # Update Team Profile Source: https://learn.nexudus.com/api/endpoints/teams/team-details-update PUT /api/public/teams/{teamId}/profile Updates the profile, social links, and public visibility settings for a team. # Update Team Profile Updates the profile information for a specific team, including display name, social media links, and public visibility. Only team administrators can call this endpoint; partial updates are supported. ## Authentication Requires a valid customer bearer token. The customer must be a team administrator of the specified team. ## Path Parameters Numeric identifier of the team. Returned as `Id` in the `Records` array from [`GET /api/public/teams/my`](/api/endpoints/teams/list-teams). ## Request Body The request body should contain the team profile fields to update. Only include fields that are being modified — partial updates are supported. ### Basic Information Display name of the team. Cannot be empty. Full-length team description. May contain HTML. Omit to leave unchanged. Short tagline shown in team cards and selectors. When `true`, the team profile is visible in the public member directory. Team website URL. Must be a valid URL format when provided. Space-separated tags describing the team. ### Social Media All social media fields are optional `string` values. Must be valid URL format when provided (except `Skype` which accepts a username). | Field | Description | | ----------- | ------------------------- | | `Twitter` | X / Twitter profile URL | | `Facebook` | Facebook page URL | | `Linkedin` | LinkedIn company page URL | | `Instagram` | Instagram profile URL | | `Github` | GitHub org or user URL | | `Pinterest` | Pinterest profile URL | | `Skype` | Skype username | | `Telegram` | Telegram handle | | `Flickr` | Flickr profile URL | | `Vimeo` | Vimeo channel URL | | `Tumblr` | Tumblr blog URL | | `Blogger` | Blogger profile URL | ## Response Returns HTTP `200 OK` with an empty body on success. ## Examples ### Update team name and social links ```http theme={null} PUT /api/public/teams/55/profile Authorization: Bearer {token} Content-Type: application/json ``` ```json theme={null} { "Name": "Tech Innovators Updated", "ProfileSummary": "Building the future, one innovation at a time — now with AI focus", "ProfileIsPublic": true, "ProfileWebsite": "https://techinnovators-ai.example.com", "ProfileTags": "technology startup innovation collaboration AI machine-learning", "Twitter": "https://twitter.com/techinnovators_ai", "Linkedin": "https://linkedin.com/company/techinnovators-ai", "Github": "https://github.com/techinnovators-ai" } ``` ``` Status: 200 OK Body: (empty) ``` ## TypeScript Integration ```typescript theme={null} import { endpoints } from '@/api/endpoints' import { Team } from '@/types/endpoints/TeamList' const updateTeamProfile = async (teamId: number, profileData: Partial) => { await httpClient.put(endpoints.teams.one(teamId), profileData) } ``` ## Usage in Portal | Context | Source file | | --------------------------------------------------------- | -------------------------------------------------------------------- | | Team Professional Profile Page (`/team/profile/{teamId}`) | `src/views/user/team/profile/TeamProfessionalProfilePage.tsx` | | Team Professional Profile form component | `src/views/user/team/profile/components/TeamProfessionalProfile.tsx` | ## Error Responses The customer is not authenticated or the session has expired. The customer is not an administrator of the specified team. Invalid request data — for example, missing required `Name` field or invalid URL format in a social media field. Team with the specified ID does not exist. ## Related Endpoints | Method | Endpoint | Description | | ------ | --------------------------------------- | ------------------------- | | `GET` | `/api/public/teams/{teamId}/profile` | Get current team profile | | `GET` | `/api/public/teams/my` | List the customer's teams | | `GET` | `/api/public/teams/{teamId}/kpi` | Team KPI metrics | | `GET` | `/api/public/teams/{teamId}/attendance` | Team attendance data | | `GET` | `/api/public/teams/{teamId}/metrics` | Team performance metrics | # Update Team Profile Images Source: https://learn.nexudus.com/api/endpoints/teams/team-images-update PATCH /api/public/teams/{teamId}/profile/images Uploads, replaces, or deletes team profile images (logo and up to 3 additional images). # Update Team Profile Images Uploads, replaces, or deletes team profile images, including the team logo and up to 3 additional images. Only team administrators can call this endpoint. ## Authentication Requires a valid customer bearer token. The customer must be a team administrator of the specified team. ## Path Parameters Numeric identifier of the team. Returned as `Id` in the `Records` array from [`GET /api/public/teams/my`](/api/endpoints/teams/list-teams). ## Request Body The request body can include **either** Base64-encoded images to upload/replace **or** delete flags to remove existing images. You can combine both in a single request. ### Upload or Replace Images Provide the full Base64-encoded image data (including the data URI prefix, e.g. `data:image/png;base64,...`) for any image you want to upload or replace. Full Base64-encoded string for the team logo, including the data URI prefix (e.g. `data:image/png;base64,iVBORw0KGgo...`). Omit or set to `null` to leave unchanged. Full Base64-encoded string for the first team image. Omit or set to `null` to leave unchanged. Full Base64-encoded string for the second team image. Omit or set to `null` to leave unchanged. Full Base64-encoded string for the third team image. Omit or set to `null` to leave unchanged. ### Delete Images Set the corresponding delete flag to `true` to remove an existing image. Set to `true` to delete the current team logo. Default is `false`. Set to `true` to delete the current first team image. Default is `false`. Set to `true` to delete the current second team image. Default is `false`. Set to `true` to delete the current third team image. Default is `false`. ## Response Returns HTTP `200 OK` with an empty body on success. ## Examples ### Upload a new team logo ```http theme={null} PATCH /api/public/teams/55/profile/images Authorization: Bearer {token} Content-Type: application/json ``` ```json theme={null} { "Base64TeamLogo": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==" } ``` ``` Status: 200 OK Body: (empty) ``` ### Delete an existing team image ```http theme={null} PATCH /api/public/teams/55/profile/images Authorization: Bearer {token} Content-Type: application/json ``` ```json theme={null} { "DeleteTeamImage1": true } ``` ``` Status: 200 OK Body: (empty) ``` ### Replace logo and delete an old image in one request ```http theme={null} PATCH /api/public/teams/55/profile/images Authorization: Bearer {token} Content-Type: application/json ``` ```json theme={null} { "Base64TeamLogo": "data:image/jpeg;base64,/9j/4AAQSkZJRg...", "DeleteTeamImage2": true } ``` ``` Status: 200 OK Body: (empty) ``` ## TypeScript Integration ```typescript theme={null} import { endpoints } from '@/api/endpoints' const updateTeamImages = async ( teamId: number, imagePayload: { base64TeamLogo?: string | null base64TeamImage1?: string | null base64TeamImage2?: string | null base64TeamImage3?: string | null deleteTeamLogo?: boolean deleteTeamImage1?: boolean deleteTeamImage2?: boolean deleteTeamImage3?: boolean } ) => { await httpClient.patch( endpoints.teams.patchImages(teamId), imagePayload ) } ``` ## Usage in Portal | Context | Source file | | -------------------------------------------------------------- | -------------------------------------------------------------------- | | Team Professional Profile Page (`/team/profile/{teamId}`) | `src/views/user/team/profile/TeamProfessionalProfilePage.tsx` | | Team Professional Profile form component (image upload fields) | `src/views/user/team/profile/components/TeamProfessionalProfile.tsx` | ## Error Responses The customer is not authenticated or the session has expired. The customer is not an administrator of the specified team. Invalid request data — for example, malformed Base64 encoding. Team with the specified ID does not exist. ## Related Endpoints | Method | Endpoint | Description | | ------ | ------------------------------------ | -------------------------- | | `PUT` | `/api/public/teams/{teamId}/profile` | Update team profile fields | | `GET` | `/api/public/teams/{teamId}/profile` | Get current team profile | | `GET` | `/api/public/teams/my` | List the customer's teams | | `GET` | `/api/public/teams/{teamId}/kpi` | Team KPI metrics | # Get Team KPIs Source: https://learn.nexudus.com/api/endpoints/teams/team-kpi GET /api/public/teams/{teamId}/kpi Returns per-member KPI data for a team, including uninvoiced charges, remaining credits, and usage totals. # Get Team KPIs Returns key performance indicators for every member of a team. Each entry includes uninvoiced charges, remaining booking and time credits, and total/monthly usage. Used on the team dashboard to give administrators a quick financial and usage overview. ## Authentication Requires a valid customer bearer token. The customer must be a team administrator of the specified team. ## Path Parameters Numeric identifier of the team. Returned as `Id` from [`GET /api/public/teams/my`](/api/endpoints/teams/list-teams). ## Query Parameters Comma-separated list of field paths to include in the response. When provided, only the specified fields are returned — useful for reducing payload size. Supports nested paths using dot notation. ## Response Array of per-member KPI objects. ### Per-Member Fields Numeric identifier of the team member. Display name of the team member. Email address of the team member. Count of purchased products not yet invoiced. Count of extra services not yet invoiced. Count of event attendee charges not yet invoiced. Note the typo (`Univoiced`) — it is preserved as-is in the API. Count of time passes not yet invoiced. Note the typo (`Univoiced`) — it is preserved as-is in the API. Remaining booking credit balance. Remaining time credit in minutes. Remaining time credit in days. Remaining time credit in weeks. Remaining time credit in months. Remaining time credit uses. Remaining time pass minutes. Remaining time pass count. Total booked time in minutes across all time. Total booked time in minutes for the current month. Total checked-in time in minutes across all time. Total checked-in time in minutes for the current month. ## Examples ### Fetch team KPIs ```http theme={null} GET /api/public/teams/55/kpi Authorization: Bearer {token} ``` ```json theme={null} { "Kpi": [ { "CoworkerId": 101, "CoworkerFullName": "Jane Smith", "CoworkerEmail": "jane@techinnovators.com", "UninvoicedProducts": 2, "UninvoicedExtraServices": 0, "UnivoicedEventAttendees": 1, "UnivoicedTimepasses": 0, "RemainingBookingCredit": 500, "RemainingTimeCreditMinutes": 120, "RemainingTimeCreditDays": 0, "RemainingTimeCreditWeeks": 0, "RemainingTimeCreditMonths": 0, "RemainingTimeCreditUses": 5, "RemainingTimePassesMinutes": 60, "RemainingTimePassesCount": 1, "BookedTimeTotal": 4200, "BookedTimeThisMonth": 360, "CheckedTimeTotal": 3800, "CheckedTimeThisMonth": 300 } ] } ``` ## TypeScript Integration ```typescript theme={null} import { endpoints } from '@/api/endpoints' import { TeamKpiList } from '@/types/endpoints/TeamKpi' import { useData } from '@/hooks/useData' const { resource: kpiData } = useData(httpClient, endpoints.teams.kpi(teamId), { shape: { fields: ['Kpi'] } }) ``` ## Usage in Portal | Context | Source file | | ------------------------------------------------------- | -------------------------------------------------------------- | | Team dashboard KPI section (`/dashboard/team/{teamId}`) | `src/views/user/dashboards/team/components/TeamKpiSection.tsx` | ## Error Responses The customer is not authenticated or the session has expired. Team with the specified ID does not exist. ## Related Endpoints | Method | Endpoint | Description | | ------ | --------------------------------------- | ------------------------- | | `GET` | `/api/public/teams/{teamId}/metrics` | Team performance metrics | | `GET` | `/api/public/teams/{teamId}/attendance` | Team attendance data | | `GET` | `/api/public/teams/{teamId}/profile` | Full team profile | | `GET` | `/api/public/teams/my` | List the customer's teams | # Get Team Meta Source: https://learn.nexudus.com/api/endpoints/teams/team-meta GET /api/public/teams/{teamGuidId}/meta Returns lightweight metadata for a team, including its name, member cap, and default plan. # Get Team Meta Returns a minimal metadata object for a team identified by its GUID. Used during checkout flows to resolve team details without loading the full profile — for example, to display the team name and validate member limits when signing up for a tariff. ## Authentication Requires a valid customer bearer token. ## Path Parameters The team's UUID (`UniqueId`). Returned as `UniqueId` from [`GET /api/public/teams/my`](/api/endpoints/teams/list-teams). ## Query Parameters Comma-separated list of field paths to include in the response. When provided, only the specified fields are returned — useful for reducing payload size. Supports nested paths using dot notation. ## Response Returns a flat object with core team metadata. Numeric identifier for the team. Display name of the team. Maximum allowed members. `0` or absent means unlimited. The team's default membership plan, if one is assigned. Numeric identifier of the default plan. UUID of the default plan. Display name of the default plan. ## Examples ### Fetch team meta by GUID ```http theme={null} GET /api/public/teams/a1b2c3d4-e5f6-7890-abcd-ef1234567890/meta Authorization: Bearer {token} ``` ```json theme={null} { "Id": 55, "Name": "Tech Innovators", "MaxTeamMemberCount": 20, "Tariff": { "Id": 301, "UniqueId": "f1a2b3c4-d5e6-7890-abcd-ef1234567890", "Name": "Team Professional" } } ``` ## TypeScript Integration ```typescript theme={null} import { endpoints } from '@/api/endpoints' const endpoint = endpoints.teams.meta(teamGuidId) const { data } = await httpClient.get(endpoint.url) ``` ## Usage in Portal | Context | Source file | | ------------------------------------ | ----------------------------------------------- | | Tariff signup step (`/checkout/...`) | `src/views/checkout/steps/TariffSignupStep.tsx` | ## Error Responses The customer is not authenticated or the session has expired. No team exists with the specified GUID. ## Related Endpoints | Method | Endpoint | Description | | ------ | ------------------------------------ | ------------------------- | | `GET` | `/api/public/teams/my` | List the customer's teams | | `GET` | `/api/public/teams/{teamId}/profile` | Full team profile | | `GET` | `/api/public/teams/{teamId}/kpi` | Team KPI metrics | # Get Team Metrics Source: https://learn.nexudus.com/api/endpoints/teams/team-metrics GET /api/public/teams/{teamId}/metrics Returns monthly financial and usage metrics for a team, including invoiced amounts, bookings, and check-in time. # Get Team Metrics Returns an array of monthly metric snapshots for a team. Each entry covers one calendar month and includes invoiced amounts, booking and check-in minutes, revenue, and outstanding charges. Used on the team dashboard to render trend charts. ## Authentication Requires a valid customer bearer token. The customer must be a team administrator of the specified team. ## Path Parameters Numeric identifier of the team. Returned as `Id` from [`GET /api/public/teams/my`](/api/endpoints/teams/list-teams). ## Query Parameters Comma-separated list of field paths to include in the response. When provided, only the specified fields are returned — useful for reducing payload size. Supports nested paths using dot notation. ## Response Array of monthly metric snapshots, ordered chronologically. ### Per-Month Fields Unique identifier for the metric record. ISO 8601 date representing the first day of the month this record covers. ISO 4217 currency code for all monetary values in this record. Total invoiced amount for the member in this month. Total invoiced amount across the entire team in this month. Total revenue for the team in this month. Member's checked-in time in minutes. Total team checked-in time in minutes. Member's booked time in minutes. Total team booked time in minutes. Total number of bookings. Total number of active membership plans. Total other charges. Number of time passes used. Revenue from bookings. Total unpaid amount. Total unpaid NexKiosk charges. Total amount currently due. Unpaid event attendee charges. Total charges not yet invoiced. Uninvoiced miscellaneous charges. Uninvoiced product charges. Uninvoiced time pass charges. Uninvoiced extra service charges. ISO 8601 datetime of the next scheduled invoice, or `null` if none is scheduled. Days since the member's last portal access. Note the typo (`Dasy`) — it is preserved as-is in the API. ## Examples ### Fetch team metrics ```http theme={null} GET /api/public/teams/55/metrics Authorization: Bearer {token} ``` ```json theme={null} { "Metrics": [ { "Id": 1001, "MonthDate": "2025-01-01T00:00:00", "CurrencyCode": "GBP", "InvoicedAmount": 1250.0, "TeamInvoicedAmount": 8500.0, "Revenue": 8500.0, "CheckingMinutes": 2400, "TeamCheckingMinutes": 18000, "BookingMinutes": 480, "TeamBookingMinutes": 3200, "TotalBookings": 15, "TotalTariffs": 12, "TotalOther": 0, "TimePasses": 3, "Bookings": 450.0, "TotalUnpaid": 200.0, "TotalUnpaidNexKiosk": 0, "TotalDue": 200.0, "UnPaidAttendees": 0, "NotInvoicedCharges": 50.0, "UnInvoicedCharges": 25.0, "UnInvoicedProducts": 15.0, "UnInvoicedTimePasses": 10.0, "UnInvoicedExtraServices": 0, "NextInvoice": "2025-02-01T00:00:00", "DasySinceLastAccess": 2 } ] } ``` ## TypeScript Integration ```typescript theme={null} import { endpoints } from '@/api/endpoints' import { TeamMetrics } from '@/types/endpoints/TeamMetrics' import { useData } from '@/hooks/useData' const { resource: metricsData } = useData(httpClient, endpoints.teams.metrics(teamId)) ``` ## Usage in Portal | Context | Source file | | ----------------------------------------------------------- | ------------------------------------------------------------------ | | Team dashboard metrics section (`/dashboard/team/{teamId}`) | `src/views/user/dashboards/team/components/TeamMetricsSection.tsx` | ## Error Responses The customer is not authenticated or the session has expired. Team with the specified ID does not exist. ## Related Endpoints | Method | Endpoint | Description | | ------ | --------------------------------------- | ------------------------- | | `GET` | `/api/public/teams/{teamId}/kpi` | Per-member KPI data | | `GET` | `/api/public/teams/{teamId}/attendance` | Team attendance data | | `GET` | `/api/public/teams/{teamId}/profile` | Full team profile | | `GET` | `/api/public/teams/my` | List the customer's teams | # Update Member Permissions Source: https://learn.nexudus.com/api/endpoints/teams/team-permissions PUT /api/public/teams/{teamId}/permissions/{memberId} Updates the permission flags for a specific member within a team. # Update Member Permissions Updates the permission flags for a single team member, controlling what actions they can perform within the team context — such as making bookings, purchasing products, or accessing community features. Only team administrators can modify permissions. An administrator cannot change their own `IsTeamAdministrator` flag. ## Authentication Requires a valid customer bearer token. The customer must be a team administrator of the specified team. ## Path Parameters Numeric identifier of the team. Returned as `Id` from [`GET /api/public/teams/my`](/api/endpoints/teams/list-teams). Numeric identifier of the member whose permissions are being updated. Returned as `Id` in the `AllTeamMembers` array from [`GET /api/public/teams/ {teamId}/profile`](/api/endpoints/teams/team-details). ## Request Body Member ID (mirrors the path parameter). When `true`, grants the member full administrative rights. Disabled when editing one's own permissions. When `true`, the member can create bookings. When `true`, the member can create bookings on behalf of the team. When `true`, the member can purchase products. When `true`, the member can purchase event tickets. When `true`, the member can access community features (directory, discussion boards). Access card identifier for physical access control. Maximum 15 characters. ## Response Returns HTTP `200 OK` with an empty body on success. ## Examples ### Grant admin rights and booking permissions ```http theme={null} PUT /api/public/teams/55/permissions/102 Authorization: Bearer {token} Content-Type: application/json ``` ```json theme={null} { "Id": 102, "IsTeamAdministrator": false, "CanMakeBookings": true, "CanBookForTeam": true, "CanPurchaseProducts": true, "CanPurchaseEvents": false, "CanAccessCommunity": true, "AccessCardId": "CARD-00102" } ``` ``` Status: 200 OK Body: (empty) ``` ## TypeScript Integration ```typescript theme={null} import { endpoints } from '@/api/endpoints' await httpClient.put(endpoints.teams.permissions(teamId, memberId), { IsTeamAdministrator: false, CanMakeBookings: true, CanBookForTeam: true, CanPurchaseProducts: true, CanPurchaseEvents: false, CanAccessCommunity: true, }) ``` ## Usage in Portal | Context | Source file | | ----------------------------------------------------- | -------------------------------------------------------------------- | | Team permissions modal (`/team/permissions/{teamId}`) | `src/views/user/team/permissions/components/TeamPermissionModal.tsx` | ## Error Responses The customer is not authenticated or the session has expired. The customer is not an administrator of the specified team. Invalid request data — for example, `AccessCardId` exceeding 15 characters. Team or member with the specified ID does not exist. ## Related Endpoints | Method | Endpoint | Description | | -------- | ------------------------------------------------- | ------------------------------ | | `GET` | `/api/public/teams/{teamId}/profile` | Full team profile with members | | `POST` | `/api/public/teams/{teamId}/members` | Add members to a team | | `DELETE` | `/api/public/teams/{teamId}/members/{coworkerId}` | Remove a member from a team | | `GET` | `/api/public/teams/my` | List the customer's teams | # List Team Profiles Source: https://learn.nexudus.com/api/endpoints/teams/team-profiles GET /en/team/profiles Returns team profile summaries including member lists, permissions, and recent bookings for the booking flow. # List Team Profiles Returns an array of team profile summaries for teams the authenticated customer belongs to. Each entry includes the team's details, permission flags (can add/remove/cancel members), all team members with their contracts, and recent bookings. Primarily used in the booking flow to populate the "book for team" selector. This endpoint uses a view-style URL (`/en/team/profiles`) rather than the `/api/public/` convention. It returns server-rendered JSON and is called with the `bookForTeam=true` query parameter in the booking context. ## Authentication Requires a valid customer bearer token. ## Query Parameters When `true`, scopes the response to teams the customer can book on behalf of. Added conditionally in the booking flow. Comma-separated list of field paths to include in the response. When provided, only the specified fields are returned — useful for reducing payload size. Supports nested paths using dot notation. ## Response Returns an array of `TeamProfile` objects (not wrapped in a list envelope). ### TeamProfile Fields Whether the authenticated customer can add new members to this team. Whether the authenticated customer can remove members from this team. Whether the authenticated customer can cancel member contracts in this team. Full team object with the same fields as the response from [`GET /api/public/teams/{teamId}/profile`](/api/endpoints/teams/team-details). Recent bookings made by team members. Extended member objects that include contract information alongside standard `Customer` fields. Active contracts for this member, including plan name, start date, next invoice date, price, and cancellation details. ## Examples ### Fetch team profiles for booking ```http theme={null} GET /en/team/profiles?bookForTeam=true Authorization: Bearer {token} ``` ```json theme={null} [ { "CanAddNewMembers": true, "CanRemoveMembers": true, "CanCancelMembers": false, "Team": { "Id": 55, "Name": "Tech Innovators", "BusinessName": "Downtown Coworking Hub", "TeamMembersCount": 12, "ProfileSummary": "Building the future", "MaxTeamMemberCount": 20 }, "RecentBookings": null, "AllTeamMembers": [ { "Id": 101, "FullName": "Jane Smith", "Email": "jane@techinnovators.com", "Contracts": [ { "Id": 5001, "StartDate": "2024-01-15T00:00:00", "NextInvoice": "2025-02-01T00:00:00", "Price": 250.0, "CurrencyCode": "GBP" } ] } ] } ] ``` ## TypeScript Integration ```typescript theme={null} import { endpoints } from '@/api/endpoints' import { TeamProfiles } from '@/types/endpoints/TeamProfiles' import { useData } from '@/hooks/useData' const { resource: teamProfiles } = useData(httpClient, endpoints.teams.profiles) ``` ## Usage in Portal | Context | Source file | | -------------------------------------------- | ------------------------------------------------------ | | Booking flow team selector (`/checkout/...`) | `src/views/public/checkout/booking/useBookingData.tsx` | ## Error Responses The customer is not authenticated or the session has expired. ## Related Endpoints | Method | Endpoint | Description | | ------ | ------------------------------------ | ------------------------- | | `GET` | `/api/public/teams/my` | List the customer's teams | | `GET` | `/api/public/teams/{teamId}/profile` | Full team profile | | `POST` | `/api/public/teams/{teamId}/members` | Add members to a team | # Register Visitor Source: https://learn.nexudus.com/api/endpoints/visitors/create-visitor POST /api/public/visitors Registers a new visitor for the authenticated customer. # Register Visitor Registers a new visitor expected at the coworking space. The visitor receives a notification and the front desk is alerted when they arrive. ## Authentication Requires a valid customer bearer token. ## Request Body The request body is an **array** of visitor objects. Multiple visitors can be registered in a single request (e.g. for recurring visits). Numeric identifier of the location where the visitor is expected. Full name of the visitor. Email address of the visitor (for notifications). Phone number of the visitor. Expected arrival date/time in ISO 8601 format. Notes from the host for the visitor or front desk. ## Response Returns a `200 OK` on success. ## Examples ### Register a visitor ```http theme={null} POST /api/public/visitors Authorization: Bearer {token} Content-Type: application/json [ { "BusinessId": 1, "FullName": "Sarah Connor", "Email": "sarah@example.com", "PhoneNumber": "+44 7700 900000", "ExpectedArrival": "2026-04-01T10:00:00Z", "CustomerNotes": "Meeting in room 3" } ] ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' const visitors = repeatDates.map((date) => ({ BusinessId: values.BusinessId, FullName: values.FullName, Email: values.Email, PhoneNumber: values.PhoneNumber, ExpectedArrival: date.toJSDate(), CustomerNotes: values.CustomerNotes, })) await httpClient.post(endpoints.visitors.create, visitors) ``` # Delete Visitor Source: https://learn.nexudus.com/api/endpoints/visitors/delete-visitor DELETE /api/public/visitors/{visitorId} Removes a registered visitor. # Delete Visitor Cancels and removes a visitor registration. The visitor will no longer receive arrival notifications. ## Authentication Requires a valid customer bearer token. ## Path Parameters Numeric identifier of the visitor to remove. ## Response Returns a `200 OK` on success. ## Examples ### Delete a visitor ```http theme={null} DELETE /api/public/visitors/55 Authorization: Bearer {token} ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' await httpClient.delete(endpoints.visitors.delete(55)) ``` # List Visitors Source: https://learn.nexudus.com/api/endpoints/visitors/list-visitors GET /api/public/visitors/my Returns the authenticated customer's registered visitors. # List Visitors Returns the list of visitors registered by the authenticated customer. Optionally filter to only upcoming visits. ## Authentication Requires a valid customer bearer token. ## Query Parameters `true` — return only future visits. `false` or omitted — return all visitors. Comma-separated list of field paths to include in the response. When provided, only the specified fields are returned — useful for reducing payload size. Supports nested paths using dot notation. Example: `_shape=Records.FullName,Records.ExpectedArrival,Records.Arrived`. ## Response Returns a `VisitorList` object containing an array of visitor records. ### Visitor Fields #### Identity | Field | Type | Description | | ---------- | -------- | ----------------------------------------- | | `Id` | `number` | Unique numeric identifier for the visitor | | `UniqueId` | `string` | Globally unique identifier | #### Core | Field | Type | Description | | ------------- | ---------------- | ------------------------------ | | `FullName` | `string` | Visitor's full name | | `Email` | `string` | Visitor's email address | | `PhoneNumber` | `string` | Visitor's phone number | | `Notes` | `string \| null` | Customer notes about the visit | #### Schedule | Field | Type | Description | | -------------------- | ---------------- | -------------------------------------- | | `ExpectedArrival` | `string \| null` | Expected arrival (business-local time) | | `UtcExpectedArrival` | `string \| null` | Expected arrival (UTC) | | `ArrivalDate` | `string \| null` | Actual arrival date (business-local) | | `UtcArrivalDate` | `string \| null` | Actual arrival date (UTC) | | `Arrived` | `boolean` | Whether the visitor has arrived | #### Media | Field | Type | Description | | --------------------- | ---------------- | ------------------------------------- | | `GravatarHashedEmail` | `string \| null` | MD5-hashed email for Gravatar lookups | | `DefaultAvatarUrl` | `string \| null` | Generated avatar URL from initials | #### Timestamps (from base) | Field | Type | Description | | -------------- | ---------------- | --------------------------------------- | | `CreatedOn` | `string` | Date created (business-local time) | | `UpdatedOn` | `string \| null` | Date last updated (business-local time) | | `CreatedOnUtc` | `string` | Date created (UTC) | | `UpdatedOnUtc` | `string \| null` | Date last updated (UTC) | ## Examples ### Fetch upcoming visitors ```http theme={null} GET /api/public/visitors/my?showUpcoming=true Authorization: Bearer {token} ``` ## TypeScript Integration ```typescript theme={null} import endpoints from '@/api/endpoints' const { resource: visitors } = useTypedData(httpClient, endpoints.visitors.list(true)) ``` # Public API Source: https://learn.nexudus.com/api/overview A comprehensive guide to the Nexudus Members Portal API The Nexudus Members Portal is a front-end only application that connects to the Nexudus API backend. This API provides comprehensive access to all the functionality available in the portal interface, enabling developers to integrate portal features into custom applications, mobile apps, or third-party systems. This portal application does not have its own backend - it connects directly to the Nexudus API infrastructure for all data operations using a client-side architecture. ## Base URL Structure The API endpoints follow two primary URL patterns: * **API Endpoints**: `https://[your-space].spaces.nexudus.com/api/public/...` * **Localized Endpoints**: `https://[your-space].spaces.nexudus.com/{lang}/...` ### HTTP Methods The API primarily uses these HTTP methods: * `GET` - Retrieve data (most common) * `POST` - Create resources and submit data * `PUT` - Update existing resources * `DELETE` - Remove resources * `PATCH` - Update resources partially ### Response Format API responses return JSON with consistent structures. List endpoints follow the `ApiListResult` pattern: ```json theme={null} { "Records": [ /* array of items */ ], "CurrentPageSize": 20, "CurrentPage": 1, "CurrentOrderField": "Name", "CurrentSortDirection": "ASC", "FirstItem": 1, "HasNextPage": true, "HasPreviousPage": false, "LastItem": 20, "PageNumber": 1, "PageSize": 20, "TotalItems": 150, "TotalPages": 8 } ``` ### Single-record Responses For single-record endpoints. ```json theme={null} { "Resource": { ... } } ``` ### Error Handling Error responses generally use HTTP 400 status code with and error code: ```json theme={null} { "Invalid booking date - start date cannot be in the past" } ``` When authentication fails or the user does not have permission to make a specific request, the API returns a 401 status code; ## API Client Implementation The portal uses a custom HTTP client based on Axios with these characteristics: * Bearer token authentication * Timezone-aware requests (`X-Use-Timezone` header). * JSON content type by default ## Request Shaping The API supports request shaping to optimize response size: ```typescript theme={null} // Example of request shaping const shape = ['BlogPost.Id', 'BlogPost.Title', 'BlogPost.AllowComments', 'BlogPost.UpdatedOn', 'BlogPost.Comments.Id', 'BlogPost.Comments.Text'] // URL with shape parameter const url = `${endpoint}?_shape=${shape.join(',')}` ``` ```javascript theme={null} GET /api/public/blogPosts?page=1&top=10&featured=true&_shape=BlogPosts.Records.Id,BlogPosts.Records.Business.Id,BlogPosts.Records.Business.WebAddress,BlogPosts.Records.Business.Name,BlogPosts.Records.Title,BlogPosts.Records.BlogCategories.Id,BlogPosts.Records.BlogCategories.Title,BlogPosts.Records.SummaryText,BlogPosts.Records.PublishDateUtc,BlogPosts.Records.UpdatedOn,BlogPosts.Records.PostedBy.FullName,BlogPosts.HasNextPage,Category.Id,Category.Title,Categories.Id,Categories.Title ``` ## Multi-tenancy Support The application supports multi-tenancy through dynamic domain resolution: * Each location has its own subdomain (`your-space.spaces.nexudus.com`) ## API Throttling Limits The API enforces throttling rules to prevent abuse and ensure fair usage.\ Limits apply per client (based on request signature) and vary depending on method, endpoint, and time window. ### General Limits | Scope | Methods | Limit | Window | | ------------------------ | ----------------- | ---------------- | -------- | | Per second | Any | 10 requests | 1 sec | | Per minute | Any | 120 requests | 1 min | | Per hour | Any | 5000 requests | 1 hour | | Per day | Any | 200,000 requests | 24 hours | | POST/PUT/DELETE (minute) | POST, PUT, DELETE | 60 requests | 1 min | | POST/PUT/DELETE (day) | POST, PUT, DELETE | 5000 requests | 24 hours | ### Public API Limits | Endpoint | Methods | Limit | Window | | --------------------- | ------- | ----------- | ------ | | `/api/public*` | Any | 10 requests | 5 sec | | `/api/public/checkin` | Any | 60 requests | 1 min | ### Endpoint-Specific Limits | Endpoint | Methods | Limit | Window | | ------------------------------------------- | --------- | ----------- | ------ | | `/api/Spaces/CoworkerPricePlanHistories` | Any | 1 request | 10 sec | | `/api/Sys/AuditTrailEntries` | Any | 1 request | 60 sec | | `/api/spaces/coworkerDataFiles` | POST, PUT | 5 requests | 1 min | | `/api/spaces/coworkerMessages` | POST, PUT | 5 requests | 1 min | | `/api/billing/proposals/runcommand` | Any | 10 requests | 1 min | | `/api/billing/coworkercontracts/runcommand` | Any | 10 requests | 1 min | | `/api/billing/coworkerinvoices/runcommand` | Any | 10 requests | 1 min | | `/api/nexpos/validatepin` | Any | 60 requests | 1 min | | `*/bigquery/pushall` | Any | 1 request | 12 min | | `/api/integrations/textract` | Any | 12 requests | 1 min | | `/api/integrations/openai` | Any | 12 requests | 1 min | | `/api/sys/users/sendmagiclink` | Any | 12 requests | 1 min | *** # Installing Agent Skills Source: https://learn.nexudus.com/cli/agent-skills-installation Step-by-step guide to installing the Nexudus Agent Skill for GitHub Copilot and Claude. # Installing Agent Skills The Nexudus Agent Skill is distributed as a public skills package. Installation takes one command and works for both GitHub Copilot and Claude. ## Prerequisites * **Node.js** — required to run the `npx skills` installer. * **Nexudus CLI** — the skill calls the CLI under the hood, so [install it first](/cli/installation). * **GitHub Copilot** or **Claude** — the AI assistant you want to use. ## Install the skill Install from the public GitHub repository: ```bash theme={null} npx skills add Nexudus-Ltd/nexudus-coworking-skills ``` Or use the full repository URL: ```bash theme={null} npx skills add https://github.com/Nexudus-Ltd/nexudus-coworking-skills.git ``` ### Install for a specific agent To install specifically for GitHub Copilot: ```bash theme={null} npx skills add Nexudus-Ltd/nexudus-coworking-skills -a github-copilot ``` ### Install globally To install the skill globally (available across all your projects): ```bash theme={null} npx skills add Nexudus-Ltd/nexudus-coworking-skills -g ``` Combine flags as needed: ```bash theme={null} npx skills add Nexudus-Ltd/nexudus-coworking-skills -g -a github-copilot ``` ## Verify the installation ```bash theme={null} npx skills list ``` You should see the `nexudus` skill in the list. The skill provides: * `skills/nexudus/SKILL.md` — the main skill file that teaches your AI assistant how to use the CLI. ## After installation Once the skill is installed, your AI assistant can use the Nexudus CLI. To confirm everything is working end-to-end: 1. **Make sure the CLI is authenticated** — run `nexudus login` if you haven't already. 2. **Ask your assistant to run diagnostics** — say something like *"Run nexudus doctor and tell me the status"*. 3. **Try a query** — ask *"List my Nexudus businesses"*. ## Updating the skill The Nexudus CLI and Agent Skills receive frequent updates with new entity coverage and improvements. To get the latest version: ```bash theme={null} npx skills add Nexudus-Ltd/nexudus-coworking-skills ``` Running the install command again updates the skill to the latest published version. The skill is synced from the private Nexudus CLI repository and only exposes the public skills payload. Updates are published every few days as new entity types and features are added. ## Uninstalling To remove the skill: ```bash theme={null} npx skills remove nexudus ``` ## Troubleshooting | Issue | Solution | | -------------------------------------------- | ---------------------------------------------------------------------------------------------- | | `npx skills` command not found | Make sure Node.js is installed and in your PATH | | Skill installed but assistant doesn't use it | Restart your editor or AI assistant session to pick up the new skill | | Assistant returns "Not logged in" errors | Run `nexudus login` in your terminal to authenticate | | Assistant can't find the CLI | Make sure the Nexudus CLI is installed globally via `dotnet tool install --global Nexudus.Cli` | # What are Agent Skills? Source: https://learn.nexudus.com/cli/agent-skills-overview How Agent Skills let AI assistants like GitHub Copilot and Claude manage your Nexudus coworking spaces through natural language. # Agent Skills **Agent Skills** teach AI assistants how to use the Nexudus CLI. Once installed, your AI assistant (GitHub Copilot or Claude) can manage your Nexudus coworking spaces through natural language instructions — no need to remember command syntax. ## How it works The Agent Skill is a structured knowledge file (`SKILL.md`) that gets installed into your AI assistant's context. It contains: * **Command reference** — every CLI command, its options, and expected output. * **Decision trees** — step-by-step workflows for common tasks (finding a business, creating a product, updating an entity). * **Output parsing rules** — how to interpret the JSON envelope returned by `--agent` mode. * **Error handling** — how to diagnose and recover from common errors. * **Entity index** — a catalogue of all 40+ entity types the CLI supports. When you ask your AI assistant something like *"List all products in my London office"*, the skill teaches the assistant to: 1. Run `nexudus businesses list --query "London" --agent` to find the business ID. 2. Run `nexudus products list --business --agent` to list products for that location. 3. Parse the JSON envelope and present the results. ## Supported AI assistants | Assistant | Support | | ---------------------- | ------------------------------------------------------------- | | **GitHub Copilot** | Fully supported — install the skill globally or per-workspace | | **Claude** (Anthropic) | Fully supported via the same skill file | ## What the AI assistant can do Once the skill is installed, your AI assistant can: * **Query data** — list, search, and filter any entity type (businesses, products, resources, bookings, coworkers, invoices, etc.). * **Create entities** — set up new products, resources, bookings, and more using natural language. * **Update entities** — modify properties, assign tariffs, change pricing, upload images. * **Delete entities** — remove entities with proper confirmation handling. * **Run entity commands** — execute special operations like archiving or activating. * **Diagnose issues** — run `nexudus doctor` and interpret the results. ## Example conversations **You:** *"Show me all the meeting rooms in my space"* The assistant runs: ```bash theme={null} nexudus resources list --agent ``` and presents the results. *** **You:** *"Create a day pass product for £25"* The assistant runs `nexudus whoami --agent` to get your default business and currency, then: ```bash theme={null} nexudus products create --name "Day Pass" --price 25.00 --business --agent ``` *** **You:** *"Delete product 12345678"* The assistant confirms the entity exists, then: ```bash theme={null} nexudus products delete 12345678 --yes --agent ``` ## With great power comes great responsibility Agent Skills give your AI assistant the ability to **create, update, and delete real data** in your Nexudus account. Before using them, be aware of the following risks: * **Destructive actions are real** — deletions and updates are applied immediately to your live environment. There is no undo button. * **AI can misinterpret intent** — a vague instruction like *"clean up old bookings"* could lead to unintended bulk deletions. Be specific in your requests. * **Always review before confirming** — read the commands and parameters the assistant proposes before letting them run, especially for write operations. * **Start in a test environment** — if your plan supports it, try commands against a sandbox or test business first. * **Limit scope when possible** — only grant the assistant access to the workspaces and businesses it needs. ## Important: the `--agent` flag The skill instructs the AI assistant to always append `--agent` to every CLI call. This flag returns a structured JSON envelope that the assistant can parse reliably, instead of human-formatted table output. ## Next steps Step-by-step installation guide for GitHub Copilot and Claude. # Authentication Source: https://learn.nexudus.com/cli/authentication How to log in, log out, and manage credentials with the Nexudus CLI. # Authentication The Nexudus CLI authenticates against the Nexudus REST API using your Nexudus account email and password. Credentials are stored securely in your operating system's native credential store. ## Credential storage | Operating system | Storage backend | | ---------------- | -------------------------------------- | | Windows | Windows Credential Manager | | macOS | macOS Keychain | | Linux | libsecret (GNOME Keyring / KDE Wallet) | Credentials are never stored in plain text on disk. ## Log in ```bash theme={null} nexudus login ``` The CLI prompts you for your Nexudus email and password. After entering them, the CLI validates your credentials by calling the Nexudus API and stores them securely if successful. The admin CLI currently uses Basic Authentication (username and password). OAuth/Bearer token support is planned for a future release. ## Public API Authentication In addition to admin authentication, the CLI supports the **Public API**, which lets you authenticate as a member of a coworking space. Public API tokens are stored separately from admin credentials, so you can use both contexts simultaneously. ### Log in as a member ```bash theme={null} nexudus public login --web-address myspace --email you@example.com --password your-password ``` | Option | Description | | --------------- | -------------------------------------------------- | | `--web-address` | The subdomain of your location (e.g., `myspace`) | | `--email` | Your member email address | | `--password` | Your member password | | `--totp` | Two-factor authentication code (if 2FA is enabled) | ### Verify your member session ```bash theme={null} nexudus public whoami ``` ### Log out as a member ```bash theme={null} nexudus public logout ``` This only clears public API (member) credentials — your admin credentials remain unaffected. For the full reference of public API commands, see [Public API Commands](/cli/public-api). ## Verify your session ```bash theme={null} nexudus whoami ``` This displays your authenticated user information including your name, email, and default business. It also returns useful defaults that commands use automatically: | Default | Description | | ------------------------- | ------------------------------------- | | `DefaultBusinessId` | Your primary business (location) ID | | `DefaultCurrencyId` | The default currency for your account | | `DefaultCountryId` | The default country for your account | | `DefaultSimpleTimeZoneId` | The default timezone for your account | These defaults are used automatically when creating or updating entities so you don't have to specify them every time. ## Log out ```bash theme={null} nexudus logout ``` This clears all stored credentials from your system's secure storage. ## Troubleshooting authentication | Symptom | Solution | | ---------------------- | ------------------------------------------------------------------------------ | | "Not logged in" errors | Run `nexudus login` to authenticate | | "Unauthorized" errors | Your credentials may have changed — run `nexudus login` again | | "Forbidden" errors | Your account may not have API permissions — contact your Nexudus administrator | Run `nexudus doctor` at any time to check whether you have stored credentials and whether the API is reachable. # CLI Commands Source: https://learn.nexudus.com/cli/commands Complete reference of all Nexudus CLI commands, global flags, and usage examples. # CLI Commands The Nexudus CLI follows a consistent `nexudus ` pattern. Every entity supports a standard set of operations where applicable. ## Command tree ``` nexudus ├── login # Authenticate and store credentials ├── logout # Clear stored credentials ├── whoami # Show current user info and defaults ├── doctor # Run environment diagnostics ├── config │ ├── get # Read a configuration value │ └── set # Set a configuration value ├── businesses │ ├── list [--query] [--page] # Search businesses │ ├── get # Get a single business │ └── update [--name] ... # Update a business ├── products │ ├── list [--query] [--business] # Search products │ ├── get # Get a single product │ ├── create [--name] [--price] ... # Create a product │ ├── update [--name] ... # Update a product │ └── delete # Delete a product ├── resources │ ├── list / get / create / update / delete ├── bookings │ ├── list / get / create / update / delete ├── coworkers │ ├── list / get / create / update / delete / commands ├── public │ ├── login # Authenticate as a member │ ├── logout # Clear member credentials │ ├── whoami # Show member session info │ ├── plans list / get / cancel # Manage your plans │ ├── bookings list / get / delete # Manage your bookings │ ├── invoices list / get # View your invoices │ ├── visitors list / create # Manage your visitors │ ├── profile patch # Update your profile │ ├── store list # Browse store products │ ├── community threads list/start # Community forum │ └── ... (see Public API Commands) └── ... (100+ entity types) Global flags: --json | --md | --agent | --base-url ``` New entity types are added regularly. Run `nexudus --help` to see all currently available commands, or run `nexudus doctor --agent` to get a machine-readable list. **Public API Commands:** The `nexudus public` branch lets you interact with your coworking space as a member. See [Public API Commands](/cli/public-api) for the full reference. ## Global flags These flags can be added to any command: | Flag | Description | | ------------------ | -------------------------------------------------------------- | | `--json` | Output raw JSON envelope (for scripting) | | `--md` | Output as Markdown tables | | `--agent` | Output JSON envelope with enhanced summary (for AI assistants) | | `--base-url ` | Override the API base URL | | `--yes` or `-y` | Skip confirmation prompts (e.g., on delete) | ## Common operations ### Listing entities ```bash theme={null} nexudus products list nexudus products list --name "Day Pass" nexudus products list --business 12345678 nexudus products list --page 2 --size 50 nexudus products list --order-by Name --dir 0 ``` * `--name` filters results by name or keyword. Different entities support different parameter names. * `--business` scopes results to a specific business (location). * `--page` and `--size` control pagination. Default page size is 25; use `--size 100` for larger pages. * `--order-by` specifies the property to sort results by (e.g., `Name`, `CreatedOn`, `FromTime`). * `--dir` sets the sort direction: `0` for ascending, `1` for descending. Each entity type has a default sort order (e.g., Bookings sort by `FromTime` ascending). If you omit `--order-by`, the API applies this default. You can override it with any property that the entity exposes. ### Getting a single entity ```bash theme={null} nexudus products get 12345678 ``` List responses return a simplified projection without collection properties (e.g., `Tariffs`, `Teams`, `LinkedResources`). To see all fields including lists, always fetch the individual entity by ID with `get `. ### Creating an entity ```bash theme={null} nexudus products create --name "Day Pass" --price 25.00 --business 12345678 ``` Required fields depend on the entity type. Run `nexudus create --help` to see all available options and which are required. ### Updating an entity ```bash theme={null} nexudus products update 12345678 --name "Premium Day Pass" --price 35.00 ``` Only the fields you specify are changed. All other fields remain untouched. ### Deleting an entity ```bash theme={null} nexudus products delete 12345678 ``` The CLI prompts for confirmation before deleting. Use `--yes` to skip the prompt in scripts: ```bash theme={null} nexudus products delete 12345678 --yes ``` ### Entity commands Some entities support additional operations called "commands" (e.g., archiving, activating): ```bash theme={null} # Discover available commands for an entity type nexudus products commands # Run a command on one or more entities nexudus products run-command archive 123,456,789 ``` ## Working with list properties Some entities have list properties (e.g., tariffs on a resource, teams on a coworker). To set these, repeat the flag for each value: ```bash theme={null} nexudus resources update 123 --tariffs 101 --tariffs 202 --tariffs 303 ``` Three variants are available: | Flag pattern | Behaviour | | ------------------ | --------------------------------------------------------------------------- | | `--{list}` | **Replaces** the entire list with the supplied values. Use this by default. | | `--added-{list}` | **Adds** values to the existing list without removing current entries. | | `--removed-{list}` | **Removes** specific values from the existing list. | Do not use comma-separated values or bracket syntax for lists. Each value needs its own flag occurrence. ## Image uploads Some entities have image properties (logo, banner, picture). To set an image, provide a publicly accessible URL: ```bash theme={null} nexudus businesses update 123 --logo-url "https://example.com/logo.png" nexudus resources update 456 --new-picture-url "https://example.com/room.jpg" ``` The Nexudus back-end downloads the image from the URL, so it must be reachable from the internet — local file paths will not work. ## Discovering options You can always check available options for any command by appending `--help`: ```bash theme={null} nexudus businesses update --help nexudus products create --help nexudus resources list --help ``` # Entity Reference Source: https://learn.nexudus.com/cli/entity-reference Complete index of all entity types available in the Nexudus CLI with their supported operations. # Entity Reference The Nexudus CLI supports 100+ entity types. Each entity follows the same consistent command pattern and maps to a Nexudus REST API endpoint. This list grows with each release. Run `nexudus --help` to see all currently available entity commands, or run `nexudus doctor --agent` for the full list. ## Supported entities | Entity | CLI command | Operations | API module | | ---------------------------------- | ------------------------------------- | ------------------------------------------- | ------------- | | AccessToken | `accesstokens` | list, get, create, update, delete | spaces | | Application | `applications` | list, get, create, update, delete | apps | | AudioFile | `audiofiles` | list, get, create, update, delete | content | | AuditTrailEntry | `audittrailentries` | list, get | sys | | AutomationTile | `automationtiles` | list, get, create, update, delete | sys | | AutomationTileAudit | `automationtileaudits` | list, get, create, update, delete | sys | | BasketSession | `basketsessions` | list, get, create, update, delete | billing | | BlogCategory | `blogcategories` | list, get, create, update, delete | content | | BlogPost | `blogposts` | list, get, create, update, delete | content | | BlogPostComment | `blogpostcomments` | list, get, create, update, delete | content | | Booking | `bookings` | list, get, create, update, delete | spaces | | BookingAvailabilityException | `bookingavailabilityexceptions` | list, get, create, update, delete | spaces | | BookingNote | `bookingnotes` | list, get, create, update, delete | spaces | | BookingProduct | `bookingproducts` | list, get, create, update, delete | spaces | | BookingVisitor | `bookingvisitors` | list, get, create, update, delete | spaces | | Business | `businesses` | list, get, update | sys | | BusinessAnnouncement | `businessannouncements` | list, get, create, update, delete | content | | BusinessBackgroundJob | `businessbackgroundjobs` | list, get | sys | | BusinessCharge | `businesscharges` | list, get, create, update, delete | billing | | BusinessDomain | `businessdomains` | list, get, create, update, delete | sys | | BusinessRedirection | `businessredirections` | list, get, create, update, delete | sys | | BusinessSetting | `businesssettings` | list, get, create, update, delete | sys | | BusinessTimeSlot | `businesstimeslots` | list, get, create, update, delete | sys | | CalendarEvent | `calendarevents` | list, get, create, update, delete | content | | CalendarEventCategory | `calendareventcategories` | list, get, create, update, delete | content | | CancelledBooking | `cancelledbookings` | list, get, create, update, delete | spaces | | CannedResponse | `cannedresponses` | list, get, create, update, delete | crm | | Charge | `charges` | list, get, create, update, delete | billing | | ChatRoom | `chatrooms` | list, get, create, update, delete | support | | ChatUserMessage | `chatusermessages` | list, get, create, update, delete | sys | | Checkin | `checkins` | list, get, create, update, delete | spaces | | CommunityGroup | `communitygroups` | list, get, create, update, delete | community | | CommunityMessage | `communitymessages` | list, get, create, update, delete | community | | CommunityMessageLike | `communitymessagelikes` | list, get, create, update, delete | community | | CommunityPerk | `communityperks` | list, get, create, update, delete | content | | CommunityThread | `communitythreads` | list, get, create, update, delete | community | | CommunityThreadFile | `communitythreadfiles` | list, get, create, update, delete | community | | CommunityThreadFollow | `communitythreadfollows` | list, get, create, update, delete | community | | CommunityThreadLike | `communitythreadlikes` | list, get, create, update, delete | community | | CommunityThreadMute | `communitythreadmutes` | list, get, create, update, delete | community | | ContractContact | `contractcontacts` | list, get, create, update, delete | billing | | ContractDeposit | `contractdeposits` | list, get, create, update, delete | billing | | ContractPausedPeriod | `contractpausedperiods` | list, get, create, update, delete | billing | | ContractProduct | `contractproducts` | list, get, create, update, delete | billing | | ContractSchedule | `contractschedules` | list, get, create, update, delete | billing | | Country | `countries` | list, get | sys | | Course | `courses` | list, get, create, update, delete | content | | CourseCompletedLesson | `coursecompletedlessons` | list, get, create, update, delete | content | | CourseLesson | `courselessons` | list, get, create, update, delete | content | | CourseMember | `coursemembers` | list, get, create, update, delete | content | | CourseSection | `coursesections` | list, get, create, update, delete | content | | Coworker | `coworkers` | list, get, create, update, commands | spaces | | CoworkerAccessControlAudit | `coworkeraccesscontrolaudits` | list, get, create, update, delete | sys | | CoworkerBookingCredit | `coworkerbookingcredits` | list, get, create, update, delete | billing | | CoworkerBookingCreditUseHistory | `coworkerbookingcreditusehistories` | list, get, create, update | billing | | CoworkerContract | `coworkercontracts` | list, get, create, update, delete | billing | | CoworkerDataFile | `coworkerdatafiles` | list, get, create, update, delete | spaces | | CoworkerDelivery | `coworkerdeliveries` | list, get, create, update, delete | spaces | | CoworkerDiscountCode | `coworkerdiscountcodes` | list, get, create, update, delete | billing | | CoworkerExtraService | `coworkerextraservices` | list, get, create, update, delete | billing | | CoworkerExtraServiceUseHistory | `coworkerextraserviceusehistories` | list, get, create, update, delete | billing | | CoworkerGoogleCalendar | `coworkergooglecalendars` | list, get, create, update, delete | spaces | | CoworkerIdentityCheck | `coworkeridentitychecks` | list, get, create, update, delete | spaces | | CoworkerIdentityCheckDocument | `coworkeridentitycheckdocuments` | list, get, create, update, delete | spaces | | CoworkerInventoryAsset | `coworkerinventoryassets` | list, get, create, update, delete | spaces | | CoworkerInvoice | `coworkerinvoices` | list, get, update | billing | | CoworkerInvoiceHistory | `coworkerinvoicehistories` | list, get, create, update, delete | billing | | CoworkerInvoiceLine | `coworkerinvoicelines` | list, get, update | billing | | CoworkerInvoicePaymentToken | `coworkerinvoicepaymenttokens` | list, get, create, update, delete | billing | | CoworkerLedgerEntry | `coworkerledgerentries` | list, get, create, update, delete | billing | | CoworkerLegalContentAudit | `coworkerlegalcontentaudits` | list, get, create, update, delete | sys | | CoworkerMessage | `coworkermessages` | list, get | spaces | | CoworkerMsOfficeCalendar | `coworkermsoffecalendars` | list, get, create, update, delete | spaces | | CoworkerMsOfficeCalendar | `coworkermsofficecalendars` | list, get, create, update, delete | spaces | | CoworkerNote | `coworkernotes` | list, get, create, update, delete | spaces | | CoworkerNotification | `coworkernotifications` | list, get, create, update, delete | spaces | | CoworkerPaymentMethod | `coworkerpaymentmethods` | list, get, create, update, delete | billing | | CoworkerPricePlanHistory | `coworkerpriceplanhistories` | list, get | spaces | | CoworkerProduct | `coworkerproducts` | list, get, create, update, delete | billing | | CoworkerReminderAudit | `coworkerreminderaudits` | list, get, create, update, delete | crm | | CoworkerSetting | `coworkersettings` | list, get, create, update, delete | spaces | | CoworkerTask | `coworkertasks` | list, get, create, update, delete | crm | | CoworkerTimePass | `coworkertimepasses` | list, get, create, update, delete | billing | | CrmBoard | `crmboards` | list, get, create, update, delete | crm | | CrmBoardColumn | `crmboardcolumns` | list, get, create, update, delete | crm | | CrmOpportunity | `crmopportunities` | list, get, create, update, delete | crm | | CrmOpportunityHistory | `crmopportunityhistories` | list, get, create, update, delete | crm | | CrmOpportunityImportFile | `crmopportunityimportfiles` | list, get, create, update, delete | crm | | Currency | `currencies` | list, get | sys | | CustomField | `customfields` | list, get, create, update, delete | crm | | DataFile | `datafiles` | list, get, create, update, delete | content | | DiscountCode | `discountcodes` | list, get, create, update, delete | billing | | DocumentTemplate | `documenttemplates` | list, get, create, update, delete | crm | | EloxxLockersAudit | `eloxxlockersaudits` | list, get, create, update, delete | sys | | EmailAccount | `emailaccounts` | list, get, create, update, delete | crm | | EmailQueueItem | `emailqueueitems` | list, get | sys | | EmailQueueItemAttachment | `emailqueueitemattachments` | list, get, update | sys | | EmailTemplateFile | `emailtemplatefiles` | list, get, create, update, delete | sys | | EventAttendee | `eventattendees` | list, get, create, update, delete | content | | EventComment | `eventcomments` | list, get, create, update, delete | content | | EventProduct | `eventproducts` | list, get, create, update, delete | content | | EventWaitingAttendee | `eventwaitingattendees` | list, get, create, update, delete | content | | ExtraService | `extraservices` | list, get, create, update, delete | billing | | ExtraServicePrice | `extraserviceprices` | list, get, create, update, delete | billing | | ExtraServiceTimeSlot | `extraservicetimeslots` | list, get, create, update, delete | billing | | FailedCheckin | `failedcheckins` | list, get, create, update, delete | spaces | | FaqArticle | `faqarticles` | list, get, create, update, delete | content | | FinancialAccount | `financialaccounts` | list, get, create, update, delete | billing | | FloorPlan | `floorplans` | list, get, create, update, delete | sys | | FloorPlanAsset | `floorplanassets` | list, get | sys | | FloorPlanDesk | `floorplandesks` | list, get, create, update, delete | sys | | FloorPlanDeskVariant | `floorplandeskvariants` | list, get, create, update, delete | sys | | FloorPlanLayout | `floorplanlayouts` | list, get, create, update, delete | sys | | FloorPlanLayoutArea | `floorplanlayoutareas` | list, get, create, update, delete | sys | | FloorPlanLayoutAsset | `floorplanlayoutassets` | list, get, create, update, delete | sys | | FloorPlanLayoutEdge | `floorplanlayoutedges` | list, get, create, update, delete | sys | | FloorPlanLayoutNode | `floorplanlayoutnodes` | list, get, create, update, delete | sys | | FloorPlanLayoutOpening | `floorplanlayoutopenings` | list, get, create, update, delete | sys | | FloorplanLayoutTransition | `floorplanlayouttransitions` | list, get, create, update, delete | sys | | FormPage | `formpages` | list, get, create, update, delete | content | | FormPageAnswer | `formpageanswers` | list, get, create, update | content | | FormPageQuestion | `formpagequestions` | list, get, create, update, delete | content | | FormPageRequest | `formpagerequests` | list, get, create, update, delete | content | | GlobalChatMessage | `globalchatmessages` | list, get, create, update, delete | support | | HelpDeskComment | `helpdeskcomments` | list, get, create, update, delete | support | | HelpDeskDepartment | `helpdeskdepartments` | list, get, create, update, delete | support | | HelpDeskMessage | `helpdeskmessages` | list, get, create, update, delete | support | | ImageFile | `imagefiles` | list, get, create, update, delete | content | | InstalledApplication | `installedapplications` | list, get, create, update, delete | apps | | InstalledMarketPlaceApplication | `installedmarketplaceapplications` | list, get, create, update, delete | apps | | InventoryAsset | `inventoryassets` | list, get, create, update, delete | spaces | | Invoice | `invoices` | list, get, update | billing | | Language | `languages` | list, get, create, update, delete | sys | | LanguageToken | `languagetokens` | list, get, create, update, delete | sys | | LedgerEntry | `ledgerentries` | list, get | billing | | LegalContentAudit | `legalcontentaudits` | list, get, create, update, delete | sys | | LogEntry | `logentries` | list, get | sys | | MarketPlaceApplication | `marketplaceapplications` | list, get, create, update, delete | apps | | MsOfficeAdminCalendar | `msofficeadmincalendars` | list, get, create, update, delete | spaces | | NewsLetter | `newsletters` | list, get, create, update, delete | content | | NewsLetterSubscriber | `newslettersubscribers` | list, get, create, update, delete | content | | OpenAiChatMessage | `openaichatmessages` | list, get, create, update, delete | sys | | OpportunityType | `opportunitytypes` | list, get, create, update, delete | crm | | PassportCard | `passportcards` | list, get, create, update, delete | sys | | PaymentGateway | `paymentgateways` | list, get, create, update, delete | billing | | PayoutInvoice | `payoutinvoices` | list, get, create, update, delete | sys | | PlatformChangeMessage | `platformchangemessages` | list, get, create, update, delete | sys | | Product | `products` | list, get, create, update, delete, commands | billing | | ProductBookingCredit | `productbookingcredits` | list, get, create, update, delete | billing | | ProductExtraService | `productextraservices` | list, get, create, update, delete | billing | | ProductTimePass | `producttimepasses` | list, get, create, update, delete | billing | | Proposal | `proposals` | list, get, create, update, delete | billing | | ProposalContract | `proposalcontracts` | list, get, create, update, delete | billing | | ProposalContractSchedule | `proposalcontractschedules` | list, get, create, update, delete | billing | | ProposalProduct | `proposalproducts` | list, get, create, update, delete | billing | | ProposalSchedule | `proposalschedules` | list, get, create, update, delete | billing | | RadiusServer | `radiusservers` | list, get, create, update, delete | sys | | RefreshToken | `refreshtokens` | list, get, create, update, delete | sys | | RegisteredDevice | `registereddevices` | list, get, update | sys | | Reminder | `reminders` | list, get, create, update, delete | crm | | Report | `reports` | list, get, create, update, delete | sys | | Reseller | `resellers` | list, get, create, update, delete | sys | | ResellerAccount | `reselleraccounts` | list, get, create, update, delete | sys | | ResellerPayout | `resellerpayouts` | list, get, create, update, delete | sys | | Resource | `resources` | list, get, create, update, delete | spaces | | ResourceAccessRule | `resourceaccessrules` | list, get, create, update, delete | spaces | | ResourceAccessRuleEligibleTimeSlot | `resourceaccessruleeligibletimeslots` | list, get, create, update, delete | spaces | | ResourceAccessRuleTimeSlot | `resourceaccessruletimeslots` | list, get, create, update, delete | spaces | | ResourceProduct | `resourceproducts` | list, get, create, update, delete | billing | | ResourceTimeSlot | `resourcetimeslots` | list, get, create, update, delete | spaces | | ResourceType | `resourcetypes` | list, get, create, update, delete | spaces | | Role | `roles` | list, get | security | | Sensor | `sensors` | list, get, create, update, delete | sys | | SensorHistory | `sensorhistories` | list, get, create, update, delete | sys | | SimpleTimeZone | `simpletimezones` | list, get, update | sys | | SubscriberActivity | `subscriberactivities` | list, get | content | | SubscriberGroup | `subscribergroups` | list, get, create, update, delete | content | | Survey | `surveys` | list, get, create, update, delete | content | | SurveyAnswer | `surveyanswers` | list, get, create, update, delete | content | | SurveyQuestion | `surveyquestions` | list, get, create, update, delete | content | | SurveyRun | `surveyruns` | list, get, create, update, delete | content | | SystemNotification | `systemnotifications` | list, get, create, update, delete | sys | | Tariff | `tariffs` | list, get, create, update, delete | billing | | TariffBookingCredit | `tariffbookingcredits` | list, get, create, update, delete | billing | | TariffDefaultDueDate | `tariffdefaultduedates` | list, get, create, update, delete | billing | | TariffExtraService | `tariffextraservices` | list, get, create, update, delete | billing | | TariffProduct | `tariffproducts` | list, get, create, update, delete | billing | | TariffSignupProduct | `tariffsignupproducts` | list, get, create, update, delete | billing | | TariffTimePass | `tarifftimepasses` | list, get, create, update, delete | billing | | TaskItem | `taskitems` | list, get, create, update, delete | crm | | TaskList | `tasklists` | list, get, create, update, delete | crm | | TaxRate | `taxrates` | list, get, create, update, delete | sys | | Team | `teams` | list, get, create, update, delete | spaces | | TemplateFile | `templatefiles` | list, get, create, update, delete | sys | | TemplateVersion | `templateversions` | list, get, create, update, delete | sys | | TimePass | `timepasses` | list, get, create, update, delete | billing | | TimePassPrice | `timepassprices` | list, get, create, update, delete | billing | | TimePassTimeSlot | `timepasstimeslots` | list, get, create, update, delete | billing | | UiModule | `uimodules` | list, get, create, update, delete | sys | | User | `users` | list, get, create, update, delete | sys | | UserBookmark | `userbookmarks` | list, get, create, update, delete | sys | | UserMessage | `usermessages` | list, get | sys | | UserRole | `userroles` | list, get, create, update, delete | security | | ValidationRule | `validationrules` | list, get, create, update, delete | sys | | VideoFile | `videofiles` | list, get, create, update, delete | content | | VideoRoom | `videorooms` | list, get, create, update, delete | community | | Visitor | `visitors` | list, get, create, update, delete | spaces | | WebHook | `webhooks` | list, get, create, update, delete | sys | | Workspace | `workspaces` | list, get, create, update, delete | collaboration | ## Operation details ### `list` Searches and returns a paginated list of entities. Supports `--query`, `--page`, `--size`, and `--business` filters. ### `get ` Returns full details for a single entity, including collection properties (tariffs, teams, linked resources) that are omitted from list results. ### `create` Creates a new entity. Required fields vary by entity type — use `--help` to see them. ### `update ` Updates specific fields on an existing entity. Only the fields you supply are changed. ### `delete ` Deletes an entity. Prompts for confirmation unless `--yes` is passed. ### `commands` Lists available special commands for the entity type (e.g., archive, activate). ### `run-command ` Executes a special command on one or more entities. Supports comma-separated IDs for batch operations. ## API pattern Every entity maps to a Nexudus REST API endpoint following this pattern: | Operation | HTTP Method | URL | | ----------- | ----------- | ----------------------------------------- | | Search | `GET` | `/api/{module}/{entities}?page=1&size=25` | | Get one | `GET` | `/api/{module}/{entities}/{id}` | | Create | `POST` | `/api/{module}/{entities}` | | Update | `PUT` | `/api/{module}/{entities}` | | Delete | `DELETE` | `/api/{module}/{entities}/{id}` | | Commands | `GET` | `/api/{module}/{entities}/commands` | | Run command | `POST` | `/api/{module}/{entities}/runCommand` | **Business** entities cannot be created or deleted via the API — only listed, viewed, and updated. **Country** and **Currency** entities are read-only (list and get only). # Error Handling Source: https://learn.nexudus.com/cli/error-handling Common errors returned by the Nexudus CLI and how to resolve them. # Error Handling When a command fails, the CLI returns a non-zero exit code. If you're using `--json` or `--agent` output mode, the envelope's `ok` field is `false` and the `summary` field contains the error message. ## Error envelope ```json theme={null} { "ok": false, "data": null, "summary": "Not logged in. Run 'nexudus login' first.", "breadcrumbs": ["businesses", "list"] } ``` ## Common errors | Error summary | Cause | Resolution | | ------------------ | ---------------------------------- | ------------------------------------------------------------------------ | | "Not logged in" | No stored credentials found | Run `nexudus login` to authenticate | | "Unauthorized" | Invalid or expired credentials | Run `nexudus login` again with correct credentials | | "Forbidden" | Your account lacks API permissions | Contact your Nexudus administrator to grant API access | | "not found" | The entity ID does not exist | Double-check the ID — use `list` to find valid IDs | | "Failed to create" | Validation error on create | Check required fields — run `nexudus create --help` for details | | Non-zero exit code | General command failure | Read `stderr` or the JSON envelope for details | ## Checking for errors in scripts When scripting, always check the exit code or parse the envelope: ```bash theme={null} # Check exit code nexudus products get 12345678 --json if [ $? -ne 0 ]; then echo "Command failed" fi ``` ```bash theme={null} # Parse the envelope with jq result=$(nexudus products list --json) ok=$(echo "$result" | jq -r '.ok') if [ "$ok" != "true" ]; then echo "Error: $(echo "$result" | jq -r '.summary')" fi ``` ## Diagnostics If you're unsure why commands are failing, run diagnostics: ```bash theme={null} nexudus doctor ``` This checks: * Whether credentials are stored and valid. * Whether the API is reachable. * Whether the CLI is up to date. # Installing the Nexudus CLI Source: https://learn.nexudus.com/cli/installation How to install the Nexudus CLI tool and verify that it's working correctly. # Installing the Nexudus CLI The Nexudus CLI is a .NET global tool. You need the .NET SDK installed on your machine before installing the CLI. ## Prerequisites * **.NET 10 SDK** or later — [Download .NET](https://dotnet.microsoft.com/download) * A **Nexudus account** with API access ## Install the CLI Install the CLI as a .NET global tool: ```bash theme={null} dotnet tool install --global Nexudus.Cli ``` To update to the latest version: ```bash theme={null} dotnet tool update --global Nexudus.Cli ``` ### macOS (zsh) If you use zsh (the default shell on macOS), you may need to add the .NET tools directory to your `PATH`: ```bash theme={null} echo 'export PATH="$PATH:$HOME/.dotnet/tools"' >> ~/.zshrc source ~/.zshrc ``` ## Verify the installation Run the help command to confirm the CLI is available: ```bash theme={null} nexudus --help ``` You should see the top-level command tree listing available commands such as `login`, `logout`, `whoami`, `doctor`, `businesses`, `products`, and more. ## Run diagnostics The `doctor` command checks your environment and confirms everything is set up correctly: ```bash theme={null} nexudus doctor ``` This reports: | Check | What it verifies | | ---------------------- | ---------------------------------------- | | **CLI version** | The installed version of the Nexudus CLI | | **.NET runtime** | The .NET runtime version on your machine | | **OS** | Your operating system | | **Credentials stored** | Whether you have saved login credentials | | **Config file** | Location of the CLI configuration file | | **API connectivity** | Whether the Nexudus API is reachable | | **Available commands** | All registered CLI commands | If `doctor` reports that credentials are missing, run `nexudus login` to authenticate. See [Authentication](/cli/authentication) for details. ## Configuration The CLI stores its configuration in `~/.nexudus/config.json`. You can view and change settings with: ```bash theme={null} # View a setting nexudus config get base-url # Change the API base URL (useful for testing) nexudus config set base-url https://spaces.nexudus.com ``` The default base URL is `https://spaces.nexudus.com`. ## Uninstall To remove the CLI: ```bash theme={null} dotnet tool uninstall --global Nexudus.Cli ``` ## Next steps Log in and manage your credentials. Explore the full command reference. # Output Modes Source: https://learn.nexudus.com/cli/output-modes How to control the output format of the Nexudus CLI for human use, scripting, and AI assistant integration. # Output Modes Every CLI command supports four output modes, selected via global flags. The default mode produces human-friendly terminal tables. ## Available modes | Flag | Mode | Best for | | --------- | ------------ | ----------------------------------------------------- | | *(none)* | **Table** | Interactive terminal use — rich, formatted tables | | `--json` | **JSON** | Scripting and automation — raw JSON envelope | | `--md` | **Markdown** | Documentation and reports — Markdown-formatted tables | | `--agent` | **Agent** | AI assistants — JSON envelope with enhanced summary | ## The output envelope When using `--json` or `--agent`, every command returns a standardised JSON envelope: ```json theme={null} { "ok": true, "data": [ ... ], "summary": "Found 3 businesses (page 1/1)", "breadcrumbs": ["businesses", "list"], "meta": { "total": 3, "page": 1, "pageSize": 25, "totalPages": 1 } } ``` | Field | Description | | ------------- | ----------------------------------------------------------------------------------------------------------------------- | | `ok` | `true` on success, `false` on failure | | `data` | The response payload — an array for list operations, an object for single-entity operations, or `null` on some failures | | `summary` | A human-readable description of the result | | `breadcrumbs` | The command path that produced the output (e.g., `["products", "create"]`) | | `meta` | Pagination metadata (present only on list commands) | ### Error envelope When a command fails, the envelope looks like: ```json theme={null} { "ok": false, "data": null, "summary": "Not logged in. Run 'nexudus login' first.", "breadcrumbs": ["businesses", "list"] } ``` Always check `ok` first before processing `data`. ## Examples ### Table mode (default) ```bash theme={null} nexudus businesses list ``` Produces a formatted table in your terminal using rich formatting (colours, borders, alignment). ### JSON mode ```bash theme={null} nexudus businesses list --json ``` Returns the raw JSON envelope — ideal for piping into `jq`, processing in scripts, or integrating with other tools: ```bash theme={null} nexudus products list --json | jq '.data[] | .Name' ``` ### Markdown mode ```bash theme={null} nexudus businesses list --md ``` Produces Markdown-formatted tables suitable for pasting into documentation, tickets, or chat messages. ### Agent mode ```bash theme={null} nexudus businesses list --agent ``` Returns the JSON envelope with an enhanced `summary` field optimised for AI assistant consumption. This is the mode that [Agent Skills](/cli/agent-skills-overview) use to communicate with the CLI. # Nexudus CLI & Skills Source: https://learn.nexudus.com/cli/overview An overview of the Nexudus command-line interface and AI Agent Skills for managing coworking spaces from your terminal or AI assistant. # Nexudus CLI & Agent Skills The **Nexudus CLI** is a command-line tool that lets you manage your Nexudus coworking spaces directly from your terminal. Combined with **Agent Skills**, it also enables AI assistants like GitHub Copilot and Claude to perform Nexudus operations on your behalf. The Nexudus CLI and Agent Skills are under active development. New entity types, commands, and improvements are released regularly. Check the [GitHub repository](https://github.com/Nexudus-Ltd/nexudus-coworking-skills) for the latest updates. ## What can you do with it? List, create, update, and delete entities like businesses, products, resources, bookings, coworkers, and many more — all from the command line. Use the Public API to manage your own plans, bookings, invoices, visitors, and more as a member of a coworking space — no admin access required. Install the Agent Skill so GitHub Copilot or Claude can manage your Nexudus data using natural language instructions. Choose between human-friendly tables, raw JSON, Markdown, or a structured agent envelope — ideal for automation and scripting. Credentials are stored in your operating system's native secure storage (Windows Credential Manager, macOS Keychain, or Linux libsecret). ## Who is this for? | Audience | Use case | | ----------------------- | --------------------------------------------------------------------------------------------------------------- | | **Coworking operators** | Automate repetitive management tasks, bulk-update entities, and query data without leaving the terminal. | | **Space members** | Manage your plans, bookings, invoices, and visitors from the terminal using the Public API commands. | | **Developers** | Script against the Nexudus API, integrate with CI/CD pipelines, and build custom workflows. | | **AI assistant users** | Let GitHub Copilot or Claude manage your Nexudus spaces through natural language by installing the Agent Skill. | ## How it works The CLI communicates with the [Nexudus REST API](/rest-api/overview) using the same endpoints available to all integrations. Every entity in Nexudus (businesses, products, resources, bookings, coworkers, etc.) follows a consistent CRUD pattern, and the CLI wraps each one into a simple command structure: ``` nexudus [options] [--json | --md | --agent] ``` For example: ```bash theme={null} # List all businesses nexudus businesses list # Get a specific product as JSON nexudus products get 12345678 --json # Create a new resource nexudus resources create --name "Meeting Room A" --business 98765432 ``` When used with the `--agent` flag, every command returns a structured JSON envelope that AI assistants can parse and act on automatically. ## Privacy & telemetry The Nexudus CLI collects anonymous usage data to help us improve the tool. **Telemetry is enabled by default but can be disabled with a single command:** ```bash theme={null} nexudus config set telemetry off ``` No sensitive data (credentials, API responses, or business information) is collected. Learn more about what data is collected, where it's sent, and how to disable telemetry in the [Telemetry](/cli/telemetry) documentation. ## Next steps Download and set up the Nexudus CLI on your machine. Manage plans, bookings, invoices, and more as a space member. # PII Redaction Source: https://learn.nexudus.com/cli/pii-redaction How the CLI automatically redacts personal identifiable information for security and data protection. # PII Redaction The Nexudus CLI automatically redacts personally identifiable information (PII) when it detects non-interactive execution, such as when output is piped to another tool or script. This is a security feature that prevents sensitive data (names, emails, phone numbers, addresses, dates of birth) from flowing into AI agent contexts or logs. **Available since CLI v5.0.16**. PII redaction is enabled by default and cannot be disabled by flags. ## What is PII? PII includes any information that can identify a real person: | Category | Examples | | ------------- | -------------------------------------------------------- | | **NAME** | FullName, NickName, Salutation, company names in context | | **EMAIL** | Email addresses, contact emails, welcome emails | | **PHONE** | Mobile phones, landlines, fax numbers | | **ADDRESS** | Street address, postal code, city, state, country | | **DOB** | Date of birth | | **SOCIAL** | Twitter, Facebook, Google, Telegram handles | | **FINANCIAL** | Bank accounts, tax IDs, VAT numbers | | **ID\_DOC** | Passport numbers, national IDs | | **BIO** | Free-text profiles or notes that may contain PII | ## When is PII redacted? PII redaction is **automatic and structural** — it depends on your execution context, not on flags you can omit: | Context | Status | Reason | | --------------------------------------------- | ------ | -------------------------------------------------- | | **Interactive terminal** (typing commands) | ❌ OFF | You're a human — trusted context | | **Piped/redirected output** (e.g., `\| jq`) | ✅ ON | Data may enter scripts or logs — untrusted | | **Non-TTY execution** (no terminal attached) | ✅ ON | Likely automated — assume untrusted | | **With unlock token** (time-limited override) | ❌ OFF | Human confirmed via browser 2FA — checked & logged | ### How to detect redaction status Every CLI command response includes two fields that tell you whether PII is redacted: ```json theme={null} { "piiRedaction": "on", "piiRedactionReason": "non-interactive", "ok": true, "data": { ... } } ``` | Field | Values | | -------------------- | ---------------------------------------------------------------------------------- | | `piiRedaction` | `"on"` = PII is redacted; `"off"` = PII is visible | | `piiRedactionReason` | `"interactive terminal"`, `"non-interactive"`, or `"unlocked (expires TIMESTAMP)"` | ## How PII looks when redacted When PII is redacted, sensitive fields are replaced with **deterministic tokens**: ``` «PII:EMAIL:a3f2b1c9» «PII:NAME:7e4d2f8a» «PII:PHONE:1b3c5d7e» «PII:ADDR:f5e2c1b4» ``` ### Token anatomy ``` «PII:{CATEGORY}:{HASH}» ``` | Part | Example | Meaning | | ---------- | ---------- | ----------------------------------------------------- | | `PII` | constant | Identifies this as a PII token | | `CATEGORY` | `EMAIL` | The type of PII (EMAIL, NAME, PHONE, ADDR, DOB, etc.) | | `HASH` | `a3f2b1c9` | First 8 chars of SHA256(value + per-install salt) | ### Why tokens? * **Stable**: The same real value always produces the same token. You can reference entities by token across multiple commands. * **Opaque**: Tokens cannot be reversed into real values. An LLM cannot derive personal data from a token. * **Obvious**: Tokens are visually distinct from real data — not easily confused with actual emails or names. * **Resolvable**: When you pass a token back to the CLI as an argument, it resolves to the real value before sending to the API. ## Using tokens in commands You can pass tokens back to the CLI as arguments — the CLI transparently resolves them to real values before sending to the API: ```bash theme={null} # List coworkers — get tokenized output $ nexudus coworkers list --json { "piiRedaction": "on", "data": [ { "id": 123456, "fullName": "«PII:NAME:7e4d2f8a»", "email": "«PII:EMAIL:a3f2b1c9»" } ] } # Update that coworker using the token $ nexudus coworkers update 123456 --email "«PII:EMAIL:a3f2b1c9»" # The CLI resolves the token → real value before the API call ✓ Coworker 123456 updated ``` This is particularly useful for AI agents: they can read tokenized entity data, build command arguments using tokens, and pass them back without ever seeing real PII. ## Unlocking PII (browser-based 2FA override) If you're a human operator and genuinely need to see full PII in a non-interactive context (e.g., piping output to `jq`), you can temporarily unlock PII via a **browser-based 2FA flow**. This is a true second-factor mechanism — an LLM agent with terminal access cannot complete the flow because it cannot drive a browser session. ```bash theme={null} nexudus config set pii-mode unlocked --ttl 30m ``` ### Unlock requirements 1. **Browser-based confirmation** — the CLI opens your browser to the Nexudus admin panel where you must authenticate and confirm the unlock. There is no terminal prompt to confirm — agents cannot type "y" to bypass. 2. **Authenticated via admin panel** — the confirmation POST is same-origin from the admin panel, protected by your Bearer token and CORS policy. 3. **Time-limited** — defaults to 30 minutes. Maximum allowed: 8 hours. TTL clamped to 1–480 minutes. 4. **Challenge expiry** — the unlock challenge expires in 120 seconds if not confirmed in the browser. 5. **Rate-limited** — maximum 5 unlock challenges per user per hour. 6. **Auditable** — unlock events are logged to telemetry (the fact that an unlock occurred, plus the TTL; no PII is logged). ### How the 2FA unlock flow works Sequence diagram showing CLI to Browser to API flow for PII unlock ### Why agents cannot bypass the 2FA unlock | Barrier | Why agents cannot bypass | | ------------------------- | ------------------------------------------------------------------- | | **Browser launch** | Agent has terminal access, not browser control | | **Admin panel login** | Requires Bearer token from authenticated admin panel session | | **Same-origin policy** | Confirm POST is same-origin from admin panel — CORS blocks external | | **Nonce is server-side** | Cannot be forged — tied to authenticated user + TTL | | **Poll-based (no stdin)** | Nothing to "type" — the CLI just waits for server confirmation | | **Challenge expiry** | Challenge expires in 120s if not confirmed — no replay | ### Example unlock workflow ```bash theme={null} # Terminal: You need to export full PII for a report $ nexudus config set pii-mode unlocked --ttl 2h Opening browser for confirmation... Waiting for browser confirmation... (timeout: 120s) ``` The CLI creates a challenge and opens your browser to the admin panel: CLI waiting for browser-based PII unlock confirmation In the admin panel, you'll see the confirmation page showing the requested TTL and your identity. Click **Confirm Unlock** to approve: Nexudus admin panel PII unlock confirmation page Once confirmed, the CLI detects the approval and saves the session: ```bash theme={null} ✓ PII unlocked until 2026-05-14T13:30:00Z # Now redaction is temporarily OFF for 2 hours $ nexudus coworkers list --json { "piiRedaction": "off", "piiRedactionReason": "unlocked (expires 2026-05-14T13:30:00Z)", "ok": true, "data": [ { "id": 123456, "fullName": "Jane Doe", # ← Real name visible "email": "j.doe@acme.com" # ← Real email visible } ] } # After 2 hours (or you manually lock), redaction is back ON $ nexudus config set pii-mode locked ✓ PII redaction locked ``` ## Locking PII manually To immediately stop allowing PII in non-interactive mode: ```bash theme={null} nexudus config set pii-mode locked ``` This deletes the unlock session — no waiting for expiry. ## PII redaction banner Every CLI command displays a status banner that clearly states whether PII redaction is ON or OFF: ### Interactive terminal (PII visible) ``` 🔓 PII redaction: OFF (interactive terminal) ┌─────────┬──────────┬──────────────────┬─────────────────┐ │ Id │ FullName │ Email │ TariffId │ ├─────────┼──────────┼──────────────────┼─────────────────┤ │ 1234567 │ Jane Doe │ j.doe@acme.com │ 9876543 │ └─────────┴──────────┴──────────────────┴─────────────────┘ ``` ### Piped/redirected (PII redacted) ``` 🔒 PII redaction: ON (non-interactive) [JSON/Markdown table with tokenized PII fields] ``` ### With unlock (PII visible + warning) ``` ⚠️ PII redaction: OFF (unlocked until 2026-05-14T13:30:00Z) [Full data with real PII values] ``` The banner is always printed **before** the main output, so you can quickly see the current state. ## Threat model: What redaction protects against | Threat | Mitigation | | ---------------------------- | ---------------------------------------------------------------------------------------- | | **PII flows to LLM** | Tokens are sent instead of real values; LLM sees only opaque references | | **Agent bypasses redaction** | No `--no-redact` flag exists. Redaction is structural based on TTY detection. | | **Agent unlocks PII** | Unlock requires browser-based 2FA via admin panel — agents cannot drive browser sessions | | **Prompt bypass (stdin)** | No terminal prompt to confirm — unlock is poll-based, waiting for browser confirmation | | **New field leaks** | Schema annotations ensure new fields are redacted by default (fail-closed) | | **Summary text leaks** | Summary fields containing PII are automatically redacted | | **Token reversal** | Tokens are salted and stored locally; cannot derive real values without the local file | | **Challenge replay** | Nonce expires in 120s, is tied to authenticated user, rate-limited to 5/hour | ## PII token storage The CLI stores a local mapping of tokens to real values in `~/.nexudus/pii-tokens.json`: ```json theme={null} { "version": 1, "tokens": { "«PII:EMAIL:a3f2b1c9»": "j.doe@acme.com", "«PII:NAME:7e4d2f8a»": "Jane Doe", "«PII:PHONE:1b3c5d7e»": "+44 7700 900123" } } ``` ### Important notes about token storage * **Local only**: Token mappings are stored only on your machine. They are never sent to the API or stored in logs. * **Resolvable by CLI**: When you pass a token as a command argument, the CLI looks it up in this file to recover the real value. * **Per-installation**: Each machine has its own salt and token store. Tokens from one machine won't match another. * **Human-readable for debugging**: You can examine the file to understand which values have been tokenized. ### Clearing tokens To clear the local token store: ```bash theme={null} nexudus config set pii-clear-tokens ``` This deletes the token mapping file. Tokens in your command history will no longer resolve — be careful if you need to use them again. ## Best practices for agents ### ✅ Do * **Use tokens**: Read tokenized output from list/get commands and pass tokens back to update/create commands. * **Check redaction status**: Always read `piiRedaction` and `piiRedactionReason` to know the current mode. * **Cache tokens**: Store tokens in your agent state if you need to reference the same entity across multiple commands. * **Plan for token loss**: Keep records of what you're doing so you can re-fetch entities if needed. ### ❌ Don't * **Do not attempt to reverse-engineer tokens** — they're salted and hashed, not reversible. * **Do not display tokens to end users** as if they were real data — explain that they're security redactions. * **Do not request PII unlock** — it requires browser-based 2FA confirmation that agents cannot complete. * **Do not omit the `--agent` flag** to bypass redaction — redaction is structural, not flag-based. * **Do not attempt to drive the browser 2FA flow** — the confirmation requires an authenticated admin panel session with same-origin CORS protection. * **Do not store or log token mappings** — the CLI handles storage locally. ## Troubleshooting ### I see tokens but want real data **Problem**: Output is redacted when you need to see real values. **Solution 1**: Use an interactive terminal if possible — run the command directly in your shell. **Solution 2**: Unlock PII temporarily: ```bash theme={null} nexudus config set pii-mode unlocked --ttl 30m ``` ### I see "PII redaction: OFF" but expected tokens **Problem**: You expected redaction but it's not active. **Reasons**: * You're in an interactive terminal — redaction is OFF by default for humans. * A previous unlock is still valid — check `piiRedactionReason`. * Your output is not being piped — TTY detection shows it's interactive. **Solution**: Check `piiRedactionReason` in the JSON envelope to understand why: ```bash theme={null} nexudus coworkers list --json | jq '.piiRedactionReason' ``` ### Tokens don't resolve when I pass them back **Problem**: Command fails with "invalid email" or similar when I use a token as an argument. **Reasons**: * Token was from a different machine/installation (different salt). * Token store was cleared (`nexudus config set pii-clear-tokens`). * Token format is incorrect or corrupted. **Solution**: Re-fetch the entity fresh to get current tokens: ```bash theme={null} nexudus coworkers list --json | jq '.data[] | select(.id == 12345) | .email' ``` ### Unlock isn't working **Problem**: `nexudus config set pii-mode unlocked` fails or times out. **Possible reasons**: * Browser didn't open — check your default browser configuration. * You didn't confirm in time — the challenge expires in 120 seconds. * You're not logged into the admin panel — you'll be redirected to login first. * Rate limit hit — maximum 5 challenges per user per hour. **Solution**: Run the unlock command again and confirm in your browser within 120 seconds: ```bash theme={null} # Run the unlock command $ nexudus config set pii-mode unlocked --ttl 30m # Browser opens automatically to the admin panel # Log in if needed, then click "Confirm Unlock" # CLI will detect the confirmation and save the session ✓ PII unlocked (expires 2026-05-14T11:00:00Z) ``` If your browser doesn't open automatically, copy the URL from the CLI output and open it manually. ## FAQ No. Redaction is structural and based on TTY detection — it cannot be disabled by flags. However, you can unlock it temporarily via the browser-based 2FA flow if you genuinely need full PII in a non-interactive context. The unlock requires authenticating in the Nexudus admin panel and cannot be automated by agents. Tokens are salted per installation and stored in `~/.nexudus/pii-tokens.json`. If your script runs on a different machine or in a Docker container without that file, tokens won't resolve. The CLI will reject invalid tokens with an error. Yes — the file is in plaintext JSON at `~/.nexudus/pii-tokens.json`. You can read and parse it for debugging. Never share this file or its contents with others — it exposes real PII. Yes. Every entity query (list, get, search) respects the PII redaction mode. Create/update commands also resolve tokens transparently. If a command doesn't show PII fields, it's not related to redaction. The CLI tries to resolve it from the token store. If not found, it passes the token literal to the API. The API validation will reject it (e.g., "invalid email format"), and the command fails with that error. This is intentional — prevents accidentally using stale tokens. Not recommended. Tokens are salted per machine — mappings from your machine won't work on someone else's. Each person should generate their own tokens on their own machine by running queries with redaction enabled. No. Redaction is a **display-time transformation**. PII is not encrypted in transit or at rest — the CLI and API use HTTPS. Redaction is an **additional** layer that hides PII from agent contexts and logs, using local tokenization and salting. ## Related documentation * [Output Modes](/cli/output-modes) — Understanding JSON, Markdown, and Agent output formats * [Authentication](/cli/authentication) — Credential storage and login * [Agent Skills](/cli/agent-skills-overview) — Using the CLI with AI assistants # Public API Commands Source: https://learn.nexudus.com/cli/public-api Use the Nexudus CLI to access your coworking space as a member — manage plans, bookings, invoices, visitors, and more via the public API. # Public API Commands The Nexudus CLI supports the **Public API**, which allows you to interact with your coworking space as a member rather than an administrator. This is the same API that powers the members portal, and it lets you manage your plans, bookings, invoices, visitors, and more from the command line. All public API commands use the `nexudus public` prefix and authenticate against a specific location's subdomain at `{webaddress}.spaces.nexudus.com`. ## How it works The Public API targets a single location (determined by its web address/subdomain) and authenticates using member credentials (email + password). Tokens are stored separately from admin credentials, so you can switch between admin and member contexts independently. ``` nexudus public [options] [--json | --md | --agent] ``` For example: ```bash theme={null} # Authenticate as a member nexudus public login --web-address myspace --email you@example.com --password xxx # List your active plans nexudus public plans list # View your upcoming bookings nexudus public bookings list # Check your invoices nexudus public invoices list ``` ## Authentication ### Log in as a member ```bash theme={null} nexudus public login --web-address myspace --email you@example.com --password your-password ``` | Option | Description | | --------------- | --------------------------------------------------------------------------------- | | `--web-address` | The subdomain of your location (e.g., `myspace` for `myspace.spaces.nexudus.com`) | | `--email` | Your member email address | | `--password` | Your member password | | `--totp` | Two-factor authentication code (if 2FA is enabled) | If any option is omitted, the CLI will prompt you interactively. Public API tokens are stored separately from admin credentials. You can be logged in as both an admin and a member simultaneously. ### Verify your session ```bash theme={null} nexudus public whoami ``` This displays your authenticated member information, including your email, web address, token expiry, and associated profiles. ### Log out ```bash theme={null} nexudus public logout ``` This clears stored public API (member) credentials only — your admin credentials remain unaffected. ## Command Reference ### Business & Location | Command | Description | | ---------------------------------------- | ---------------------------------- | | `nexudus public businesses current` | Get current location details | | `nexudus public businesses networks` | Get all network locations | | `nexudus public businesses all` | Get all businesses in the network | | `nexudus public businesses withVisitors` | Get locations accepting visitors | | `nexudus public businesses withTour` | Get locations with available tours | | `nexudus public configuration get` | Get mobile app configuration | | `nexudus public countries list` | Get all countries | Most business commands support the `--shape` option to request only specific fields: ```bash theme={null} nexudus public businesses current --shape "Name,WebAddress,Country.Name" ``` ### Plans & Contracts | Command | Description | | ----------------------------------------- | ------------------------------------- | | `nexudus public plans list [--cancelled]` | List your active or cancelled plans | | `nexudus public plans get ` | Get details of a specific plan | | `nexudus public plans published` | Browse all published plans | | `nexudus public plans cancel ` | Cancel a plan contract | | `nexudus public contracts list` | List your contracts | | `nexudus public contracts get ` | Get contract details | | `nexudus public contracts pause ` | Pause a contract for N billing cycles | | `nexudus public contracts resume ` | Resume a paused contract | **Examples:** ```bash theme={null} # List active plans nexudus public plans list # List cancelled plans nexudus public plans list --cancelled # Cancel a plan with reason nexudus public plans cancel 12345 --reason 1 --notes "Moving to another location" # Pause a contract for 2 billing cycles nexudus public contracts pause 12345 --cycles 2 ``` ### Invoices & Billing | Command | Description | | -------------------------------------------------------- | -------------------------------- | | `nexudus public invoices list [--paid] [--credit-notes]` | List your invoices | | `nexudus public invoices get ` | Get invoice details | | `nexudus public products list` | List your products | | `nexudus public discounts list` | List your discount codes | | `nexudus public discounts referral` | Get your referral discount codes | | `nexudus public discounts refer ` | Send a referral invite | **Examples:** ```bash theme={null} # List unpaid invoices nexudus public invoices list --paid false # List credit notes nexudus public invoices list --credit-notes # Send a referral invite nexudus public discounts refer 98765 friend@example.com ``` ### Bookings & Resources | Command | Description | | ------------------------------------------ | ------------------------------------ | | `nexudus public bookings list [--past]` | List your upcoming or past bookings | | `nexudus public bookings get ` | Get booking details | | `nexudus public bookings delete ` | Cancel a booking | | `nexudus public bookings suggestions` | Get booking suggestions | | `nexudus public bookings team` | Get team bookings | | `nexudus public bookings teamCancelled` | Get cancelled team bookings | | `nexudus public bookings cancellationFee` | Get cancellation fee for a booking | | `nexudus public resources summary` | Get published resources summary | | `nexudus public resources details` | Get published resources with details | | `nexudus public resources get ` | Get specific resource details | | `nexudus public resources products ` | Get products for a resource | | `nexudus public resources fields ` | Get custom fields for a resource | **Examples:** ```bash theme={null} # List upcoming bookings nexudus public bookings list # List past bookings nexudus public bookings list --past # Cancel a booking nexudus public bookings delete 12345 --reason "NoLongerNeeded" --details "Meeting was rescheduled" # Browse available resources nexudus public resources summary ``` ### Visitors | Command | Description | | --------------------------------------- | ----------------------------------- | | `nexudus public visitors list [--past]` | List your upcoming or past visitors | | `nexudus public visitors get ` | Get visitor details | | `nexudus public visitors create` | Create a new visitor | | `nexudus public visitors delete ` | Delete a visitor | | `nexudus public visitors approve ` | Approve or reject a visitor | **Examples:** ```bash theme={null} # List upcoming visitors nexudus public visitors list # Create a visitor nexudus public visitors create --business-id 12345 --full-name "John Doe" --email "john@example.com" --expected-arrival "2026-07-10T10:00:00" # Create visitors from a JSON file nexudus public visitors create --json-file visitors.json # Approve a visitor nexudus public visitors approve 12345 ``` ### Profile & Settings | Command | Description | | --------------------------------------------- | -------------------------------------- | | `nexudus public profile patch` | Update your profile | | `nexudus public coworkers profiles` | Get all your profiles across locations | | `nexudus public coworkers benefits` | Get your benefits (credits, passes) | | `nexudus public coworkers setCurrent` | Set your active profile | | `nexudus public settings get ` | Get a specific setting value | | `nexudus public settings getMultiple ` | Get multiple setting values | | `nexudus public settings search ` | Search settings | | `nexudus public settings set ` | Set a setting value | | `nexudus public settings setMultiple` | Set multiple settings at once | **Examples:** ```bash theme={null} # Update your profile nexudus public profile patch --json-request '{"User":{"FirstName":"John"},"Coworker":{"Phone":"555-0100"}}' # Check your benefits nexudus public coworkers benefits # Get a specific setting nexudus public settings get "maxBookingDays" ``` ### Store & Checkout | Command | Description | | --------------------------------- | ---------------------------------- | | `nexudus public store list` | Browse store products | | `nexudus public store get ` | Get store product details | | `nexudus public checkout preview` | Preview checkout with basket items | | `nexudus public signup contact` | Send a contact form message | **Examples:** ```bash theme={null} # Browse store products nexudus public store list # Filter to time passes only nexudus public store list --only-time-passes # Filter by tag nexudus public store list --tag "printing" # Preview checkout nexudus public checkout preview --basket '[{"ProductId":123,"Quantity":1}]' --agreed-terms ``` ### Community | Command | Description | | ----------------------------------------------------- | ---------------------- | | `nexudus public community threads list` | List community threads | | `nexudus public community threads get ` | Get thread details | | `nexudus public community threads start` | Start a new thread | | `nexudus public community threads delete ` | Delete a thread | | `nexudus public community threads like ` | Like a thread | | `nexudus public community threads follow ` | Follow a thread | | `nexudus public community threads messages list ` | List thread messages | | `nexudus public community threads messages reply` | Reply to a thread | | `nexudus public community threads messages like` | Like a message | | `nexudus public community groups list` | List community groups | | `nexudus public community tags list` | List thread tags | **Examples:** ```bash theme={null} # List community threads nexudus public community threads list # Start a new thread nexudus public community threads start --subject "Welcome event this Friday" --message "Join us for drinks and networking!" --tags "events,community" # Like a thread nexudus public community threads like 12345 ``` ### Perks | Command | Description | | -------------------------------------- | -------------------- | | `nexudus public perks list` | List available perks | | `nexudus public perks claim ` | Claim a perk | ### Blog & Content | Command | Description | | ------------------------------------------------------------------ | ----------------------- | | `nexudus public blog list [--category-id] [--search] [--featured]` | List blog posts | | `nexudus public blog get ` | Get a blog post | | `nexudus public blog categories` | List blog categories | | `nexudus public events list [--past] [--category-id] [--featured]` | List events | | `nexudus public events get ` | Get event details | | `nexudus public faq list [--search]` | List FAQ articles | | `nexudus public newsletter subscribe ` | Subscribe to newsletter | **Examples:** ```bash theme={null} # Browse blog posts nexudus public blog list # Search blog posts nexudus public blog list --search "workshop" # List upcoming events nexudus public events list # Subscribe to newsletter nexudus public newsletter subscribe you@example.com --name "John Doe" ``` ### Courses | Command | Description | | -------------------------------------------------- | -------------------------- | | `nexudus public courses list [--group] [--search]` | List available courses | | `nexudus public courses get ` | Get course details | | `nexudus public courses my` | List your enrolled courses | | `nexudus public courses signup ` | Sign up for a course | | `nexudus public courses accept ` | Accept a course invitation | | `nexudus public courses lessons ` | List course lessons | | `nexudus public courses lesson get ` | Get lesson details | | `nexudus public courses lesson complete ` | Mark a lesson as complete | ### Help Desk | Command | Description | | --------------------------------------------- | ------------------------------ | | `nexudus public helpdesk messages list` | List your help desk messages | | `nexudus public helpdesk messages get ` | Get message details | | `nexudus public helpdesk messages create` | Create a new help desk message | | `nexudus public helpdesk messages close ` | Close a message | | `nexudus public helpdesk comments list ` | List comments on a message | | `nexudus public helpdesk comments create` | Add a comment | | `nexudus public helpdesk departments list` | List help desk departments | ### Teams | Command | Description | | ---------------------------------------- | --------------------------- | | `nexudus public teams my` | List your teams | | `nexudus public teams profile ` | Get team profile | | `nexudus public teams published` | Browse published teams | | `nexudus public teams publishedGet ` | Get published team details | | `nexudus public teams addMembers ` | Add members to a team | | `nexudus public teams removeMember ` | Remove a member from a team | | `nexudus public teams attendance ` | Get team attendance | | `nexudus public teams kpi ` | Get team KPIs | | `nexudus public teams metrics ` | Get team metrics | | `nexudus public teams directoryMeta` | Get team directory metadata | ### Deliveries & Mail | Command | Description | | ------------------------------------------------- | ---------------------------- | | `nexudus public deliveries list [--show-pending]` | List your deliveries | | `nexudus public delivery get ` | Get delivery details | | `nexudus public delivery update ` | Update delivery info | | `nexudus public delivery markCollected ` | Mark a delivery as collected | ### Virtual Offices | Command | Description | | ---------------------------------------- | ------------------------------ | | `nexudus public vo meta` | Get virtual office metadata | | `nexudus public vo form get` | Get the virtual office form | | `nexudus public vo form submit` | Submit the virtual office form | | `nexudus public vo amlChecks list` | List AML checks | | `nexudus public vo amlChecks start` | Start an AML check | | `nexudus public vo identityChecks list` | List identity checks | | `nexudus public vo identityChecks start` | Start an identity check | | `nexudus public vo directors list` | List company directors | | `nexudus public vo directors add` | Add a company director | | `nexudus public vo recipients list` | List mail recipients | | `nexudus public vo recipients add` | Add a mail recipient | | `nexudus public vo companyAliases list` | List company aliases | | `nexudus public vo companyAliases add` | Add a company alias | ### Identity & Legal | Command | Description | | ------------------------------------------- | ----------------------------- | | `nexudus public identityChecks list` | List your identity checks | | `nexudus public identityChecks get ` | Get identity check details | | `nexudus public identityChecks upload ` | Upload identity documents | | `nexudus public legal status` | Check terms acceptance status | | `nexudus public legal accept` | Accept terms and conditions | **Examples:** ```bash theme={null} # Check if you've accepted terms nexudus public legal status # Accept general terms nexudus public legal accept --general # Accept both general and contract terms nexudus public legal accept --all ``` ### Forms & Surveys | Command | Description | | ------------------------------------------ | -------------------------- | | `nexudus public form get ` | Get a form page | | `nexudus public form preview ` | Preview a form | | `nexudus public form submit ` | Submit a form | | `nexudus public survey questionnaire ` | Get a survey questionnaire | | `nexudus public survey preview ` | Preview a survey | | `nexudus public survey submit ` | Submit survey answers | ### Onboarding & Data Files | Command | Description | | -------------------------------------------- | ------------------------- | | `nexudus public onboarding get` | Get onboarding actions | | `nexudus public dataFiles list` | List your data files | | `nexudus public dataFiles getFileUrl ` | Get file download URL | | `nexudus public dataFiles getSignedUrl ` | Get signed URL for a file | | `nexudus public dataFiles eSignStatus ` | Get e-signature status | ### Payments | Command | Description | | -------------------------------------------------------- | -------------------------------- | | `nexudus public payments stripe createCustomerSession` | Create a Stripe payment session | | `nexudus public payments stripe createSetupSession` | Create a Stripe setup session | | `nexudus public payments paypal createCustomerSession` | Create a PayPal customer session | | `nexudus public payments paypal createGuestSession` | Create a PayPal guest session | | `nexudus public payments spreedly createCustomerSession` | Create a Spreedly session | | `nexudus public payments spreedly storePaymentMethod` | Store a Spreedly payment method | ## Response Shaping Many public API endpoints support **response shaping** via the `--shape` option. This lets you request only the fields you need, reducing response size and improving performance. ```bash theme={null} # Full response nexudus public plans list # Only specific fields nexudus public plans list --shape "Name,Price,FromTime" # Nested fields using dot notation nexudus public businesses current --shape "Name,WebAddress,Country.Name,Currency.Code" ``` Not all commands support `--shape`. It's available on commands that wrap endpoints with response shaping support (most list and get operations). ## Global Flags All public API commands support the same global flags as admin commands: | Flag | Description | | ---------------------- | --------------------------------------------------- | | `--json` | Output raw JSON (for scripting) | | `--md` | Output as Markdown tables | | `--agent` | Output structured JSON envelope (for AI assistants) | | `--web-address ` | Override the location subdomain | ## Error Handling ### Common Errors | Error | Cause | Solution | | ------------------------------------ | ------------------------------ | ------------------------------------------- | | "Not logged in (public)" | No public API token stored | Run `nexudus public login` | | "Unauthorized" | Token expired or invalid | Run `nexudus public login` again | | "Two-factor authentication required" | 2FA is enabled on your account | Use `--totp` to provide your code | | "Account locked" | Too many failed login attempts | Wait and retry, or reset your password | | "Account disabled" | Account has been disabled | Contact your space administrator | | "Must reset password" | Password reset required | Use "Forgot password" on the members portal | ## Next steps Download and set up the Nexudus CLI on your machine. Browse the full reference of admin CLI commands. # Troubleshooting Source: https://learn.nexudus.com/cli/troubleshooting Solutions to common issues when using the Nexudus CLI and Agent Skills. # Troubleshooting ## CLI issues ### `nexudus` command not found The CLI is installed as a .NET global tool. Make sure: 1. You have the [.NET SDK](https://dotnet.microsoft.com/download) installed (version 8 or later). 2. You ran `dotnet tool install --global Nexudus.Cli`. 3. The .NET tools directory is in your system `PATH`: * **Windows:** `%USERPROFILE%\.dotnet\tools` * **macOS/Linux:** `~/.dotnet/tools` ### API connection failures If `nexudus doctor` reports that the API is unreachable: * Check your internet connection. * Verify the base URL is correct: `nexudus config get base-url` (default: `https://spaces.nexudus.com`). * Check whether a proxy or firewall is blocking outbound HTTPS connections. ### Credential storage errors on Linux The CLI uses `libsecret` for credential storage on Linux. If you get errors: ```bash theme={null} # Install libsecret (Ubuntu/Debian) sudo apt-get install libsecret-1-0 libsecret-1-dev # Install libsecret (Fedora/RHEL) sudo dnf install libsecret libsecret-devel ``` Make sure a keyring service (GNOME Keyring or KDE Wallet) is running. ### Commands return empty results * Confirm you are authenticated: `nexudus whoami`. * Check that your account has permissions for the entity type you're querying. * Try broadening your search: remove `--query` filters or increase `--size`. ## Agent Skill issues ### AI assistant doesn't recognise the Nexudus skill 1. Verify the skill is installed: `npx skills list` should show `nexudus`. 2. Restart your editor or AI assistant session — skills are loaded at startup. 3. If using VS Code with GitHub Copilot, try reloading the window (`Ctrl+Shift+P` → "Reload Window"). ### AI assistant returns "Not logged in" errors The AI assistant calls the CLI, which needs active credentials: ```bash theme={null} nexudus login ``` After logging in, retry your request. ### AI assistant constructs incorrect commands The skill file may be outdated. Update to the latest version: ```bash theme={null} npx skills add Nexudus-Ltd/nexudus-coworking-skills ``` You can also ask your assistant to run `nexudus --help` to discover the correct options. ### Pagination issues By default, list commands return 25 results per page. If you're not seeing all your data: * Ask for a larger page: *"List all products with page size 100"* * Or paginate: *"Show page 2 of products"* ## Telemetry issues ### Commands are slow or timing out Telemetry is sent to a remote service and has a 3-second timeout. If telemetry is slow: 1. Verify the timeout isn't blocking your commands — the CLI continues even if telemetry fails. 2. Disable telemetry if you prefer: `nexudus config set telemetry off` 3. Check your network connection — poor connectivity may cause timeouts. ### Can't disable telemetry To disable telemetry: ```bash theme={null} nexudus config set telemetry off ``` To verify it's disabled: ```bash theme={null} nexudus config get telemetry ``` If telemetry key doesn't exist, telemetry is enabled by default. Explicitly set it to `off` to disable. ### Want to verify telemetry is disabled You can verify by: 1. Checking your config: `nexudus config get telemetry` should return `off` 2. Checking the config file at `~/.nexudus/config.json` — it should contain `"telemetry": "off"` 3. Enabling debug mode to check local logs: `nexudus config set telemetry-debug on` and checking `~/.nexudus/telemetry.jsonl` For detailed telemetry information and privacy details, see the [Telemetry](/cli/telemetry) documentation. ## Getting help * **CLI help:** `nexudus --help` or `nexudus --help` * **Diagnostics:** `nexudus doctor` * **GitHub Issues:** [nexudus-coworking-skills](https://github.com/Nexudus-Ltd/nexudus-coworking-skills/issues) * **Nexudus Help Center:** [help.nexudus.com](https://help.nexudus.com) # Editor Components & Mock Data Source: https://learn.nexudus.com/customisation/editor-components-and-mock-data This guide explains how the page editor is wired in the Members Portal and how mock data is injected so you can design and test components without a live API. ## Key concepts * Editor configuration lives in `src/views/admin/editor/components/useEditorConfiguration.tsx` and uses Puck (`@measured/puck`) to declare components, fields, categories and render functions. * Components that need data typically accept a `mockData` prop and delegate fetching to a `use*Data` hook which supports an optional `mockData` override. * Mock payloads are colocated in `src/views/admin/editor/mockData/mocks/*.ts` and are lazy-loaded via a small helper hook. ## How mock data works 1. Opt-in at the editor field level * Most components include a `withMockData` field and default it to `true` in the editor only. * `useEditorConfiguration` provides `withMockDataFields` which you can spread into a component's `fields`. 2. Load the data * Editor render functions call `useMockedData(Name, inEditor && props.withMockData)` and pass the result to the presentational component as `mockData`. * The hook is defined in `src/views/admin/editor/mockData/mockedData.ts`. 3. Provide a mock module * Place a file named exactly like the editor component key in `src/views/admin/editor/mockData/mocks/`. * Export `getMockData(business?: any)` which returns the mocked payload. `business` is provided by the current route context and helps match currency, branding, etc. ### The `useMockedData` hook Source: `src/views/admin/editor/mockData/mockedData.ts` * Uses `import.meta.glob('./mocks/*.ts')` to lazily import `{Name}.ts`. * Calls `getMockData(business)` if present and returns its result. * When `loadData` is false, returns `undefined` so live fetching occurs. ## The data hooks contract Data hooks (for example `useFaqData`, `useBlogData`, `useProductsData`, `usePredictiveBookingsData`) call `useData`/`useTypedData` from `src/api/fetchData.ts`. * They accept an optional `mockData` parameter. * `useData` short-circuits and returns `{ resource: mockData, isLoading: false }` if `mockData` is provided, otherwise it performs the real HTTP call. * Hooks also declare response shapes via `createShape(...)` to limit fields and enable server-side shaping. ## Adding a new editor component 1. Create the UI component * Add a presentational component under `src/views/admin/editor/components/editorComponents/v1/YourComponentEC.tsx`. * The component should accept an optional `mockData` prop (typed to the shape your data hook expects) and pass it to the relevant `use*Data` hook, or consume it directly if it doesn't fetch. 2. Add mock data (optional but recommended) * Create `src/views/admin/editor/mockData/mocks/YourComponent.ts` exporting `getMockData(business?: any)`. * Return a payload that matches what your UI expects. You can import and reuse other mocks to keep parity across variants. 3. Register the component in the editor * Open `src/views/admin/editor/components/useEditorConfiguration.tsx`. * Add a lazy import for your `YourComponentEC`. * Extend the `Components` type with a `YourComponent: {}` entry. * Add a config entry under `components` with: * `label` * `fields` (include `...withMockDataFields` if you support it) * `defaultProps` (often `{ withMockData: true }`) * `render: (props) => { const mockData = useMockedData('YourComponent', props.editMode && props.withMockData); return }` * Optionally, add it to a `categories` group so it appears in the editor palette. 4. Wire a data hook (if needed) * In your `YourComponentEC`, call the relevant `use*Data(mockData)` hook and pass its return to the presentational child. * Example pattern: ```tsx theme={null} import { useXData } from '@/views/x/useXData' export default function YourComponentEC(props: { mockData?: typeof shape.type } & any) { const data = useXData(props.mockData) return } ``` ## Naming rules and gotchas * File naming must match the editor key exactly. If your key is `UpcomingEventsDashboardSection`, the mock file must be `UpcomingEventsDashboardSection.ts`. * `getMockData` can accept the `business` object to tailor outputs (currency, business name, web address). * When outside the editor (live runtime), `withMockData` has no effect—mock hook returns `undefined` and real requests run. * Keep mock payloads small and representative. Prefer a handful of items and realistic field names so the UI matches production. ## Example: FAQ section * Editor config: * In `useEditorConfiguration`, the `FaqPageSection` entry sets `defaultProps: { withMockData: true }` and passes `mockData` to ``. * Mock file: * `src/views/admin/editor/mockData/mocks/FaqPageSection.ts` exports several FAQ articles. * Data hook: * `src/views/faq/useFaqData.tsx` accepts `mockData` and passes it into `useTypedData(..., { mockData })`. ## Troubleshooting * "No mock module found" error: ensure the mock filename matches the editor component name and lives under `mockData/mocks/`. * Mock renders but shape mismatch: align the mock payload with the `shape` your data hook requests. * Not seeing mock vs live toggle: make sure the component spreads `...withMockDataFields` and uses `props.editMode` to guard loading. ## Checklists When adding a component: * [ ] UI component under `editorComponents/v1` * [ ] Mock under `mockData/mocks` with `getMockData` * [ ] Editor registration in `useEditorConfiguration` * [ ] Category placement * [ ] Optional data hook integration that respects `mockData` # Register and authenticate add-ons Source: https://learn.nexudus.com/developers/add-ons Learn how to register an add-on application in Nexudus, configure its settings, and authenticate API requests using the application key and secret. # Register and authenticate add-ons This guide explains how to register a new add-on application in Nexudus, configure its installation URL and required roles, and authenticate API requests using your application credentials. > 💡 **Before you start** > > Add-ons (also called published add-ons) are third-party integrations that can be installed by Nexudus customers. If you're building a custom integration for your own space only, you may not need this flow — consider using a standard API access token instead. ## Overview Every add-on in Nexudus has two key credentials: | Credential | Description | | ------------------- | --------------------------------------------------------------------------------------------------------------- | | **Application Key** | A unique identifier for your add-on. This is generated when you register the application and cannot be changed. | | **Secret Key** | A shared secret used to sign and validate installation requests. **Never share this key.** | When a customer installs your add-on, Nexudus redirects them to your **Installation URL** with a set of parameters that your application uses to generate an authentication token. This token then allows your add-on to make API calls on behalf of the customer's account. ## Step 1: Register your add-on You can register a new add-on application in two ways: 1. Sign in to your Nexudus account as an **Admin**. 2. Navigate to **Settings** > **Add-ons** > **Manage add-ons**. 3. The management page is available at: `https://dashboard.nexudus.com/apps/applications/manage` 4. Click **Create** to add a new application. 5. Fill in the required fields: | Field | Description | | --------------------- | --------------------------------------------------------------------------------------------------------------------------------- | | **Name** | A display name for your add-on (required). | | **Short Description** | A brief description of what your add-on does (required). | | **Description** | A full HTML description shown during installation. | | **Installation URL** | The URL where Nexudus will redirect users after they approve the installation. This must be a publicly accessible HTTPS endpoint. | | **Published** | Set to `true` if you want this add-on available in the Nexudus marketplace. | | **Required Roles** | Select the roles that a user must have to install and use this add-on. | You can also create an application using the REST API. You'll need admin-level API access. **Create an application:** ``` POST /api/apps/applications Content-Type: application/json Authorization: Basic ``` ```json theme={null} { "Name": "My Add-on", "ShortDescription": "A brief description", "Description": "

Full HTML description

", "InstallUrl": "https://myapp.com/install", "Published": false, "RequiredRoles": [1, 2] } ``` For the full API reference, see [Create Application](/rest-api/apps/post-applications).
## Step 2: Retrieve your application credentials After creating the application, you need to retrieve the **Application Key** and **Secret Key**. You can find these in the Dashboard or via the REST API. After creating the application in the Dashboard, your credentials are displayed on the application's detail page. Navigate to **Settings** > **Add-ons** > **Manage add-ons**, click on your application, and you will see the Application Key and Secret Key listed. > 🚨 **Important** > > **Never share your Secret Key.** If someone obtains your Secret Key, they can impersonate your add-on and access customer data. Store it securely in your application configuration. You can also retrieve your application credentials using the REST API. **Get all applications:** ``` GET /api/apps/applications/my Content-Type: application/json Authorization: Basic ``` **Response:** ```json theme={null} [ { "Name": "My Add-on", "ApplicationKey": "f36292c02d9c438d98d8c9eb34897c90", "SecretKey": "b5d83da7a...7febc62d8dc", "InstallUrl": "https://myapp.com/install", "Published": false, "RequiredRoles": [1, 2] } ] ``` > 🚨 **Important** > > **Never share your Secret Key.** If someone obtains your Secret Key, they can impersonate your add-on and access customer data. Store it securely in your application configuration. For the full API reference, see [Get Applications](/rest-api/apps/get-applications). ## Step 3: Handle the installation callback When a user installs your add-on, Nexudus redirects them to the **Installation URL** you configured. The redirect includes several query parameters: | Parameter | Description | | --------- | ---------------------------------------------------------- | | `a` | Your Application Key (unique identifier) | | `t` | A unique token to generate the authentication token | | `d` | A timestamp (DateTime ticks) representing the current time | | `h` | An MD5 hash for request validation | | `b` | The Nexudus subdomain of the account installing the add-on | | `e` | The email of the user installing the add-on | **Example redirect URL:** ``` https://myapp.com/install? a=f36292c02d9c438d98d8c9eb34897c90& t=c90e30fca71a4c37810a292b99d4d4f2& d=634963729314011098& h=785a10afef749b1c26cc3c5eb3989082& b=subdomain& e=user@example.com ``` ### Validating the request Before proceeding, verify the request is genuinely from Nexudus by recalculating the hash: 1. Take the parameters `token` (`t`), `applicationKey` (`a`), and `timespan` (`d`). 2. Sort them alphabetically. 3. Join them with a pipe (`|`) separator. 4. Append your **Secret Key** to the end. 5. Calculate the MD5 hash of the resulting string. 6. Compare your calculated hash with the `h` parameter. ```csharp C# theme={null} // Extract parameters from the request var token = Request.QueryString["t"]; var appKey = Request.QueryString["a"]; var timespan = Request.QueryString["d"]; var hash = Request.QueryString["h"]; var secret = ConfigurationManager.AppSettings["SecretKey"]; // Calculate expected hash var param = new[] { token, appKey, timespan }; Array.Sort(param); // Sort alphabetically var joined = string.Join("|", param); var input = joined + secret; var expectedHash = MD5Hash(input); // Validate if (expectedHash != hash) { // Request is not from Nexudus — reject it return HttpUnauthorized(); } ``` ```javascript Node.js theme={null} const crypto = require('crypto'); // Extract parameters from the request (Express.js example) function installHandler(req, res) { const { t: token, a: appKey, d: timespan, h: hash } = req.query; const secret = process.env.NEXUDUS_SECRET_KEY; // Calculate expected hash const params = [token, appKey, timespan].sort(); // Sort alphabetically const joined = params.join('|'); const input = joined + secret; const expectedHash = crypto.createHash('md5').update(input).digest('hex'); // Validate if (expectedHash !== hash) { return res.status(403).send('Invalid request'); } // Generate authentication token const authToken = crypto.createHash('md5') .update(token + secret) .digest('hex'); // Store authToken securely for subsequent API calls // ... } ``` ### Generating the authentication token Once the request is validated, generate the authentication token: ```csharp C# theme={null} var authToken = MD5Hash(token + secret); ``` ```javascript Node.js theme={null} const authToken = crypto.createHash('md5') .update(token + secret) .digest('hex'); ``` This `authToken` is used as the password in Basic Authentication when making API calls. ## Step 4: Make authenticated API requests After installation, your add-on can make API requests using **Basic Authentication**: | Field | Value | | ------------ | ------------------------------------------------------------------------ | | **Username** | Your **Application Key** | | **Password** | The generated **authentication token** (MD5 hash of `token + secretKey`) | **Example request:** ``` GET /api/businesses Authorization: Basic QWxhZGRp...lc2FtZQ== ``` > 💡 **Note** > > The authentication token is generated once during installation and is tied to the specific customer account that installed your add-on. You should store this token securely for subsequent API calls. ## What happens during installation When a user approves the installation of your add-on, Nexudus performs the following actions behind the scenes: 1. **Creates an API access user** — A new system user is created with the email format `{applicationKey}_{businessId}_api@nexudus.com` and `APIAccess = true`. This user is linked to your add-on. 2. **Records the installation** — An `InstalledApplication` record is created, linking your application to the customer's business. 3. **Generates credentials** — The authentication token is computed and passed to your installation URL. 4. **Redirects to your app** — The user is redirected to your Installation URL with the generated parameters. ## Related entities The following Nexudus entities are involved in the add-on system: | Entity | Description | | ------------------------------------ | ---------------------------------------------------------------------------------------------------------------------- | | **Applications** | Defines the add-on application, including its key, secret, install URL, and required roles. | | **InstalledApplications** | Records when an application is installed in a specific business account, including whether admin approval is required. | | **MarketPlaceApplications** | Tracks applications published to the Nexudus marketplace. | | **InstalledMarketPlaceApplications** | Records installations of marketplace applications. | For the full API reference, see the [Apps & Marketplace](/rest-api/apps/) section. ## Submit your application for approval Once your add-on is ready, follow these steps to submit it for approval to the Nexudus team: 1. **Update your application details** — Make sure the following fields are meaningful and accurate: | Field | Guidance | | --------------- | ----------------------------------------------------------------------------------- | | **Logo** | Upload a clear, professional logo that represents your brand. | | **Name** | Use a descriptive name that clearly communicates what your add-on does. | | **Description** | Provide a detailed and accurate description of your add-on's features and benefits. | 2. **Send an approval request** — Email **[support@nexudus.com](mailto:support@nexudus.com)** with the following information: * Your **add-on URL** (the public URL where your add-on is hosted) * Your **Privacy Policy** URL * Your **Terms of Service** URL The Nexudus team will review your submission and get back to you once the approval process is complete. ## Best practices * **Store your Secret Key securely** — Never commit it to source control or expose it in client-side code. * **Validate every installation request** — Always recalculate the hash before trusting any parameters from the installation callback. * **Use HTTPS** — Your Installation URL should always use HTTPS to protect the credentials in transit. * **Check required roles** — Ensure the installing user has the roles your add-on requires before proceeding. * **Handle re-installation** — If a user already has your add-on installed, Nexudus may redirect directly without showing the installation prompt. # createShape Source: https://learn.nexudus.com/developers/data/create-shape Type-safe field selection for server-side shaping with compile-time validation. # createShape `createShape()` builds a compile-time checked list of fields to request from the server. It validates dot-paths against `T` and produces a phantom `type` that represents the shaped response. Pair it with `useData` or `useTypedData` to append `_shape=...` to requests. Source: `src/helpers/shape-helper.ts` ## Why * Keep responses small by requesting only what you need * Maintain end-to-end type safety: invalid paths fail at compile time * Works with nested objects and arrays (e.g. `Records.Items.Name` or `Posts.Title`) ## Usage ```ts theme={null} const shape = createShape()(['Records.Id', 'Records.Name']) // shape.fields → ['Records.Id', 'Records.Name'] // shape.type → { Records: { Id: number; Name: string }[] } (phantom type) ``` Then pass `shape.fields` through `useData` or directly pass the shape object to `useTypedData`: ```tsx theme={null} const { resource } = useTypedData(httpClient, endpoint, shape) ``` ## Arrays and nesting If `Posts` is an array, `'Posts.Title'` yields `{ Posts: { Title: string }[] }` in `shape.type`. ## Compile-time validation Invalid paths produce a TypeScript error via `ValidatePaths`. ```ts theme={null} // Error: Invalid path: "profiles.fullName" if fullName doesn’t exist const shape = createShape()(['id', 'profiles.fullName']) ``` ## End-to-end example ```tsx theme={null} import endpoints from '@/api/endpoints' import { useTypedData } from '@/api/fetchData' import { createShape } from '@/helpers/shape-helper' const endpoint = endpoints.teams.list(true) const shape = createShape()(['Records.Id', 'Records.Name']) const { resource } = useTypedData(httpClient, endpoint, shape) ``` ## Best practices * Define shapes next to the data hook or at top-level when reused across components * Name exported shapes descriptively, e.g. `teamListShape` * Keep shapes minimal; add fields only when needed by the UI ## See also * [useData](/developers/data/use-data) * [useTypedData](/developers/data/use-typed-data) # useData Source: https://learn.nexudus.com/developers/data/use-data React Query-based data fetching hook with shape, pagination, method, and mock support. # useData `useData` is a lightweight wrapper around React Query that standardizes HTTP calls, adds first-class support for server-side shaping, pagination, and an optional `mockData` override for editor scenarios. Source: `src/api/fetchData.ts` ## Signature ```ts theme={null} function useData( apiClient: HttpClient, url: string | null, requestConfig?: { method?: 'get' | 'post' | 'put' | 'delete' data?: any queryConfig?: Partial> shape?: string[] page?: number size?: number mockData?: T }, ): { resource: T | undefined hasError: boolean isLoading: boolean query?: Omit, 'data' | 'isError' | 'isLoading'> } ``` ## Behavior * Adds `_shape=...` to the URL when `shape` is provided (comma-separated fields) * Adds `page` and `size` if provided * Uses React Query to fetch with a stable key that includes: * `finalUrl`, `method`, `data`, `apiClient.defaults.baseURL`, and `apiClient.defaults.headers` * Disables retry for HTTP 401 errors; otherwise retries up to 3 times * If `mockData` is provided, short-circuits and returns it immediately with `isLoading: false` Note on caching: headers are part of the query key; token/header changes will revalidate. If you need header-agnostic caching, use `useSuspenseFetch` with `includeHeaders: false`. ## Examples ### GET with shaping and pagination ```tsx theme={null} import { useData } from '@/api/fetchData' import { useLocationByRouteContext } from '@/states/useLocationByRouteContext' export function UseDataExample() { const { httpClient } = useLocationByRouteContext() const { resource, isLoading, hasError } = useData<{ Records: Array<{ Id: number; Name: string }> }>(httpClient, '/api/public/teams/my', { shape: ['Records.Id', 'Records.Name'], page: 1, size: 20, queryConfig: { staleTime: 60_000 }, }) if (isLoading) return
Loading…
if (hasError) return
Failed to load
return
{JSON.stringify(resource, null, 2)}
} ``` ### POST with payload ```tsx theme={null} const { resource } = useData<{ Success: boolean }>(httpClient, '/api/public/helpdesk/messages', { method: 'post', data: { subject: 'Printer', message: 'Paper jam on Floor 2' }, }) ``` ### Editor/mock data ```tsx theme={null} const { resource } = useData(httpClient, '/api/public/faqs', { mockData: { FaqArticles: [{ Question: 'Q?', Answer: 'A!' }], OpenAiEnabled: false }, }) ``` ## Return values * `resource` – The typed response or `undefined` while loading * `isLoading` – React Query loading flag * `hasError` – React Query error flag (boolean) * `query` – The rest of the React Query result (methods, status) minus the basic fields ## Edge cases * `url` is `null`/falsy → hook is disabled (`enabled: false`) and no request is made * 401 Unauthorized → no retries (fast-fail to let auth state respond) ## See also * [useTypedData](/developers/data/use-typed-data) – Strongly-typed wrapper around `useData` * [createShape](/developers/data/create-shape) – Type-safe shape builder for `_shape` query * [LocationContext](/developers/state/location-context) – Ensure you call with the correct `httpClient` # usePageParams Source: https://learn.nexudus.com/developers/data/use-page-params Derive page and size from the URL query string with optional namespacing/prefix and share pagination field shapes. # usePageParams `usePageParams` reads `page` and `size` from the current URL (via React Router’s `useSearchParams`) and returns a small object you can pass directly into `useData`/`useTypedData` to populate `page` and `size` query parameters. Source: `src/api/usePageParams.ts` ## Signature ```ts theme={null} export const usePageParams: (props?: { prefix?: string; defaultSize?: number }) => { paging: { page: number; size: number } prefix?: string paginationProperties: readonly (keyof ApiListResult)[] } ``` ## Behavior * Reads `page` and `size` from the URL. * Supports namespacing multiple paginators on a page via `prefix`: * With `prefix: 'comments'` it reads `page_comments` and `size_comments`. * Defaults: * `page` defaults to 1 * `size` defaults to `defaultSize` (if provided) or 25 * Exposes `paginationProperties`, a readonly list of field names to include in shapes when working with `ApiListResult` responses. ## Examples ### Basic list with paging ```tsx theme={null} import { useData } from '@/api/fetchData' import { usePageParams } from '@/api/usePageParams' const { paging } = usePageParams() const { resource } = useData(httpClient, '/api/public/items', { ...paging, // adds page & size to the URL }) ``` ### With shapes for paginated responses ```tsx theme={null} import { createShape } from '@/helpers/shape-helper' import { paginationProperties, usePageParams } from '@/api/usePageParams' const shape = createShape>()([ 'Records.Id', 'Records.Name', ...paginationProperties, // PageNumber, PageSize, TotalItems, etc. ]) const { paging } = usePageParams({ defaultSize: 10 }) const { resource } = useData>(httpClient, '/api/public/items', { shape: shape.fields, ...paging, }) ``` ### Multiple independent paginators ```tsx theme={null} // Parent page const files = usePageParams({ prefix: 'files', defaultSize: 25 }) const comments = usePageParams({ prefix: 'comments', defaultSize: 5 }) // URLs managed independently: page_files/size_files and page_comments/size_comments ``` ## Notes * `usePageParams` only reads params; updating page/size is done via `useSearchParams` or Link navigation. * The hook is UI-agnostic and doesn’t render anything; it’s safe to use anywhere. ## See also * [useData](/developers/data/use-data) * [useTypedData](/developers/data/use-typed-data) * [createShape](/developers/data/create-shape) # useTypedData Source: https://learn.nexudus.com/developers/data/use-typed-data Typed data fetching helper that pairs endpoint.type with a compile-time shape. # useTypedData `useTypedData` builds on top of `useData` and the typed endpoint definitions found in `src/api/endpoints.ts`. It takes an endpoint object `{ url, type }`, an optional `createShape()([...])`, and returns the shaped, typed resource. Source: `src/api/fetchData.ts` ## Signature ```ts theme={null} function useTypedData( apiClient: HttpClient, endpoint?: { url: string | null; type: T } | null, shape?: { type: TShaped; fields: string[] }, requestConfig?: { mockData?: any method?: 'get' | 'post' | 'put' | 'delete' data?: any queryConfig?: Partial> page?: number size?: number }, ): ReturnType> ``` `useTypedData` simply calls `useData(apiClient, endpoint?.url, { ...requestConfig, shape: shape?.fields })`. ## Pattern 1. Pick an endpoint from `src/api/endpoints.ts` (these expose `type` with the expected response) 2. Build a shape for the response using `createShape()([...])` 3. Call `useTypedData(httpClient, endpoint, shape, { ...options })` ## Example – FAQ list ```tsx theme={null} import endpoints from '@/api/endpoints' import { useTypedData } from '@/api/fetchData' import { createShape } from '@/helpers/shape-helper' import { useLocationByRouteContext } from '@/states/useLocationByRouteContext' export const useFaqData = (mockData?: any) => { const { httpClient } = useLocationByRouteContext() const endpoint = endpoints.faqs.list() const shape = createShape()(['FaqArticles', 'OpenAiEnabled']) const { resource: data, isLoading, hasError } = useTypedData(httpClient, endpoint, shape, { mockData }) return { data, isLoading, hasError } } ``` ## Example – Teams list with paging ```tsx theme={null} const endpoint = endpoints.teams.list(true) const shape = createShape()(['Records.Id', 'Records.Name']) const { resource } = useTypedData(httpClient, endpoint, shape, { page: 1, size: 10 }) ``` ## Notes * You can still pass `method`, `data`, and `queryConfig` – these flow through to `useData`. * `mockData` short-circuits fetching – great for the editor and tests. ## See also * [useData](/developers/data/use-data) – Base hook with full config * [createShape](/developers/data/create-shape) – Build type-safe field lists * [useLocationByRouteContext](/developers/state/use-location-by-route-context) – To get the correct `httpClient` # Project Folder Structure Source: https://learn.nexudus.com/developers/folder-structure Developer guide to the repository layout, key folders, and how the pieces fit together. # Project Folder Structure This page gives you a quick tour of the repository so you can find things fast. ## Top-level layout ```text theme={null} . ├─ api/ # Utility/serverless scripts (e.g., SCSS pre-processing) ├─ dist-widget/ # Production build of the embeddable widget (static assets) ├─ dist-widget-debug/ # Debug build of the embeddable widget (+ maps & demo assets) ├─ docs/ # Documentation site (Mintlify) content ├─ public/ # Static assets served by Vite at the site root ├─ scripts/ # Maintenance utilities (e.g., i18n tooling) ├─ src/ # Application source (React + TypeScript) ├─ widget/ # Standalone widget demo/host page and locales ├─ dev.mjs # Local dev helpers ├─ i18next-parser.config.cjs# i18n extraction config ├─ index.html # Vite root HTML (app entry in dev/prod) ├─ jest.config.js # Jest configuration (if/when used) ├─ vite.config.ts # Vite configuration for builds and dev server ├─ vitest.config.ts # Vitest configuration for unit tests ├─ vitest.setup.ts # Test setup (jsdom, mocks, etc.) ├─ tsconfig*.json # TypeScript configuration(s) ├─ bun.lockb # Bun lockfile ├─ package.json # Scripts and dependencies └─ vercel.json # Vercel deployment config (for docs or widget hosting) ``` ## Source code (`src/`) * `api/` – Client-side API helpers (endpoints, fetch wrappers, param parsing, suspense wrappers) * `assets/` – Static assets used by the app (images, data, SCSS sources) * `components/` – Reusable UI components * `errorBoundries/` – Error boundary components and fallbacks * `helpers/` – Pure helper utilities and formatting helpers * `hooks/` – Reusable React hooks * `layouts/` – Layout wrappers (shared chrome) * `routes/` – Route-level components and loaders * `states/` – Global or module-level state containers * `transitions/` – Animation/transition helpers * `types/` – TypeScript type definitions * `utils/` – Generic utilities not tied to React * `views/` – Page-level or feature-complete views * Root files * `App.tsx` – App root * `main.tsx` – Vite entry * `i18n.ts` – i18next initialization * `widget.tsx` – Widget bootstrapping/entry ## Builds and distributions * `dist-widget/` – Production bundle of the widget and its assets. This is what you deploy/embed. * `dist-widget-debug/` – Debug build (includes source maps and demo assets for easier testing). ## Static assets (`public/`) Files in `public/` are served as-is at the site root by Vite. Use this for icons, manifest, and images that should not pass through the bundler. ## Documentation (`docs/`) Mintlify-powered documentation lives here. MDX pages are organized by topic (e.g., `api/`, `overview/`, `customisation/`). The navigation is defined in `docs/docs.json`. ## Scripts and utilities * `api/scss-to-css.ts` – SCSS-to-CSS processing script (used in build/deploy pipelines) * `scripts/` – i18n and maintenance utilities; for example `translate-missing.mjs` and ignored translations lists. ## Widget demo (`widget/`) Contains a minimal host page (`index.htm`) and locales for trying the widget in isolation. ## Testing * `vitest.config.ts`, `vitest.setup.ts` – Unit test configuration (Vitest) * `jest.config.js` – Jest config (kept for compatibility in some environments) ## Notes * Build and dev flows are handled by Vite. Check `package.json` scripts for standard commands. * Internationalization is i18next-based; see `src/i18n.ts` and `public/locales/*`. # Developer Resources Source: https://learn.nexudus.com/developers/overview APIs, tools, and integrations for building on the Nexudus Platform Everything you need to integrate with, extend, and automate the Nexudus Platform. Complete reference for every endpoint in the Nexudus REST API. Manage locations, customers, bookings, billing, and more programmatically. The API that powers the Members Portal. Use it to build custom front-ends, mobile apps, or third-party integrations for your members. API for marketplace providers aggregating inventory data across Nexudus customers. Register your marketplace and sync resources, bookings, and availability. Pull and receive sensor data to trigger actions and display measurements. Connect IoT devices and environmental sensors to your spaces. Connect your access control systems to Nexudus. Build custom integrations for door locks, turnstiles, and other entry systems. Connect with systems and services installed on your Location's local network - without requiring VPNs, static IP addresses, or firewall port forwarding. Command-line tool and AI Agent Skills for managing Nexudus coworking spaces. Automate tasks, manage entities, and integrate with AI assistants. The official .NET SDK for interacting with the Nexudus REST API programmatically. Typed models, CRUD operations, and filtering built in. Learn how to register a new add-on application, configure its settings, and authenticate API requests using application credentials. # LocationContext (provider composition) Source: https://learn.nexudus.com/developers/state/location-context How the application composes location providers, Suspense, auth, and settings to deliver scoped context to your components. # LocationContext `LocationContext` is a thin component that composes the app’s providers in the correct order so your components can rely on a fully-initialized environment: location resolution, auth, settings, and UI scaffolding. It also provides a Suspense fallback for data-driven providers. Source: `src/states/LocationContext.tsx` ## Composition order ```tsx theme={null} export const LocationContext = (props: { children: ReactElement }) => { return ( }> {props.children} ) } ``` At the app root (`src/App.tsx`), the entire tree is wrapped by `LocationByHostProvider` before `LocationContext` is rendered. This guarantees host-level location is available before route-level overrides: ```tsx theme={null} // src/App.tsx {/* boundaries, query, notifications, router */} {/* app pages */} ``` ## Responsibilities * Provide a Suspense boundary (``) for data-loading providers. * Scope business context either by route param (via `LocationByRouteProvider`) or fallback to host (via `LocationByHostProvider` at the app root). * Ensure authentication, location settings, and modal system are available to children. ## When to use Use `LocationContext` to wrap your routed application. If you’re building a standalone view or micro-frontend, replicate the same provider order to guarantee consistent behavior. ## Related hooks and providers * [useLocationByHostContext](/developers/state/use-location-by-host-context) – Resolve business by host/domain * [useLocationByRouteContext](/developers/state/use-location-by-route-context) – Override business by `:webAddress` # useLocationByHostContext Source: https://learn.nexudus.com/developers/state/use-location-by-host-context Resolve and access the current business context from the host/domain and bootstrap scoped HTTP clients. # useLocationByHostContext `useLocationByHostContext` resolves the current Business based on the configured host (domain) and exposes a business-scoped `httpClient`, a root `apiClient`, and the `business` record. It bootstraps the location context used across the app and is intended to wrap the whole application. Typical flow: the app loads using the current host (e.g. `acme.spaces.nWexudus.com`), `LocationByHostProvider` finds the matching Business, and makes that available to all children. Route-level overrides can later switch business via `useLocationByRouteContext`. ## What you get * `Id: number` – Current business ID * `WebAddress: string` – Current business web address * `httpClient: HttpClient` – Axios-like client scoped to `https://{WebAddress}.spaces.nexudus.com` * `apiClient: HttpClient` – API root client using `apiBaseUrl` from app config * `business: Business` – Business details from `endpoints.system.business` ## Provider and placement You must render the provider at the app root, before anything that consumes location state. The repository already does this in `src/App.tsx`: ```tsx theme={null} // src/App.tsx {/* ... */} {/* app content */} {/* ... */} ``` This ensures every consumer of `useLocationByHostContext` or `useLocationByRouteContext` is safely wrapped. ## How it works * Reads `config.host` from `useAppConfig()`. * Fetches `GET /api/sys/businesses/getByHost?host={config.host}` using the root `apiClient(config.apiBaseUrl)`. * Builds `httpClient = ApiHttpClient(WebAddress)` and `apiClient = ApiHttpClient(config.apiBaseUrl)`. * Fetches `business` via `endpoints.system.business` with `includeHeaders: false` to avoid cache invalidation on auth changes. * Throws `NO_BUSINESS_FOR_HOST` if no matching business is found. Source: `src/states/useLocationDomainContext.tsx`. ## Usage example ```tsx theme={null} import { useLocationByHostContext } from '@/states/useLocationDomainContext' export function HostBusinessBadge() { const { business } = useLocationByHostContext() return {business.Name} } ``` `useLocationByRouteContext` will override the `httpClient` and `business` when a `:webAddress` is present in the route; otherwise, consumers see this host-level context. ## Edge cases and errors * Usage outside the provider throws: `useLocationByHostContext must be used within an LocationByHostContext`. * Suspense: data loading is Suspense-based, so ensure a `` boundary above the provider tree (the app already has one in `LocationContext`). * `NO_BUSINESS_FOR_HOST` indicates misconfiguration of the domain/host. ## See also * [useLocationByRouteContext](/developers/state/use-location-by-route-context) – Route param override for business context * [LocationContext](/developers/state/location-context) – Provider composition used by the app # useLocationByRouteContext Source: https://learn.nexudus.com/developers/state/use-location-by-route-context How to scope API calls and business context by the :webAddress route parameter. # useLocationByRouteContext `useLocationByRouteContext` is a React hook that exposes the current Business context and scoped HTTP clients based on the `:webAddress` route parameter. If the parameter is present, the hook resolves the matching business and returns an `httpClient` bound to that business. If it’s absent, it falls back to the host-level location context. It’s designed for multi-location portals where you can deep-link to a specific business (e.g. `/london/bookings`, `/new-york/events`). ## What you get The hook returns the following shape: * `Id: number` – The current business ID * `WebAddress: string` – The current business web address * `httpClient: HttpClient` – An Axios-like client scoped to the current business (`https://{WebAddress}.spaces.nexudus.com`) * `apiClient: HttpClient` – An API root client (base `apiBaseUrl` from app config) * `business: Business` – The full business record fetched from `endpoints.system.business` ## Provider and placement This hook must be used inside `LocationByRouteProvider` (and within a `` boundary, because data loading uses Suspense): ```tsx theme={null} // src/states/LocationContext.tsx export const LocationContext = (props: { children: ReactElement }) => { return ( }> {props.children} ) } ``` If you use the app’s default `LocationContext` wrapper, you’re already covered. ## How it works * Reads `:webAddress` from React Router (`useParams()`). Routes define it as `/:webAddress` or nested via `:webAddress/*`. * If present, fetches `GET /api/sys/businesses/getByHost?host={webAddress}` using the root `apiClient`. * Builds a business-scoped `httpClient = ApiHttpClient(WebAddress)` and copies auth headers from the host context (`httpClient.defaults.headers = hostContext.httpClient.defaults.headers`) to keep the user session. * Fetches the full `business` via `endpoints.system.business` using the scoped `httpClient`. * Uses `useSuspenseFetch(..., { includeHeaders: false })` so auth header changes don’t bust the cache. * If `:webAddress` is missing, it falls back to the host-level location from `useLocationByHostContext`. Source: `src/states/useLocationByRouteContext.tsx` (provider and hook) and `src/states/LocationContext.tsx` (composition). ## Usage examples ### Make business-scoped API calls ```tsx theme={null} import { useLocationByRouteContext } from '@/states/useLocationByRouteContext' export function TeamProfile() { const { httpClient, business } = useLocationByRouteContext() // Call an endpoint scoped to the current business // e.g. httpClient.get('/api/teams') // ... render using `business` fields as needed return
Current business: {business.Name}
} ``` ### Deep-link between businesses Ensure your routes include `:webAddress` and build links with it. When a user navigates, the hook will re-resolve the business and swap the scoped `httpClient` for you. ```tsx theme={null} import { Link, useParams } from 'react-router-dom' export function SwitchBusinessLink({ toWebAddress }: { toWebAddress: string }) { const params = useParams() return ( Go to {toWebAddress} ) } ``` ## Routing contract * Define routes with `:webAddress`, for example: * `path: '/:webAddress'` * or nested: `} />` * When the param is present, the context will re-scope to that business; otherwise it uses the host context. Related code: `src/routes/index.tsx` and `src/routes/HomeRouter.tsx`. ## Edge cases and errors * Hook usage outside its provider throws: `useLocationByRouteContext must be used within an LocationByRouteContext`. * Data loading is Suspense-based; components must render under a `` boundary. * If a `:webAddress` does not resolve to any business, the underlying fetch may trigger your Suspense fallback or error boundary depending on the response. Consider wrapping route segments with an error boundary where appropriate. * Authentication headers are mirrored from the host context each render so sessions persist across business switches. ## See also * [useLocationByHostContext](/developers/state/use-location-by-host-context) – Host-level location resolution and bootstrapping (`src/states/useLocationDomainContext.tsx`). * [LocationContext](/developers/state/location-context) – The app wrapper that composes all providers (`src/states/LocationContext.tsx`). # Styling System Source: https://learn.nexudus.com/developers/styling-system How the Members Portal styling architecture works, and how to extend or adjust existing components. The Members Portal uses **Bootstrap 5.3** with SCSS customisation, **CSS Modules** for component-scoped styles, and **CSS custom properties** for runtime theming. This page explains how these layers work together and how to make changes at each level. ## Architecture overview ``` ┌──────────────────────────────────────────────────────┐ │ Runtime branding colours (per-location) │ ← Highest priority │ Injected via /api/scss-to-css endpoint │ ├──────────────────────────────────────────────────────┤ │ _user.scss │ ← Project-level overrides ├──────────────────────────────────────────────────────┤ │ Component styles (.module.scss + global SCSS) │ ├──────────────────────────────────────────────────────┤ │ custom/ — Bootstrap component extensions │ ├──────────────────────────────────────────────────────┤ │ _variables.scss — Theme colour palette │ ├──────────────────────────────────────────────────────┤ │ _defaults.scss — Base colour defaults │ ├──────────────────────────────────────────────────────┤ │ Bootstrap 5.3 core │ ← Lowest priority └──────────────────────────────────────────────────────┘ ``` Styles are compiled into a single CSS bundle. The compilation order in `style.scss` determines which layer can override which. ## Folder structure All SCSS source files live under `src/assets/scss/`: ```text theme={null} src/assets/scss/ ├── style.scss # Main entry – imports everything in order ├── _defaults.scss # Default colour palette ($primary, $secondary, …) ├── _variables.scss # Derived theme colours, contrast values, CSS vars ├── _variables-dark.scss # Dark-mode variable overrides ├── _dark-mode.scss # Dark-theme component rules ├── _mobile.scss # Mobile-only responsive overrides ├── _user.scss # Project-level custom rules (safe to edit) ├── icon.css # Icon font definitions ├── custom/ # Bootstrap component extensions │ ├── _utilities.scss # Extra utility classes │ ├── _buttons.scss │ ├── _card.scss │ ├── _navbar.scss │ ├── forms/ │ │ ├── _form-check.scss │ │ └── _form-control.scss │ └── … └── components/ # Global component styles ├── _general.scss ├── _avatar.scss ├── _navbar-mobile.scss ├── _sidebar-admin.scss ├── _utilities.scss ├── _stepper.scss └── vendor/ # Third-party library overrides ├── dayPicker.scss ├── flatpickr.scss └── … ``` ## Default colour palette Default colours are defined in `_defaults.scss` using the `!default` flag, which means they can be overridden by any value set before the import: ```scss theme={null} // _defaults.scss $primary: #ff5b13 !default; $secondary: #0f0d76 !default; $success: #008d42 !default; $danger: #dc2626 !default; $warning: #da7500 !default; ``` `_variables.scss` then derives contrast colours, subtle variants, and border colours from these base values and exports them as a `$theme-colors` map. Bootstrap uses this map to generate CSS custom properties like `--bs-primary`, `--bs-primary-bg-subtle`, etc. ## How components are styled Components use one of three patterns (often combined): ### CSS Modules (scoped styles) Component-specific styles live in a `.module.scss` file next to the component. Class names are locally scoped at build time so they never leak. ```tsx theme={null} // ArkSmallCard.tsx import styles from './ArkSmallCard.module.scss' export default function ArkSmallCard({ image }: Props) { return } ``` ```scss theme={null} // ArkSmallCard.module.scss .fullImage { height: calc(100% - 100px); object-fit: cover; position: absolute; top: 0; left: 0; width: 100%; } ``` Use CSS custom properties inside `.module.scss` files to reference theme colours: `color: var(--bs-primary);` ### Bootstrap utility classes Most layout and spacing is handled with Bootstrap 5 utility classes directly in JSX: ```tsx theme={null}
{title}
``` The project extends Bootstrap's utility API in `custom/_utilities.scss` with additional helpers such as fixed-pixel heights (`h-40px`), viewport heights (`vh-100`), and more. ### Global SCSS (unscoped) Some components import a plain `.scss` file for global styles. These affect the entire page and are typically used for animation keyframes or third-party library overrides: ```tsx theme={null} import './Typewriter.scss' ``` Prefer CSS Modules over global imports for new components. Global styles can cause unintended side-effects. ## Runtime branding (per-location colours) Each location can set its own brand colours in the Nexudus dashboard. The portal loads these at runtime through a two-step process: 1. The client fetches `/api/scss-to-css?businessId=&hash=`. 2. The endpoint compiles a virtual SCSS file that overrides `$primary`, `$secondary`, etc. before importing the full `style.scss`. 3. The compiled CSS is cached in Vercel Blob storage with a hash-based filename. 4. An edge function serves the cached file with CDN headers for fast delivery. The virtual SCSS that gets compiled looks like this: ```scss theme={null} $runtime: production; $primary: #; $secondary: #; // … other overrides from the location's colour settings @import 'style.scss'; ``` Because `_defaults.scss` uses `!default`, the runtime values take precedence. ## Dark mode Dark mode is controlled via the `data-bs-theme` attribute on the `` element. The `_dark-mode.scss` file redefines CSS custom properties when this attribute is set: ```scss theme={null} [data-bs-theme='dark'] { --bs-body-bg: #222529; --bs-body-color: #b0b0b8; --bs-border-color: rgba(255, 255, 255, 0.07); // … full dark palette } ``` Theme switching is managed by the `useLayoutContext` hook: ```tsx theme={null} const { updateTheme } = useLayoutContext() updateTheme('dark') // 'light' | 'dark' | 'auto' ``` The preference is saved to `localStorage` and restored on load. When writing component styles, always use CSS custom properties (`var(--bs-body-bg)`) instead of hard-coded colour values. This ensures your styles work in both light and dark modes. ## Extending Bootstrap utilities Custom utility classes are registered in `custom/_utilities.scss` using Bootstrap's utility API. To add a new utility: ```scss theme={null} // custom/_utilities.scss $utilities: map-merge( $utilities, ( "my-custom-util": ( property: opacity, class: custom-opacity, values: ( 25: .25, 50: .5, 75: .75, ) ), ) ); ``` This generates classes like `.custom-opacity-25`, `.custom-opacity-50`, etc. with responsive variants if you add `responsive: true`. ## Overriding Bootstrap component styles Bootstrap component customisations live in `custom/` as partial SCSS files (e.g., `_buttons.scss`, `_card.scss`). These are imported after Bootstrap core, so they can override default styles. To adjust a Bootstrap component: Look in `src/assets/scss/custom/` for an existing file that matches the component (e.g., `_buttons.scss` for buttons). Write your SCSS rules in that file. You can use Bootstrap variables and mixins: ```scss theme={null} // custom/_buttons.scss .btn { border-radius: 0.5rem; font-weight: 600; } ``` Make sure the file is imported in `style.scss`. All existing partials are already imported. ## Adding styles to a new component Add a `.module.scss` file next to your component: ```text theme={null} src/components/MyComponent/ ├── MyComponent.tsx └── MyComponent.module.scss ``` ```scss theme={null} // MyComponent.module.scss .wrapper { padding: 1rem; border: 1px solid var(--bs-border-color); border-radius: var(--bs-border-radius); background: var(--bs-body-bg); } ``` ```tsx theme={null} import styles from './MyComponent.module.scss' export default function MyComponent() { return (

Content

) } ```
Combine CSS Modules for component-specific layout with Bootstrap utilities for spacing and typography. This keeps styles scoped while reusing the design system. ## The `_user.scss` file `_user.scss` is imported last in `style.scss` and is intended for project-level custom rules that don't belong to a specific component or Bootstrap override. It currently contains helpers like `.sticky-top-20`, `.no-select`, and `.disabled-component`. Add rules here when you need a global utility that doesn't fit into Bootstrap's utility API or a component module. ## Key conventions | Practice | Rationale | | ---------------------------------------------------- | -------------------------------------------------- | | Use CSS Modules for new components | Prevents style leaking between components | | Use `var(--bs-*)` for colours | Ensures light/dark mode and branding compatibility | | Never hard-code colour values in components | Runtime branding would not apply | | Put Bootstrap overrides in `custom/` | Keeps overrides organized and discoverable | | Put vendor/library overrides in `components/vendor/` | Separates third-party concerns from project styles | | Use `!default` for new SCSS variables | Allows runtime and theme-level overrides | # useModal Source: https://learn.nexudus.com/developers/ui/use-modal Global modal system with promise-based API and a controller for fully controlled modals. # useModal `useModal` provides a global, promise-based modal API and a controller for building controlled modals. It is backed by a `ModalProvider` that renders two Bootstrap modals: a regular modal and a confirm modal. Source: `src/states/useModalContext.tsx` ## Provider Wrap your app with `ModalProvider`. The default `LocationContext` already includes it, so you usually don’t need to add it yourself. ```tsx theme={null} // src/states/LocationContext.tsx {children} ``` ## API ```ts theme={null} type ModalContent = ReactNode | { render: (controller: ModalController) => ReactNode } type ModalOptions = Partial<{ title: string confirmText: string cancelText: string size: 'sm' | 'lg' | 'xl' bodyClassName: string confirmButtonClass: string // e.g. 'primary', 'danger' confirmHandler: () => () => Promise }> type ModalContext = { showModal: (content: ModalContent, options?: ModalOptions) => Promise hideModal: () => void confirm: (message: ModalContent, options?: ModalOptions) => Promise hideAllModals: () => void setModalsVisible: (visible: boolean) => void } type ModalController = { setTitle(text: string): void setConfirmButtonText(text: string): void setCancelButtonText(text: string): void setConfirmButtonLoading(loading: boolean): void setCancelButtonLoading(loading: boolean): void setConfirmButtonDisabled(disabled: boolean): void setCancelButtonDisabled(disabled: boolean): void setOnConfirm(fn: () => Promise): void close(): void } ``` ## Quick use ```tsx theme={null} import { useModal } from '@/states/useModalContext' const Example = () => { const { showModal, confirm } = useModal() const openInfo = async () => { await showModal(
Hello world
, { title: 'Info' }) } const ask = async () => { const ok = await confirm('Delete this item?', { title: 'Confirm', confirmText: 'Delete', confirmButtonClass: 'danger' }) if (ok) { // proceed } } return ( <> ) } ``` ## Controlled modals (advanced) Controlled modals let the modal content drive button text, loading state, and confirm behavior using the `ModalController`. To opt in, pass a content object with a `render(controller)` function. Inside, call controller setters to update button state or register an async confirm handler. ```tsx theme={null} const { showModal } = useModal() const openControlled = async () => { await showModal( { render: (controller) => (
{ e.preventDefault() controller.setOnConfirm(async () => { controller.setConfirmButtonLoading(true) try { // await API call } finally { controller.setConfirmButtonLoading(false) } }) }}>
), }, { title: 'Create', confirmText: 'Save' }, ) } ``` How it works: * When you call `showModal`, the provider renders the regular modal. * If your content is `{ render(controller) }`, the provider calls your render function and injects a `ModalController`. * You then call `controller.setOnConfirm(fn)` to register the confirm handler; when the user clicks the confirm button (or closes), the provider executes it with error handling: * Shows a LoadingSpinner while the promise is pending (`setConfirmButtonLoading(true)`) * Displays an error `Alert` inside the modal if your handler throws * Closes the modal and resolves the promise when the handler completes successfully Notes: * You can dynamically change title and button labels using `setTitle`, `setConfirmButtonText`, and `setCancelButtonText`. * Disable or enable buttons via `setConfirmButtonDisabled` and `setCancelButtonDisabled`. * Call `controller.close()` to programmatically close the active modal. ## Confirm modals with custom content `confirm(content, options)` behaves similarly, but displays a Cancel + Confirm footer. You can also control it via the same controller pattern: ```tsx theme={null} const ok = await confirm( { render: (controller) => (
Are you absolutely sure? {/* Example: attach extra async work to the confirm action */} {controller.setOnConfirm(async () => { /* async side-effects */ })}
), }, { title: 'Danger zone', confirmText: 'Yes, do it', confirmButtonClass: 'danger' }, ) ``` ## Error handling and loading * The provider wraps your confirm handler in a try/catch and surfaces errors via a danger `Alert` in the modal body. * `LoadingSpinner` is shown automatically on the confirm button while your handler is pending. ## Accessibility and visibility * `setModalsVisible(false)` hides the modal UI but keeps state. Useful for embedded flows where the host temporarily forbids overlays. * Modals are React-Bootstrap `Modal` components; ensure surrounding UI remains keyboard navigable. ## See also * [LocationContext](/developers/state/location-context) – Includes the `ModalProvider` in the app provider stack # Advanced: Iframes, Scripts, CustomerType & ResourcesProvider Source: https://learn.nexudus.com/editor/advanced-components Embed external content, load third-party scripts, conditionally show content by audience type, and provide resources context to child components. The editor includes advanced components for embedding external content, targeting specific audiences, and providing data context to child components. They are found in the **Layout** category of the Blocks panel. *** ## Iframe Embeds an external web page inside your portal page using a standard HTML `