# Create an adhesion Source: https://orgo.space/docs/api-reference/adhesion/create-an-adhesion /api-reference/openapi.json post /api/v1/adhesion/create Creates a new adhesion application in draft (NEW) status. Members can create their own; HR staff with HR_LOCAL permission can create on behalf of another user by passing a userId. # Download adhesion as PDF Source: https://orgo.space/docs/api-reference/adhesion/download-adhesion-as-pdf /api-reference/openapi.json get /api/v1/adhesion/{id}/pdf Generates and returns a PDF document of the adhesion application form. # Get an adhesion Source: https://orgo.space/docs/api-reference/adhesion/get-an-adhesion /api-reference/openapi.json get /api/v1/adhesion/{id} Returns full details of an adhesion application including personal data, identity documents, interview notes, and current status. Access restricted to the applicant, HR staff, and parent local center admins. # List adhesions Source: https://orgo.space/docs/api-reference/adhesion/list-adhesions /api-reference/openapi.json get /api/v1/adhesions Returns a paginated list of adhesion applications. Filterable by status, user, and local center. Results are automatically scoped to the current user permissions. # Send adhesion for review Source: https://orgo.space/docs/api-reference/adhesion/send-adhesion-for-review /api-reference/openapi.json patch /api/v1/adhesion/{id}/send Submits the adhesion application for HR review. Transitions status from NEW to PENDING. Requires both a signed document and an ID document to be uploaded. If submitted by the member (not HR), an email notification is sent to the responsible admin. # Update adhesion data Source: https://orgo.space/docs/api-reference/adhesion/update-adhesion-data /api-reference/openapi.json patch /api/v1/adhesion/update/{id} Updates the personal and professional information on a draft adhesion. Only available while the adhesion is in NEW status. Clears any previously uploaded media. # Update adhesion interview details Source: https://orgo.space/docs/api-reference/adhesion/update-adhesion-interview-details /api-reference/openapi.json patch /api/v1/adhesion/{id}/interview Records or updates interview notes and details for an adhesion. Cannot be edited once the adhesion reaches a final status (REJECTED, SUCCESS). # Update adhesion status Source: https://orgo.space/docs/api-reference/adhesion/update-adhesion-status /api-reference/openapi.json patch /api/v1/adhesion/{id}/status Transitions the adhesion to a new status. Valid statuses: NEW, VALIDATED, INTERVIEWED, REJECTED, SUCCESS. Each transition triggers specific side effects — VALIDATED sends a confirmation email, REJECTED sends a rejection email, SUCCESS assigns the member role and activates the membership. Resetting to NEW clears all uploaded documents. # Upload adhesion video recording Source: https://orgo.space/docs/api-reference/adhesion/upload-adhesion-video-recording /api-reference/openapi.json post /api/v1/adhesion/{id}/upload-video Uploads a video recording for the adhesion application. Replaces any previously uploaded video. The video is recorded by the applicant answering predefined questions. # Upload ID document for adhesion Source: https://orgo.space/docs/api-reference/adhesion/upload-id-document-for-adhesion /api-reference/openapi.json post /api/v1/adhesion/{id}/upload-id Uploads an identity document (ID card, passport) for the applicant. Creates or updates the user identity record and triggers OCR extraction of personal data. Required before the adhesion can be submitted. # Upload signed adhesion document Source: https://orgo.space/docs/api-reference/adhesion/upload-signed-adhesion-document /api-reference/openapi.json post /api/v1/adhesion/{id}/upload-signed Uploads the signed adhesion form as a file attachment. Replaces any previously uploaded signed document. Required before the adhesion can be submitted for review. # Create a badge Source: https://orgo.space/docs/api-reference/badge/create-a-badge /api-reference/openapi.json post /api/v1/badges Creates a new badge definition. Requires ADMIN_TENANT role. Badges can be hours-based (auto-awarded when a user logs enough hours) or manually assigned. # Delete a badge Source: https://orgo.space/docs/api-reference/badge/delete-a-badge /api-reference/openapi.json delete /api/v1/badges/{id} Permanently deletes a badge definition. Requires tenant admin permission. Existing badge assignments may be affected. # Get a badge Source: https://orgo.space/docs/api-reference/badge/get-a-badge /api-reference/openapi.json get /api/v1/badges/{id} Retrieves a single badge by ID. Requires tenant admin permission. # List badges Source: https://orgo.space/docs/api-reference/badge/list-badges /api-reference/openapi.json get /api/v1/badges Returns all badges for the current tenant. Paginated with up to 1000 items per page. # Update a badge Source: https://orgo.space/docs/api-reference/badge/update-a-badge /api-reference/openapi.json patch /api/v1/badges/{id} Updates badge properties such as name, description, hours threshold, or image. Requires tenant admin permission. # Delete a badge hour entry Source: https://orgo.space/docs/api-reference/badgehour/delete-a-badge-hour-entry /api-reference/openapi.json delete /api/v1/badge_hours/{id} Removes a badge hour log entry. Requires HR_ASSISTANT_LOCAL or HR_ASSISTANT_TENANT permission on the target user. The entry owner can also delete their own entries. # Get a badge hour entry Source: https://orgo.space/docs/api-reference/badgehour/get-a-badge-hour-entry /api-reference/openapi.json get /api/v1/badge_hours/{id} Retrieves a single badge hour log entry by ID, showing the user, number of hours, and related badge context. # List badge hours Source: https://orgo.space/docs/api-reference/badgehour/list-badge-hours /api-reference/openapi.json get /api/v1/badge_hours Returns all badge hour log entries for the current tenant. Each record represents hours contributed by a user toward earning hours-based badges. # Log badge hours Source: https://orgo.space/docs/api-reference/badgehour/log-badge-hours /api-reference/openapi.json post /api/v1/badge_hours Records hours for a user toward badge completion. Sets the current user as the entry owner. Automatically recalculates the user total hours and awards any hours-based badges whose threshold is now met. Requires HR_ASSISTANT_LOCAL or HR_ASSISTANT_TENANT permission on the target user. # Update a badge hour entry Source: https://orgo.space/docs/api-reference/badgehour/update-a-badge-hour-entry /api-reference/openapi.json patch /api/v1/badge_hours/{id} Updates an existing badge hour log entry. Automatically recalculates the user total hours and awards any hours-based badges whose threshold is now met. Requires HR_ASSISTANT_LOCAL or HR_ASSISTANT_TENANT permission on the target user. # Create a badge type Source: https://orgo.space/docs/api-reference/badgetype/create-a-badge-type /api-reference/openapi.json post /api/v1/badge_types Creates a new badge type (category) for organizing badges. Requires ADMIN_TENANT role. # Delete a badge type Source: https://orgo.space/docs/api-reference/badgetype/delete-a-badge-type /api-reference/openapi.json delete /api/v1/badge_types/{id} Permanently deletes a badge type (category). Requires tenant admin permission. Badges associated with this type may be affected. # Get a badge type Source: https://orgo.space/docs/api-reference/badgetype/get-a-badge-type /api-reference/openapi.json get /api/v1/badge_types/{id} Retrieves a single badge type (category) by ID. Requires tenant admin permission. # List badge types Source: https://orgo.space/docs/api-reference/badgetype/list-badge-types /api-reference/openapi.json get /api/v1/badge_types Returns all badge types (categories) for the current tenant. Paginated with up to 1000 items per page. # Update a badge type Source: https://orgo.space/docs/api-reference/badgetype/update-a-badge-type /api-reference/openapi.json patch /api/v1/badge_types/{id} Updates a badge type (category) name or properties. Requires tenant admin permission. # Assign a badge to a user Source: https://orgo.space/docs/api-reference/badgeuser/assign-a-badge-to-a-user /api-reference/openapi.json post /api/v1/badge_users Manually assigns a badge to a user. Sets the current user as the assignment owner. Requires HR_ASSISTANT_LOCAL permission on the target user, or HR_ASSISTANT_TENANT permission. Validates that the badge belongs to the same tenant. # Get a badge assignment Source: https://orgo.space/docs/api-reference/badgeuser/get-a-badge-assignment /api-reference/openapi.json get /api/v1/badge_users/{id} Retrieves a single badge assignment record by ID, showing which user holds which badge and when it was awarded. # List badge assignments Source: https://orgo.space/docs/api-reference/badgeuser/list-badge-assignments /api-reference/openapi.json get /api/v1/badge_users Returns all badge-to-user assignments for the current tenant. Each record links a user to a badge they have earned or been awarded. # Remove a badge from a user Source: https://orgo.space/docs/api-reference/badgeuser/remove-a-badge-from-a-user /api-reference/openapi.json delete /api/v1/badge_users/{id} Removes a badge assignment from a user. Requires HR_ASSISTANT_LOCAL permission on the target user, or HR_ASSISTANT_TENANT permission. The assignment owner can also remove their own assignments. # Update a badge assignment Source: https://orgo.space/docs/api-reference/badgeuser/update-a-badge-assignment /api-reference/openapi.json patch /api/v1/badge_users/{id} Updates properties of an existing badge assignment. Requires HR_ASSISTANT_LOCAL permission on the target user, or HR_ASSISTANT_TENANT permission. The assignment owner can also edit their own assignments. # Add member to bundle Source: https://orgo.space/docs/api-reference/bundlemember/add-member-to-bundle /api-reference/openapi.json patch /api/v1/bundle/{id}/add-member Adds a user to a fee bundle by email address. Requires the request body to contain an "email" field. The target user must exist in the same tenant and not already belong to another bundle. The slot must be empty. Creates a product payment record cloned from the bundle coordinator last paid period and updates the member fee validity date. Only the bundle coordinator or a tenant admin can perform this action. # Remove member from bundle Source: https://orgo.space/docs/api-reference/bundlemember/remove-member-from-bundle /api-reference/openapi.json patch /api/v1/bundle/{id}/remove-member Removes the current member from a bundle slot. Deletes all product payment records for the member associated with their bundle product price and resets their fee validity date to null. Only the bundle coordinator or a tenant admin can perform this action. # Create a certification Source: https://orgo.space/docs/api-reference/certification/create-a-certification /api-reference/openapi.json post /api/v1/certifications Creates a new certification record on the authenticated user profile. The user is automatically set to the current authenticated user. # Delete a certification Source: https://orgo.space/docs/api-reference/certification/delete-a-certification /api-reference/openapi.json delete /api/v1/certifications/{id} Permanently deletes a certification record from the user profile. Only the certification owner can perform this action. # Get a certification Source: https://orgo.space/docs/api-reference/certification/get-a-certification /api-reference/openapi.json get /api/v1/certifications/{id} Retrieves a single certification record by ID. Certifications represent professional credentials or qualifications on a user profile. # List certifications Source: https://orgo.space/docs/api-reference/certification/list-certifications /api-reference/openapi.json get /api/v1/certifications Returns certifications filtered by the required "user" query parameter. The user parameter must be provided or access is denied. # Update a certification Source: https://orgo.space/docs/api-reference/certification/update-a-certification /api-reference/openapi.json patch /api/v1/certifications/{id} Updates a certification record. Only the certification owner can perform this action. # Add member to company Source: https://orgo.space/docs/api-reference/company/add-member-to-company /api-reference/openapi.json post /api/v1/companies/{uuid}/members Adds an existing user or contact as a member of the company. Provide either "userId" or "contactId" in the request body, along with an optional "role" (defaults to MEMBER). The user/contact must belong to the same tenant. # Create a company Source: https://orgo.space/docs/api-reference/company/create-a-company /api-reference/openapi.json post /api/v1/companies Creates a new company and adds the current user as primary contact. Requires the company feature to be enabled on the tenant. Tenant settings control whether all users or only admins can create companies. Non-admin users cannot create a company if they already belong to one. # Create company bank transfer invoice Source: https://orgo.space/docs/api-reference/company/create-company-bank-transfer-invoice /api-reference/openapi.json post /api/v1/companies/{uuid}/bank-transfer-invoice Generates an unpaid invoice for company membership payment via bank transfer. Requires bank transfer and invoice features to be enabled on the tenant. Validates billing info (name, address) and checks for existing pending invoices. Sends the invoice by email. Requires COMPANY_MANAGE_PAYMENTS permission or tenant admin role. # Delete a company Source: https://orgo.space/docs/api-reference/company/delete-a-company /api-reference/openapi.json delete /api/v1/companies/{uuid} Permanently deletes a company and all associated memberships. Restricted to tenant administrators only. # Get a company Source: https://orgo.space/docs/api-reference/company/get-a-company /api-reference/openapi.json get /api/v1/companies/{uuid} Retrieves a single company by ID. Requires COMPANY_VIEW permission on the company or tenant admin role. # Get company payment checkout Source: https://orgo.space/docs/api-reference/company/get-company-payment-checkout /api-reference/openapi.json get /api/v1/companies/{uuid}/payment-checkout Creates a Stripe checkout session for the company membership fee. The company must have a membership plan selected. Returns a checkout session URL for redirect. Requires COMPANY_MANAGE_PAYMENTS permission or tenant admin role. # Get company status counts Source: https://orgo.space/docs/api-reference/company/get-company-status-counts /api-reference/openapi.json get /api/v1/companies/status-counts Returns a breakdown of company counts grouped by status for the current tenant. Supports an optional "name" query parameter to filter counts by company name. # Get my company Source: https://orgo.space/docs/api-reference/company/get-my-company /api-reference/openapi.json get /api/v1/my-company Returns the company the current user belongs to, along with their role in that company. Returns 204 No Content if the user is not a member of any company or if the company has been deleted. # Leave a company Source: https://orgo.space/docs/api-reference/company/leave-a-company /api-reference/openapi.json post /api/v1/companies/{uuid}/leave Removes the current user from the company. If the user is the last remaining member, the company is soft-deleted (status set to DELETED) and the user membership is reset. Returns "companyDeleted" flag in the response. Requires active company membership. # List companies Source: https://orgo.space/docs/api-reference/company/list-companies /api-reference/openapi.json get /api/v1/companies Returns a paginated list of companies within the current tenant, ordered by name. Supports standard API Platform filters for status, name, and other fields. # List company invitations Source: https://orgo.space/docs/api-reference/company/list-company-invitations /api-reference/openapi.json get /api/v1/companies/{uuid}/invitations Returns all invitations for the specified company, including pending, accepted, declined, and revoked. Sensitive fields (hash, message) are excluded from the response. Requires COMPANY_MANAGE_INVITATIONS permission or tenant admin role. # Remove member from company Source: https://orgo.space/docs/api-reference/company/remove-member-from-company /api-reference/openapi.json delete /api/v1/companies/{uuid}/members/{userId} Removes a user from the company membership. Requires COMPANY_MANAGE_MEMBERS permission or tenant admin role. The user must be an active member of the company. # Resend company invitation Source: https://orgo.space/docs/api-reference/company/resend-company-invitation /api-reference/openapi.json post /api/v1/companies/{uuid}/invitations/{invitationId}/resend Resends the invitation email and resets the expiration date. The invitation must belong to the specified company. Requires COMPANY_MANAGE_INVITATIONS permission or tenant admin role. No request body needed. # Revoke company invitation Source: https://orgo.space/docs/api-reference/company/revoke-company-invitation /api-reference/openapi.json delete /api/v1/companies/{uuid}/invitations/{invitationId} Revokes a pending invitation, preventing the recipient from accepting it. The invitation must belong to the specified company. Requires COMPANY_MANAGE_INVITATIONS permission or tenant admin role. # Send company invitation Source: https://orgo.space/docs/api-reference/company/send-company-invitation /api-reference/openapi.json post /api/v1/companies/{uuid}/invitations Sends an email invitation to join the company. Requires "email", "firstName", and "lastName" in the request body. Optionally include "roles" (array) or legacy "role" (string) and a personal "message". Sends a branded invitation email with an accept/decline link. Requires COMPANY_MANAGE_INVITATIONS permission or tenant admin role. # Set company member role Source: https://orgo.space/docs/api-reference/company/set-company-member-role /api-reference/openapi.json patch /api/v1/companies/{uuid}/members/{userId}/role Toggles a role on a company member (adds if not present, removes if present). Requires the caller to be the company primary contact or a tenant admin. The member must have an active (non-ended) membership. Send "role" in the request body. # Set member join date Source: https://orgo.space/docs/api-reference/company/set-member-join-date /api-reference/openapi.json patch /api/v1/companies/{uuid}/members/{userId}/date-joined Updates the join date for a company member (user or contact). Send "dateJoined" (ISO 8601) and optionally "memberType" ("user" or "contact", defaults to "user") in the request body. Requires COMPANY_MANAGE_MEMBERS permission or tenant admin role. # Update a company Source: https://orgo.space/docs/api-reference/company/update-a-company /api-reference/openapi.json patch /api/v1/companies/{uuid} Updates company details such as name, address, VAT number, and contact information. Requires COMPANY_EDIT permission or tenant admin role. # Accept company invitation Source: https://orgo.space/docs/api-reference/companyinvitation/accept-company-invitation /api-reference/openapi.json post /api/v1/company-invitation/{hash}/accept Public endpoint that accepts a company invitation by hash. If the invited email matches an existing user, adds them to the company and sends a login OTP. If no user exists, creates a new account with the invitation details and sends a login OTP. Rate-limited to prevent abuse. Returns tempToken for OTP verification flow. # Decline company invitation Source: https://orgo.space/docs/api-reference/companyinvitation/decline-company-invitation /api-reference/openapi.json post /api/v1/company-invitation/{hash}/decline Declines a company invitation by hash. Marks the invitation as declined so it can no longer be accepted. Requires an authenticated user. No request body needed. # Get a company invitation Source: https://orgo.space/docs/api-reference/companyinvitation/get-a-company-invitation /api-reference/openapi.json get /api/v1/company_invitations/{id} Retrieves a company invitation by its internal ID. Requires an authenticated user. # Get public invitation by hash Source: https://orgo.space/docs/api-reference/companyinvitation/get-public-invitation-by-hash /api-reference/openapi.json get /api/v1/company-invitation/{hash} Public endpoint (no auth required) that retrieves invitation details by its unique hash link. Returns company name, logo, inviter name, personal message, assigned roles, expiration date, and validity status. Used for the invitation landing page. # Get a company user Source: https://orgo.space/docs/api-reference/companyuser/get-a-company-user /api-reference/openapi.json get /api/v1/company_users/{id} Retrieves a single company-user membership record, including the user details, roles, and join date. Requires COMPANY_VIEW permission on the parent company or tenant admin role. # List company users Source: https://orgo.space/docs/api-reference/companyuser/list-company-users /api-reference/openapi.json get /api/v1/company_users Returns a paginated list of company memberships within the current tenant. Filter by company, user, or role using standard API Platform filters. Results include nested user/contact details with max depth support. # Authentication Source: https://orgo.space/docs/api-reference/concepts/authentication How to authenticate against the Orgo API and when to use each method The Orgo API accepts several authentication methods. The one you should use depends on who is calling and from where. | Method | Who uses it | Header | | ------------------ | -------------------------------------------------------------------------------- | ------------------------------------------------- | | **OAuth 2.0** | A third-party app or agent acting as a member | `Authorization: Bearer ` | | **Api-Token** | Servers, scripts, CRON jobs you control | `Api-Token: ` | | **Bearer JWT** | A user who logged in with email + password | `Authorization: Bearer ` | | **OTP** | A user logging in via emailed one-time code | Returns a JWT, then `Authorization: Bearer ` | | **X-Contact-Hash** | An emailed contact opening an event link | `X-Contact-Hash: ` | | **Legacy SSO** | Existing apps using the `*-sso` handshake — [deprecated](#legacy-sso-deprecated) | `Authorization: Bearer ` | Two quick rules of thumb: * Building an app that logs members in **as themselves**? Use **OAuth 2.0**. It is the supported path for third-party apps and agents. * Running a backend job that acts **as itself**, with no end user in the loop? Use an **Api-Token**. Every URL below is on **your tenant's host**. The host *is* the tenant selector — the bare `app.orgo.space` domain resolves no tenant and returns `404`. Examples use `acme.orgo.space`; substitute your own. See [Tenancy](/docs/api-reference/concepts/tenancy). *** ## OAuth 2.0 (third-party apps and agents) Orgo is a standards OAuth 2.0 authorization server with OIDC discovery. Use the authorization code flow with PKCE. ### Discovery Read the metadata rather than hardcoding URLs: ```bash theme={null} curl https://acme.orgo.space/.well-known/oauth-authorization-server # alias: curl https://acme.orgo.space/.well-known/openid-configuration ``` | Key | Value | | --------------------------------------- | ----------------------------------------------------- | | `issuer` | `https://acme.orgo.space` | | `authorization_endpoint` | `{issuer}/authorize` | | `token_endpoint` | `{issuer}/api/v1/oauth/token` | | `userinfo_endpoint` | `{issuer}/api/v1/oauth/userinfo` | | `jwks_uri` | `{issuer}/api/v1/oauth/jwks.json` | | `registration_endpoint` | `{issuer}/api/v1/oauth/register` | | `scopes_supported` | `["profile","email","groups","roles"]` | | `response_types_supported` | `["code"]` | | `grant_types_supported` | `["authorization_code","refresh_token"]` | | `code_challenge_methods_supported` | `["S256"]` | | `token_endpoint_auth_methods_supported` | `["none","client_secret_basic","client_secret_post"]` | | `subject_types_supported` | `["public"]` | | `id_token_signing_alg_values_supported` | `["RS256"]` | The consent screen sits at `/authorize` while the machine endpoints sit under `/api/v1/oauth/*`. That asymmetry is intentional — use the URLs exactly as discovery returns them. The discovery document is **per tenant**: `issuer` reflects the host you fetched it from. Fetch discovery once per tenant host. Never reuse one tenant's document for another. ### Registering a client Two kinds of client, differing in whether a secret exists. Any developer can register a public client. No authentication required, rate limited to **10 registrations per hour per IP**: ```bash theme={null} curl -X POST https://acme.orgo.space/api/v1/oauth/register \ -H "Content-Type: application/json" \ -d '{ "redirect_uris": ["https://your-app.example.com/callback"], "client_name": "Civic Forum" }' ``` Returns `201` with a `client_id`, `client_id_issued_at`, and your echoed metadata. **No client secret is issued** — PKCE is the only client authentication. Optional metadata: `client_uri`, `logo_uri`, `policy_uri`, `tos_uri`. When no scopes are requested the defaults are `profile` and `email`. A tenant admin creates the app in **Developer → Apps**. This issues both a `client_id` and a `client_secret`, and the client **must** authenticate at the token endpoint. Store the secret server-side only. See [OAuth Server](/docs/platform/oauth) for the admin side. ### Step 1 — send the member to the consent screen ``` GET https://acme.orgo.space/authorize ?response_type=code &client_id=YOUR_CLIENT_ID &redirect_uri=https://your-app.example.com/callback &scope=profile%20email &state= &code_challenge= &code_challenge_method=S256 ``` **PKCE is mandatory for every client, confidential ones included.** This is stricter than baseline OAuth 2.0 and matches OAuth 2.1. The server rejects violations with `invalid_request`: * `code_challenge_method` must be `S256`. `plain` is not supported. * `code_challenge` must match `[A-Za-z0-9-._~]{43,128}`. * `code_verifier` must match the same charset and length rules. If the member is not signed in, Orgo sends them through login and returns them to the consent screen automatically — including when they sign in with Google, Apple or Microsoft. Your app does nothing for this. ### Step 2 — exchange the code ```bash theme={null} curl -X POST https://acme.orgo.space/api/v1/oauth/token \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "grant_type=authorization_code" \ -d "code=$CODE" \ -d "redirect_uri=https://your-app.example.com/callback" \ -d "client_id=$CLIENT_ID" \ -d "code_verifier=$VERIFIER" ``` ```json theme={null} { "access_token": "eyJ...", "token_type": "Bearer", "expires_in": 3600, "refresh_token": "...", "scope": "profile email" } ``` Confidential clients additionally authenticate — see [Client authentication](#client-authentication) below. `redirect_uri` must exactly equal the one used in step 1. ### Step 3 — refresh ```bash theme={null} curl -X POST https://acme.orgo.space/api/v1/oauth/token \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "grant_type=refresh_token" \ -d "refresh_token=$REFRESH_TOKEN" \ -d "client_id=$CLIENT_ID" ``` **Refresh tokens rotate.** Every refresh returns a new `refresh_token` and invalidates the one you sent. Persist the new value on each refresh — a client that keeps replaying its original refresh token will stop working. ### Token lifetimes | Token | Lifetime | | ----------------------- | --------------------------------- | | Access token | **1 hour** | | Refresh token | **30 days**, rotated on every use | | Legacy SSO access token | **1 year**, no refresh token | ### Authorization code rules * **Single use.** Redeeming twice fails with `invalid_grant`. * **A replay by an authenticated client revokes the tokens that code produced.** This is the OAuth 2.1 interception defence — never retry a code blindly after a successful exchange. * A *failed client authentication* leaves the code redeemable, so a client that fixes its credentials can safely retry the same code. ### Client authentication | Method | Who | How | | --------------------- | ------------------------ | -------------------------------------------------------------------- | | `none` | Public / self-registered | PKCE only. Sending a `client_secret` is an error (`invalid_client`). | | `client_secret_basic` | Confidential | `Authorization: Basic base64(urlencode(id):urlencode(secret))` | | `client_secret_post` | Confidential | `client_secret` form field | Use exactly one method: * Credentials sent by more than one method → `invalid_request`. * A `client_id` in the Basic header disagreeing with the body → `invalid_request`. * A confidential client omitting its secret → `invalid_client` (`401`, with `WWW-Authenticate: Basic realm="orgo-oauth"`). Token-endpoint errors are RFC 6749 shaped and sent with `Cache-Control: no-store`: ```json theme={null} { "error": "invalid_client", "error_description": "…" } ``` Codes in use: `invalid_request`, `invalid_client`, `invalid_grant`, `unsupported_grant_type`, `rate_limit_exceeded`. **Wrong secrets are throttled.** Repeated *failed* client authentications for the same `client_id` are rate limited: after 10 failures in 5 minutes, further failures return `429 rate_limit_exceeded` with a `Retry-After` header instead of `401`. A request presenting the correct secret is never throttled, however many failed attempts preceded it — so a healthy client is unaffected, and a `429` here means your credentials are wrong, not that you are calling too often. ### Using the access token ```bash theme={null} curl https://acme.orgo.space/api/v1/oauth/userinfo \ -H "Authorization: Bearer $ACCESS_TOKEN" ``` Returns an OIDC-shaped profile (`sub`, `name`, `email`, …). The same token works against the rest of the API: ```bash theme={null} curl https://acme.orgo.space/api/v1/users/me \ -H "Authorization: Bearer $ACCESS_TOKEN" ``` Access tokens are RS256 JWTs, verifiable against `jwks_uri`. Tokens are also **revocable server-side**, and revocation takes effect on the next request. A token that still looks valid locally — unexpired signature, `exp` in the future — can be rejected. Do not treat a local expiry check as proof a token still works; handle `401` at any time. ### What actually bounds a token Two limits surprise most integrators. Neither is configurable per request. **An app acts as a member, never as an administrator.** A token issued to an app that a tenant admin created is capped to member level (`ROLE_USER`), regardless of what the authorizing member can do in the Orgo UI. If a tenant administrator authorizes your app, your token still cannot perform administrator actions. **Read-only apps are gated by HTTP method.** Every app is flagged either read-only or permitted to act on the member's behalf. A read-only app may use `GET`, `HEAD` and `OPTIONS` only; any `POST`, `PUT`, `PATCH` or `DELETE` is rejected with `403`: ``` This application has read-only access and may not act on your behalf. ``` The gate is by **HTTP method, not intent**. An endpoint that performs a read via `POST` — some search endpoints do — is still blocked for a read-only app. If your integration needs those, it must be registered with acting enabled. The consent screen shows the member which of these applies before they approve. ### Scopes `profile`, `email`, `groups` and `roles` are advertised in discovery, shown on the consent screen, and recorded in the token's `scope` claim. Scopes describe what an application **requests** and what the member **approves** when they authorize it. What the resulting token can actually reach is bounded by the member-level cap and the application's read-only / act-on-behalf setting described above. Request only the scopes you need — it keeps the consent screen short and makes it clearer to the member what they are approving. Full walkthrough: [Integrate "Log in with Orgo"](/docs/api-reference/recipes/integrate-oauth-login). Admin-side setup: [OAuth Server](/docs/platform/oauth). *** ## Api-Token (server-to-server) Generate a token at **Settings → Developers → API Access**. Send it as a raw header — there is no `Bearer` prefix and no encoding: ```bash theme={null} curl https://your-org.orgo.space/api/v1/users \ -H "Api-Token: 7f3c8b4e2a..." ``` Tokens carry one of two access levels: * **Read/write** — full access to whatever the owning user can do. * **Read-only** — any `POST`, `PATCH`, `PUT`, or `DELETE` is rejected with `403 Forbidden`. Useful for analytics integrations. Tokens inherit the permissions of the user that created them. If the user loses a role, the token loses the same access. Revoke a token by deleting it in the same UI — it stops working immediately. Tokens grant durable access. Never commit them, log them, or send them to a client browser. Rotate periodically and prefer one token per integration so you can revoke individually. *** ## JWT (interactive login) For sessions started by a user typing email + password, exchange those credentials for a JWT: ```bash theme={null} curl -X POST https://your-org.orgo.space/api/v1/login-check \ -H "Content-Type: application/json" \ -d '{"username":"alice@example.com","password":""}' ``` Response: ```json theme={null} { "token": "eyJ0eXAiOiJKV1QiLCJhbGc...", "refresh_token": "f3c7a..." } ``` Send the JWT on every subsequent call: ```bash theme={null} curl https://your-org.orgo.space/api/v1/me \ -H "Authorization: Bearer eyJ0eXAi..." ``` JWTs are valid for approximately **11 days**. After expiry, exchange the refresh token at `POST /api/v1/token/refresh` for a new pair. JWTs are scoped to the tenant the login was made against — calling a different tenant's host with the same JWT will fail with `401`. *** ## OTP (one-time password) For users who do not have a password — or who prefer a magic-link flow — Orgo can send a 6-digit code by email. Two steps: ```bash theme={null} # 1. Request the code curl -X POST https://your-org.orgo.space/api/v1/request-login-otp \ -H "Content-Type: application/json" \ -d '{"email":"alice@example.com"}' # 2. Verify the code (returns a JWT exactly like /login-check) curl -X POST https://your-org.orgo.space/api/v1/verify-login-otp \ -H "Content-Type: application/json" \ -d '{"email":"alice@example.com","otp":"483921"}' ``` OTP requests are rate-limited per email — typically 20 requests per 60 seconds — to prevent abuse. From there, the returned JWT is used exactly like the password-login JWT. OTP is also the auth method used by the event-app surface (members logging in from inside an event landing page) and for password resets. *** ## X-Contact-Hash (anonymous contacts) When Orgo emails a Contact (someone without a user account) an event invitation or a form link, the email contains a magic URL with a hash. That hash is also the auth header: ```bash theme={null} curl https://your-org.orgo.space/api/v1/event_attends/12345 \ -H "X-Contact-Hash: 9a8f7e6d5c..." ``` This authenticates the contact for that specific event and that specific contact identity — they cannot use the hash to access other contacts' data. Most server-to-server integrations will not use this; it is here for completeness. *** ## Legacy SSO (deprecated) **Deprecated.** The `/api/v1/*-sso` token exchange is deprecated in favour of [OAuth 2.0](#oauth-20-third-party-apps-and-agents). Existing integrations continue to work and **no removal date has been set**. New integrations must use the authorization code flow. Responses from these endpoints now carry a `Deprecation` header and a `Link: rel="deprecation"` pointer to this section. If you arrived here from a `Deprecation` header, this is the flow you are using. It is a proprietary handshake that predates Orgo's OAuth support: | Endpoint | Role in the handshake | | -------------------------------------- | ------------------------------------------------------------------------------ | | `POST /api/v1/request-token-sso` | App exchanges its `appId` + `appSecret` for a `requestToken` | | `GET /api/v1/verify-request-token-sso` | Looks up a `requestToken`, returns the app's display name for the login screen | | `POST /api/v1/login-check-sso` | Member submits credentials against the `requestToken`, returns a `redirectUri` | | `GET /api/v1/verify-success-token-sso` | App exchanges the `successToken` for the member's profile and an access token | | `GET /api/v1/logout-sso` | Discards the login request | `verify-success-token-sso` returns a flat member profile — `id`, `cardId`, `firstName`, `lastName`, `email`, `status`, `localCenter`, `town`, membership dates — alongside a **1-year** access token with no refresh token. The access token is minted once per login; re-reading the profile does not mint a new one or invalidate the existing token. Only the token exchange is deprecated. Creating apps and regenerating their secrets is **not** deprecated, and tokens issued this way are subject to the same [member-level cap and read-only gate](#what-actually-bounds-a-token) as OAuth tokens. ### Migrating to OAuth 2.0 1. **Keep your existing `client_id` and `client_secret`.** The secret hash format is unchanged, so no rotation is required to migrate. 2. Replace the `request-token-sso` redirect with `GET /authorize`, adding PKCE. 3. Replace `verify-success-token-sso` with `POST /api/v1/oauth/token`. 4. Replace the profile payload from `verify-success-token-sso` with `GET /api/v1/oauth/userinfo`. 5. Expect a **1-hour access token plus a rotating refresh token** instead of the legacy 1-year token — add refresh handling before you switch. *** ## Picking the right method **Api-Token.** Read-only if you only need to fetch data; read/write if you need to create or update. **JWT.** Call `POST /api/v1/login-check` with the user's credentials, store the returned JWT, and send it on every subsequent call. **OAuth 2.0.** Self-register a public client at `/api/v1/oauth/register`, or have a tenant admin create a confidential one, then run the authorization code flow with PKCE. **OAuth 2.0**, registered with acting enabled. Remember the two bounds: the token is capped to member level, and a read-only app cannot issue any `POST`, `PUT`, `PATCH` or `DELETE` — including reads implemented as `POST`. **OTP.** Two-step: `request-login-otp` then `verify-login-otp`. Returns a JWT. **X-Contact-Hash.** The hash is in the URL Orgo emails; lift it into the header on subsequent API calls. That is the [legacy handshake](#legacy-sso-deprecated) — still supported, now deprecated. Follow the migration steps when you can; there is no removal date. *** ## Common authentication errors | Status | What it means | Fix | | ----------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------ | | `401 Unauthorized` | Header missing, malformed, or invalid token | Re-send the header; if the token looks right it may have been revoked — revocation applies on the next request, so handle this at any time | | `403 Forbidden` — `This API token has read-only access.` | A read-only **Api-Token** was used for a write | Use a read/write token, or switch the call to `GET` | | `403 Forbidden` — `This application has read-only access and may not act on your behalf.` | A read-only **OAuth app** attempted a non-`GET`/`HEAD`/`OPTIONS` call | The app must be registered with acting enabled — see [what bounds a token](#what-actually-bounds-a-token) | | `403 Forbidden` (other) | Authenticated, but the member lacks permission — remember an app token is capped to member level | Check the member's role for this resource | | `404 Not Found` | Resource exists but in a different tenant | Confirm you are calling the correct subdomain — see [Tenancy](/docs/api-reference/concepts/tenancy) | Token-endpoint errors use the RFC 6749 envelope instead — see [client authentication](#client-authentication). *** ## Related * [Tenancy](/docs/api-reference/concepts/tenancy) — getting the tenant context right is half of getting auth right * [Integrate "Log in with Orgo"](/docs/api-reference/recipes/integrate-oauth-login) — end-to-end OAuth walkthrough * [Errors](/docs/api-reference/concepts/errors) — full error envelope reference * [OAuth Server](/docs/platform/oauth) — admin-side setup for OAuth applications # Content types Source: https://orgo.space/docs/api-reference/concepts/content-types JSON-LD versus plain JSON versus multipart, and the Hydra collection envelope The Orgo API supports three response formats and two request formats. Most endpoints accept all of them — the format is chosen by the `Accept` and `Content-Type` headers. For 95% of integrations, **plain `application/json`** is the right choice. Use JSON-LD when you need pagination metadata or generic link discovery, and multipart only when you are uploading files. *** ## Response formats | `Accept` header | Format | When to use | | --------------------------------- | ------------------ | ---------------------------------------------------------------------------------------------------------------------- | | `application/ld+json` *(default)* | JSON-LD with Hydra | You want collection metadata (`hydra:totalItems`, next-page links) or are building a generic client that follows links | | `application/json` | Plain JSON | Most integrations — simpler shape, no `@context`/`@id`/`@type` | | `multipart/form-data` | Multipart | Rarely useful as a response format; included for symmetry with multipart requests | If you do not send an `Accept` header at all, JSON-LD is returned by default. ### Example: the same resource, three ways `GET /api/v1/users/42` returns one of these depending on the `Accept` header: ```json theme={null} { "@context": "/api/contexts/User", "@id": "/api/v1/users/42", "@type": "User", "id": 42, "firstName": "James", "lastName": "Patterson", "email": "james.patterson@example.com", "status": "ACTIVE", "localCenter": { "@id": "/api/v1/local_centers/4", "@type": "LocalCenter", "id": 4, "name": "Boston" } } ``` ```json theme={null} { "id": 42, "firstName": "James", "lastName": "Patterson", "email": "james.patterson@example.com", "status": "ACTIVE", "localCenter": { "id": 4, "name": "Boston" } } ``` The data is the same — JSON-LD just adds the `@context`, `@id`, `@type` wrapping that lets generic clients reason about the response without knowing the schema in advance. *** ## The Hydra collection envelope JSON-LD collections are wrapped in a Hydra envelope that carries totals and pagination links: ```json theme={null} { "@context": "/api/contexts/User", "@id": "/api/v1/users", "@type": "hydra:Collection", "hydra:member": [ { "@id": "/api/v1/users/42", "firstName": "James", ... }, { "@id": "/api/v1/users/43", "firstName": "Emma", ... } ], "hydra:totalItems": 1248, "hydra:view": { "@id": "/api/v1/users?page=2", "@type": "hydra:PartialCollectionView", "hydra:first": "/api/v1/users?page=1", "hydra:last": "/api/v1/users?page=42", "hydra:previous": "/api/v1/users?page=1", "hydra:next": "/api/v1/users?page=3" } } ``` Plain JSON returns just the array: ```json theme={null} [ { "id": 42, "firstName": "James", ... }, { "id": 43, "firstName": "Emma", ... } ] ``` **You lose `hydra:totalItems` and the next-page links in plain JSON.** If you need to display "showing 60 of 1,248" or iterate every page, use JSON-LD. For ad-hoc scripting and one-off integrations, plain JSON is shorter and easier to consume. For data-pipeline integrations that need to paginate through everything, JSON-LD is usually worth the slightly noisier envelope. *** ## Request formats | `Content-Type` header | Method | When to use | | ------------------------------ | --------------- | -------------------------------------------------------------------------- | | `application/json` | `POST`, `PUT` | Create or full-replace a resource — most common | | `application/merge-patch+json` | `PATCH` | Partial update following RFC 7396 (send only fields you want to change) | | `application/ld+json` | `POST`, `PUT` | Same as plain JSON but you can include `@id` references to other resources | | `multipart/form-data` | `POST`, `PATCH` | File uploads — see below | ### PATCH and merge-patch Always send `Content-Type: application/merge-patch+json` for PATCH. The endpoint only updates the fields you include — missing fields are left untouched. ```bash theme={null} # Update James's phone number, leave everything else alone curl -X PATCH https://acme.orgo.space/api/v1/users/42 \ -H "Api-Token: $TOKEN" \ -H "Content-Type: application/merge-patch+json" \ -d '{"phoneNumber":"+1 415 555 0142"}' ``` Sending `null` for a field explicitly clears it (where the field is nullable). Sending an empty string is treated as the literal empty string. ### Referencing other resources For relations, send the IRI (Internationalized Resource Identifier) of the target: ```json theme={null} { "firstName": "James", "lastName": "Patterson", "email": "james.patterson@example.com", "localCenter": "/api/v1/local_centers/4", "type": "/api/v1/roles/12" } ``` This works for both JSON and JSON-LD requests. Sending the full nested object instead of the IRI is also accepted but slower and more error-prone — prefer IRIs. ### File uploads (multipart) For endpoints that accept file uploads — ID documents, contract signatures, course media, drive files, profile pictures — use `multipart/form-data`: ```bash theme={null} curl -X POST https://acme.orgo.space/api/v1/adhesion/123/upload-id \ -H "Api-Token: $TOKEN" \ -F "idMedia=@/path/to/passport.pdf" ``` The field name (`idMedia` above) is documented per endpoint. For endpoints that accept both metadata and files, include the metadata as additional form fields: ```bash theme={null} curl -X POST https://acme.orgo.space/api/v1/drives \ -H "Api-Token: $TOKEN" \ -F "name=Annual Report 2026" \ -F "file=@/path/to/report.pdf" ``` *** ## When in doubt * **You're a human writing a curl by hand**: omit `Accept` (defaults to JSON-LD) for the metadata, or set `Accept: application/json` for cleaner output. * **You're writing an integration**: `Accept: application/json` for reads, `Content-Type: application/json` for writes, `Content-Type: application/merge-patch+json` for partial updates, `Content-Type: multipart/form-data` for uploads. * **You're building a generic browser/client over the API**: stay on JSON-LD throughout so you get the link relations. *** ## Related * [Pagination and filters](/docs/api-reference/concepts/pagination-and-filters) — how to iterate collections * [Errors](/docs/api-reference/concepts/errors) — error envelope shape (same for all content types) # Errors Source: https://orgo.space/docs/api-reference/concepts/errors Error envelope shape, every status code, and when to retry The Orgo API returns errors as JSON. Two envelope shapes exist — one for general errors, one for validation errors. Both carry the HTTP status in the body as well as in the response status line, so you can log either reliably. *** ## General error envelope For most errors (`400`, `401`, `403`, `404`, `409`, `500`): ```json theme={null} { "title": "Bad Request", "detail": "Email must be a valid email address.", "status": 400 } ``` | Field | Always present | Notes | | -------- | -------------- | --------------------------------------------------------------- | | `title` | yes | Short, human-readable summary — usually matches the HTTP status | | `detail` | yes | Human-readable description of *what specifically* went wrong | | `status` | yes | HTTP status code, mirroring the response status line | Some errors include additional context (e.g., the conflicting resource ID on a `409`) under a `context` or `meta` field — these are documented per endpoint. *** ## Validation error envelope (422) When the API rejects a request because field-level validation failed, the response includes a `violations` array enumerating each failed field: ```json theme={null} { "@context": "/api/contexts/ConstraintViolationList", "@type": "ConstraintViolationList", "title": "An error occurred", "detail": "email: This value is not a valid email address.\nphoneNumber: This value is too short.", "violations": [ { "propertyPath": "email", "message": "This value is not a valid email address.", "code": "bd79c0ab-ddba-46cc-a703-a7a4b08de310" }, { "propertyPath": "phoneNumber", "message": "This value is too short. It should have 7 characters or more.", "code": "9ff3fdc4-b214-49db-8718-39c315e33d45" } ] } ``` Iterate `violations[]` to surface each error next to the right form field. `code` is a stable Symfony validator UUID — useful if you want to localize the message without parsing the English text. *** ## Status codes The request is malformed at the HTTP/JSON level: invalid JSON syntax, wrong `Content-Type`, missing required query parameter, unknown enum value. ```json theme={null} { "title": "Bad Request", "detail": "Expected one of: NEW, ACTIVE, INACTIVE. Got: ENABLED.", "status": 400 } ``` **Retry?** No. The same request will fail again. Inspect `detail` and fix. The auth header is missing, malformed, or carries an expired/revoked token. JWT might have expired (refresh it); Api-Token might have been revoked. ```json theme={null} { "title": "Unauthorized", "detail": "Invalid JWT Token", "status": 401 } ``` **Retry?** Yes, after refreshing the token or re-authenticating. If a fresh token still fails, the tenant might be wrong — see [Tenancy](/docs/api-reference/concepts/tenancy). You're authenticated, but your user (or the API token's owner) lacks the permission required for this action. Common reasons: * The token is read-only and you sent a write * The user has `HR_LOCAL` but the resource is in a different local center * The endpoint requires `ADMIN_TENANT` and the user is `HR_LOCAL` ```json theme={null} { "title": "Forbidden", "detail": "Access Denied.", "status": 403 } ``` **Retry?** No. Have an admin grant the missing permission, or use a different token. The resource does not exist, OR exists but belongs to a different tenant than the one your auth is scoped to. Orgo returns `404` (not `403`) in the second case so the absence of the resource is indistinguishable from "exists but forbidden" — preventing tenant-existence leaks. ```json theme={null} { "title": "Not Found", "detail": "The referenced resource was not found or is no longer accessible.", "status": 404 } ``` **Retry?** No. Verify the ID/URL and the tenant host. The request would create a conflict with the current state of the resource. Two common causes: * **Optimistic locking**: another writer updated the record between your read and your write. Refetch and retry. * **Illegal state transition**: e.g., trying to mark a contract as signed twice, or transition an adhesion to a state that is not reachable from its current state. * **Duplicate identifier**: e.g., creating a resource whose external ID already exists. ```json theme={null} { "title": "Conflict", "detail": "Cannot create: a resource with this identifier already exists. Please refresh and try again.", "status": 409 } ``` **Retry?** *Sometimes*. For optimistic-lock collisions: refetch, reconcile your changes, retry. For illegal state transitions: no — fix the workflow. For duplicate IDs: no — use a different identifier or update the existing resource. The request is well-formed but one or more fields failed validation (required, format, length, custom rules). ```json theme={null} { "@type": "ConstraintViolationList", "title": "An error occurred", "detail": "email: This value is not a valid email address.", "violations": [ { "propertyPath": "email", "message": "This value is not a valid email address.", "code": "bd79c0ab-..." } ], "status": 422 } ``` **Retry?** No. Iterate `violations[]`, surface each error next to the right form field, let the user correct, and resubmit. You hit the per-endpoint rate limit (usually 20/min on write-heavy endpoints like login or send-email). ```json theme={null} { "title": "Too Many Requests", "detail": "Rate limit exceeded. Try again in 47 seconds.", "status": 429 } ``` The response includes a `Retry-After` header (seconds). **Retry?** Yes, after `Retry-After`. See [Rate limits](/docs/api-reference/concepts/rate-limits). Something went wrong inside Orgo. The `detail` may be generic ("An error occurred") to avoid leaking internals. **Retry?** Yes, with exponential backoff. If a 500 reproduces on the same call repeatedly, contact support with the request ID from the response headers. Load balancer, application server, or upstream dependency is unreachable. **Retry?** Yes, with exponential backoff (start \~1s, double up to \~30s, give up after \~5 minutes). *** ## Retry strategy A safe default for any integration: ```python theme={null} import time import requests def call_orgo(method, url, **kwargs): backoff = 1 for attempt in range(6): resp = requests.request(method, url, **kwargs) if resp.status_code < 500 and resp.status_code != 429: return resp if resp.status_code == 429: time.sleep(int(resp.headers.get("Retry-After", backoff))) else: time.sleep(backoff) backoff = min(backoff * 2, 30) return resp # final attempt, give up ``` Do **not** retry: * `400`, `401`, `403`, `404`, `422` — retrying produces the same failure * `409` from illegal state transitions or duplicate IDs — retrying still conflicts * `409` from optimistic locks — refetch first, then retry once (not in a tight loop) *** ## Logging tips Save the request ID from response headers (when present) — it lets support trace the exact request in our logs. The body's `status` field mirrors the HTTP status, so you can log just the response body and recover the status from JSON without needing two fields. *** ## Related * [Authentication](/docs/api-reference/concepts/authentication) — what 401 and 403 mean per auth method * [Tenancy](/docs/api-reference/concepts/tenancy) — why a 404 may actually be a tenant mismatch * [Rate limits](/docs/api-reference/concepts/rate-limits) — how to avoid 429 in the first place # Pagination and filters Source: https://orgo.space/docs/api-reference/concepts/pagination-and-filters Iterating collections and narrowing them with filters and ordering Every collection endpoint in Orgo (`GET /api/v1/users`, `GET /api/v1/events`, `GET /api/v1/payments`, ...) supports the same pagination, filtering, and ordering query parameters. Once you learn the pattern on one endpoint, the rest follow the same shape. *** ## Pagination basics Defaults: **30 items per page**, maximum **100 per page**. | Query parameter | Purpose | Default | | --------------- | --------------------------------------------------- | ------- | | `page` | 1-indexed page number | `1` | | `itemsPerPage` | Page size (capped at 100) | `30` | | `pagination` | Set to `false` to disable pagination, where allowed | `true` | ```bash theme={null} # First page, default size GET /api/v1/users # Second page, 50 items per page GET /api/v1/users?page=2&itemsPerPage=50 # As many items as the endpoint allows in one go GET /api/v1/countries?pagination=false ``` `pagination=false` is only honored on endpoints flagged for it (mostly small reference lists like countries and counties). On large collections it is ignored — you must paginate. *** ## Iterating every page The reliable way to iterate all pages depends on which response format you accept. ### With JSON-LD (the default) Follow `hydra:view.hydra:next` until it is absent: ```python theme={null} import requests url = "https://acme.orgo.space/api/v1/users?itemsPerPage=100" headers = {"Api-Token": "..."} while url: resp = requests.get(url, headers=headers).json() for user in resp["hydra:member"]: process(user) url = resp.get("hydra:view", {}).get("hydra:next") if url and not url.startswith("http"): # Hydra returns relative URLs; join against the host url = f"https://acme.orgo.space{url}" ``` ### With plain JSON You do not get totals or next-page links — increment `page` until the response is shorter than `itemsPerPage`: ```python theme={null} page = 1 per_page = 100 while True: resp = requests.get( f"https://acme.orgo.space/api/v1/users?page={page}&itemsPerPage={per_page}", headers={"Api-Token": "...", "Accept": "application/json"} ).json() for user in resp: process(user) if len(resp) < per_page: break page += 1 ``` For long-running exports, prefer JSON-LD — `hydra:totalItems` lets you display progress and `hydra:next` is a stable signal that the server still has more rows. *** ## Filtering Filters are query-string parameters. The available filters differ per resource and are listed under each endpoint's **Parameters** section in the reference. ### Exact-value filter ```bash theme={null} GET /api/v1/users?status=ACTIVE GET /api/v1/events?isPublic=true ``` ### Filter by relation (IRI) When filtering by a relation, pass the related resource's IRI: ```bash theme={null} GET /api/v1/users?localCenter=/api/v1/local_centers/4 GET /api/v1/event_attends?event=/api/v1/events/9c4f... ``` You can also pass just the ID — the server resolves both shapes: ```bash theme={null} GET /api/v1/users?localCenter=4 ``` ### Multi-value (OR) Repeat the parameter to filter against any of several values: ```bash theme={null} GET /api/v1/users?localCenter[]=4&localCenter[]=7&localCenter[]=12 ``` Returns users in local center 4, 7, *or* 12. ### Keyword search Most user-facing collections support a `keyword` parameter for full-text search across the most-relevant fields: ```bash theme={null} GET /api/v1/users?keyword=patterson GET /api/v1/events?keyword=annual+meeting ``` ### Date range Date filters use the `[before]`, `[after]`, `[strictly_before]`, `[strictly_after]` modifiers: ```bash theme={null} GET /api/v1/events?startDate[after]=2026-01-01T00:00:00Z GET /api/v1/payments?datePaid[after]=2026-01-01&datePaid[before]=2026-12-31 ``` ### Boolean Use `true` / `false`: ```bash theme={null} GET /api/v1/users?isFullMember=true GET /api/v1/events?isPublic=false ``` ### Custom-field filters User and Contact resources expose a `customFieldValues.value` filter that targets the value column of the custom-fields table. Pair with `customFieldValues.customField` (the custom field IRI) to target a specific field: ```bash theme={null} GET /api/v1/users?customFieldValues.customField=/api/v1/custom_fields/8&customFieldValues.value=Vegetarian ``` *** ## Ordering Use `order[field]=asc|desc`. Order by multiple fields by repeating the parameter: ```bash theme={null} # Single field, descending GET /api/v1/events?order[startDate]=desc # Two fields — first by status, then by name GET /api/v1/events?order[status]=asc&order[name]=asc # By a related resource's field GET /api/v1/users?order[localCenter.name]=asc&order[lastName]=asc ``` The default order varies per resource (usually `dateCreated` descending for "feed" resources like Events and Newsletters, alphabetic for reference data). *** ## Combining filters, ordering, and pagination Stack them with `&`: ```bash theme={null} GET /api/v1/users?status=ACTIVE &localCenter=/api/v1/local_centers/4 &keyword=james &order[lastName]=asc &page=1 &itemsPerPage=50 ``` URL-encode parameter values that contain spaces or special characters (`?keyword=annual%20meeting`). Most HTTP clients do this automatically. *** ## Performance notes * Collection endpoints fetch and serialize each row's full read group. For large datasets, prefer narrow filters before broad ones (`?status=ACTIVE` shrinks the row count *before* any extra joins). * `itemsPerPage=100` is the maximum — larger requests return at most 100 and the rest must be paginated. * Sorting by a non-indexed column on a large collection can be slow. If a sort feels slow, check whether the column is documented as filterable — those are guaranteed indexed. *** ## Related * [Content types](/docs/api-reference/concepts/content-types) — the Hydra envelope shape used in JSON-LD pagination * [Errors](/docs/api-reference/concepts/errors) — what bad filter / order values produce # Rate limits Source: https://orgo.space/docs/api-reference/concepts/rate-limits Per-endpoint limits, how 429 responses look, and how to design integrations that never trip them Rate limiting on the Orgo API is **per endpoint** and **per token**, not a single global bucket. Most endpoints have no application-layer limit at all — they are only protected by platform-level infrastructure throttles. Limits exist on endpoints that are expensive (sending email, generating PDFs) or sensitive to abuse (login, OTP requests, impersonation). *** ## How limits are applied When an endpoint is rate-limited: * The limit is **20 requests per 60 seconds** by default. Some endpoints set their own. * The bucket is keyed by the **authenticated token** (Api-Token or JWT), or by **IP address** for unauthenticated endpoints. * Hitting the limit returns `429 Too Many Requests` with a `Retry-After` header telling you how many seconds to wait. Read-heavy endpoints (`GET /api/v1/users`, `GET /api/v1/events`, etc.) are *not* application-rate-limited under normal circumstances — you can paginate freely. *** ## Endpoints with explicit limits | Endpoint family | Why limited | Typical limit | | ---------------------------------------------------------------------- | --------------------------- | ------------------ | | `POST /api/v1/login-check` | Brute-force protection | 20 / 60s per IP | | `POST /api/v1/request-login-otp` | Email abuse prevention | 20 / 60s per email | | `POST /api/v1/verify-login-otp` | Brute-force protection | 20 / 60s per email | | `POST /api/v1/request-password-reset-otp` | Email abuse prevention | 20 / 60s per email | | `POST /api/v1/newsletters/{uuid}/send` | Outbound-email cost control | varies per plan | | `POST /api/v1/email_templates/send-test` | Outbound-email cost control | 20 / 60s | | `POST /api/v1/permission/impersonate/*` | Audit/abuse protection | 20 / 60s per admin | | `POST /api/v1/webhook_subscriptions/{id}/test` | Outbound-HTTP cost control | 20 / 60s | | `GET /api/v1/contacts-csv`, `GET /api/v1/users-csv` | DB load on large exports | 20 / 60s | | File-generation endpoints (PDF invoices, adhesion PDFs, contract PDFs) | CPU cost | 20 / 60s | Where a limit is not listed in an endpoint's reference page, assume it is not application-rate-limited beyond platform protections. *** ## The 429 response ```http theme={null} HTTP/1.1 429 Too Many Requests Content-Type: application/json Retry-After: 47 ``` ```json theme={null} { "title": "Too Many Requests", "detail": "Rate limit exceeded. Try again in 47 seconds.", "status": 429 } ``` Always honor `Retry-After`. Retrying inside the window will *not* succeed and only delays your overall throughput. *** ## Designing for the limits Many endpoints have explicit bulk variants: `POST /api/v1/contacts/bulk-delete`, `POST /api/v1/waitlist_entries/bulk-approve`, etc. Each bulk call counts as **one** request and is far cheaper than N individual calls. Prefer bulk endpoints over `for entry in entries: api.delete(entry)` loops. `itemsPerPage=100` is the cap. Setting it lower means more requests for the same data and a higher chance of tripping platform-level throttles. Use 100 unless you have a specific reason not to. If you find yourself polling `GET /api/v1/payments?status=PENDING` every few seconds, subscribe to the `product_payment.updated` webhook instead. Webhooks deliver in under a second and cost no API calls. See [Webhooks](/docs/api-reference/concepts/webhooks). Do not call `/api/v1/login-check` before every request. Cache the JWT for its full \~11-day lifetime and only re-login when a request returns `401`. The same applies to OAuth access tokens — cache and refresh on demand, never on every call. For nightly data syncs, schedule them during your tenant's off-hours. The platform handles concurrent tenants well, but a single integration making a thousand requests at noon still adds latency on top of normal user traffic. *** ## Retry pattern A safe pattern that handles both 429 and transient 5xx: ```python theme={null} import time import requests def call(method, url, **kw): backoff = 1 for attempt in range(6): r = requests.request(method, url, **kw) if r.status_code == 429: wait = int(r.headers.get("Retry-After", backoff)) time.sleep(wait) elif r.status_code >= 500: time.sleep(backoff) else: return r backoff = min(backoff * 2, 30) return r ``` The same pattern in JavaScript / TypeScript: ```ts theme={null} async function call(input: RequestInfo, init?: RequestInit): Promise { let backoff = 1000; for (let attempt = 0; attempt < 6; attempt++) { const r = await fetch(input, init); if (r.status === 429) { const retryAfter = Number(r.headers.get("Retry-After") ?? backoff / 1000); await new Promise(res => setTimeout(res, retryAfter * 1000)); } else if (r.status >= 500) { await new Promise(res => setTimeout(res, backoff)); } else { return r; } backoff = Math.min(backoff * 2, 30000); } throw new Error("call failed after 6 attempts"); } ``` *** ## Per-plan limits There is no per-plan rate limit at the application layer today. Higher-volume plans get more generous platform-level concurrency budgets (more API workers, larger DB connection pools), but the per-endpoint application limits above are the same regardless of plan. If you have a use case that needs limits raised on a specific endpoint — high-volume webhook sender, large nightly export, etc. — contact support and we can adjust on a per-tenant basis. *** ## Related * [Errors](/docs/api-reference/concepts/errors) — the 429 envelope and full retry strategy * [Webhooks](/docs/api-reference/concepts/webhooks) — the cure for polling # Tenancy Source: https://orgo.space/docs/api-reference/concepts/tenancy How the API resolves the current tenant and why subdomain choice matters Orgo is multi-tenant. Every organization that uses Orgo gets its own isolated workspace — its own users, events, payments, contracts, files. Two organizations cannot see each other's data, ever, even if a query is misconfigured. This page explains how the API knows which tenant a request is for, and what to do when the answer is wrong. *** ## Tenant resolution: the `Host` header The tenant is resolved from the HTTP `Host` header of the incoming request. Each organization has either a subdomain on `orgo.space` or a fully-custom domain: ``` https://acme.orgo.space/api/v1/users → tenant = "acme" https://members.your-org.com/api/v1/users → tenant = "your-org" ``` There is **no header, query parameter, or JWT claim that overrides this**. The host *is* the tenant selector. ```bash theme={null} # ✓ Correct — host is the tenant curl https://acme.orgo.space/api/v1/users \ -H "Api-Token: $TOKEN" # ✗ Wrong — calling the bare app.orgo.space domain returns 404 # for tenant-scoped endpoints because no tenant resolves curl https://app.orgo.space/api/v1/users \ -H "Api-Token: $TOKEN" ``` The OpenAPI spec lists `https://app.orgo.space` as the base URL only because the API playground needs *some* URL. For real requests, swap that for your tenant's host. *** ## Why this matters for tokens Tokens are tenant-scoped at the moment they are issued: * **Api-Token**: tied to the user who created it; that user belongs to one tenant; the token only works against that tenant's host. * **JWT** (from `/login-check` or `/verify-login-otp`): contains a `session_id` claim bound to the tenant of the host the login was performed against. * **OAuth access tokens**: bound to the tenant where the OAuth application was registered. A token from tenant A cannot be used against tenant B. Trying produces `401 Unauthorized`. *** ## Cross-tenant access is blocked at the persistence layer Inside Orgo's backend, Doctrine extensions automatically add `WHERE entity.tenant = current_tenant` to every read. Even if a developer wrote `SELECT * FROM users` without a tenant filter, the extension would inject the filter before the query runs. This is enforced at the ORM level so no API endpoint can leak across tenants. The one exception is OTP-issued JWTs used by the event-app surface (members opening an event landing page from a different tenant they were invited to). Those JWTs carry an `auth_strength: OTP` claim and a `verified_email` instead of a `session_id`, and they can cross tenants but only for the event-attendance endpoints. *** ## Resolving your tenant host Every tenant admin can find their host in the admin UI under **Settings → Organisation → Domains**. Common shapes: | Shape | Example | Notes | | ------------------ | ------------------ | ------------------------------------------------ | | Default subdomain | `acme.orgo.space` | Always available, even after custom-domain setup | | Custom subdomain | `members.acme.org` | Configured by the admin | | Apex custom domain | `acme.org` | Less common; requires DNS at the apex | The default subdomain always works, even when a custom domain is also configured. Use it for integrations to avoid breakage if the admin changes the custom-domain setup. *** ## What happens when the tenant is missing or wrong | Scenario | Response | | -------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------ | | Host doesn't match any tenant | `404 Not Found` from the load balancer before Symfony sees the request | | Host matches a tenant, but token is from another tenant | `401 Unauthorized` | | Host matches, token is valid, but the requested resource belongs to a different tenant | `404 Not Found` (not `403` — leaking "exists but forbidden" would itself be a tenant leak) | The 404 in the last row is intentional. From outside, "not found" and "exists in another tenant" are indistinguishable. This is the same pattern GitHub uses for private repos. *** ## Tenant context in webhook deliveries Webhook payloads carry a top-level `tenant_id` field so a single receiver subscribed to multiple tenants can route events. See [Webhooks](/docs/api-reference/concepts/webhooks). ```json theme={null} { "id": "wh_evt_67aa128c2f4a", "event": "user.created", "tenant_id": 142, "created": 1704067200, "object": { ... } } ``` *** ## Common scenarios Check that the host you are calling matches the tenant the token was issued for. The same token against the wrong host produces 401, not 403. Generate one Api-Token per tenant (each from an admin user in that tenant) and route by hostname server-side. There is no "super-token" that crosses tenants. Switch to the `*.orgo.space` default subdomain. It is permanent and never changes. Yes — `GET /api/v1/tenant-host/{slug}` returns the current canonical host for a tenant slug. This endpoint is public (no auth needed). *** ## Related * [Authentication](/docs/api-reference/concepts/authentication) — how tokens carry tenant scope * [Errors](/docs/api-reference/concepts/errors) — what each tenant-mismatch error looks like # Webhooks Source: https://orgo.space/docs/api-reference/concepts/webhooks Receive event notifications from Orgo over HTTP — subscribe, verify, handle idempotently Orgo can push event notifications to a URL you control. Subscribe to any subset of 18 event types, register an HTTPS endpoint, and Orgo delivers a signed JSON POST every time a matching event happens. This page is the reference. For a complete walkthrough — including idempotent handling and replay — see [Handle webhooks](/docs/api-reference/recipes/handle-webhooks). *** ## Available events | Family | Events | When they fire | | -------------------- | ------------------------------------------------------------------------------- | ----------------------------------------------------- | | **User** | `user.created`, `user.updated`, `user.deleted` | New registrations, profile changes, account deletion | | **Payment** | `product_payment.created`, `product_payment.updated`, `product_payment.deleted` | Stripe checkout, bank transfer mark-paid, refunds | | **Event attendance** | `event_attend.created`, `event_attend.updated`, `event_attend.deleted` | Member RSVPs, confirmations, check-ins, cancellations | | **Contract** | `contract_user.created`, `contract_user.updated`, `contract_user.deleted` | Contract assigned, signed, force-resign | | **Role** | `user_role.created`, `user_role.updated`, `user_role.deleted` | Permission grants and revocations | | **Contact** | `contact.created`, `contact.updated`, `contact.deleted` | CRM contact added, updated, removed | Every event ships with the full entity snapshot (`object`) and, for updates, a diff (`previous_attributes`). The complete payload schemas are in the [Webhooks section](#webhook-events) of the playground. *** ## Subscribing Create a subscription via the API or in the admin UI under **Settings → Developers → Webhooks**. ```bash theme={null} curl -X POST https://acme.orgo.space/api/v1/webhook_subscriptions \ -H "Api-Token: $ORGO_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "url": "https://your-app.example.com/webhooks/orgo", "events": ["user.created", "product_payment.updated"], "secret": "whsec_a3f8b2c4d6e8f1a3b5c7d9e1f3a5b7c9", "active": true, "description": "Sync new members and payments into our CRM." }' ``` The `secret` is yours to choose — a 32-byte random string is standard. Orgo uses it to sign each delivery so you can verify the payload came from Orgo. *** ## Payload envelope Every delivery, regardless of event type, has the same outer shape (Stripe-inspired). Only the `object` and `previous_attributes` differ per event. ```json theme={null} { "id": "wh_evt_67aa128c2f4a", "event": "user.created", "api_version": "2024-01", "created": 1735689600, "tenant_id": 1, "request": { "id": "req_8c2f4a67aa12" }, "object": { "@id": "/api/v1/users/42", "id": 42, "firstName": "James", "lastName": "Patterson", "email": "james.patterson@example.com", "status": "NEW" }, "previous_attributes": null, "is_update": false, "entity_type": "user", "operation": "created" } ``` | Field | Always present | Notes | | --------------------------------------- | ------------------- | -------------------------------------------------------------- | | `id` | yes | Unique per delivery — **the idempotency key** | | `event` | yes | The event type (e.g. `user.created`) | | `api_version` | yes | Schema version of the payload (currently `2024-01`) | | `created` | yes | Unix timestamp (seconds) when Orgo emitted the event | | `tenant_id` | yes | The Orgo tenant ID — use for routing in multi-tenant receivers | | `request` | yes | Metadata about the API request that triggered the event | | `object` | yes | Snapshot of the entity at the moment of emission | | `previous_attributes` | only on `*.updated` | Diff against prior state — `null` on create/delete | | `is_update`, `entity_type`, `operation` | yes | Denormalized helpers | The OpenAPI spec declares a `Webhook.` schema for each event type (e.g. `Webhook.UserCreated`) — use these in your typed client for autocomplete and validation. *** ## Delivery headers | Header | Purpose | | --------------------- | --------------------------------------------------------------------------------------------------------------------------- | | `X-Webhook-Event` | The event type (e.g. `user.created`) | | `X-Webhook-Delivery` | Unique delivery ID — log this; you can look it up in the dashboard | | `X-Webhook-Timestamp` | Unix timestamp of when this delivery was sent (use for replay-attack defense) | | `X-Webhook-Signature` | HMAC-SHA256 over the delivery, keyed with the subscription secret. Sent only when the subscription has a secret (see below) | | `Content-Type` | `application/json` | | `User-Agent` | `OrgoWebhook/1.0` | *** ## Authenticating the sender Set a `secret` on the subscription and every delivery carries `X-Webhook-Signature` in this shape: ``` X-Webhook-Signature: t=1754413200,v1=3f9c0e2b… ``` | Part | Meaning | | ---- | --------------------------------------------------------------------------------------- | | `t` | Unix seconds at signing time. Same value as `X-Webhook-Timestamp` | | `v1` | `HMAC-SHA256(secret, "." + raw request body)`, hex encoded, lowercase, 64 characters | The timestamp is inside the signed string, so it cannot be edited without invalidating `v1`. That is what lets you reject a captured delivery replayed later. Verify against the **raw body**. A body that has been parsed and re-serialized is a different byte string and will not match. ```javascript theme={null} const crypto = require("crypto"); function verify(rawBody, header, secret, toleranceSeconds = 300) { const parts = Object.fromEntries( header.split(",").map((p) => p.split("=", 2)) ); if (!parts.t || !parts.v1) return false; if (Math.abs(Date.now() / 1000 - Number(parts.t)) > toleranceSeconds) { return false; // too old, or too far in the future } const expected = crypto .createHmac("sha256", secret) .update(`${parts.t}.${rawBody}`) .digest("hex"); const a = Buffer.from(expected, "utf8"); const b = Buffer.from(parts.v1, "utf8"); return a.length === b.length && crypto.timingSafeEqual(a, b); } ``` ```python theme={null} import hashlib, hmac, time def verify(raw_body: bytes, header: str, secret: str, tolerance: int = 300) -> bool: parts = dict(p.split("=", 1) for p in header.split(",")) if "t" not in parts or "v1" not in parts: return False if abs(time.time() - int(parts["t"])) > tolerance: return False expected = hmac.new( secret.encode(), parts["t"].encode() + b"." + raw_body, hashlib.sha256, ).hexdigest() return hmac.compare_digest(expected, parts["v1"]) ``` Respond `401` and log the delivery ID when verification fails. Orgo treats that as a failed delivery and retries it, which is the behavior you want if the failure is your own misconfiguration. Each retry is signed at the moment it is sent, so the same delivery ID can arrive with different `t` and `v1` values. Deduplicate on the payload `id` or `X-Webhook-Delivery`, never on the signature. This format shipped in August 2026 and replaced a short non-keyed checksum. There is no compatibility header: a receiver comparing the old value must move to the recipe above. *** ## Idempotency Orgo may deliver the same event twice — retries on transient failures, network races on at-least-once delivery. Your handler must be safe to call repeatedly with the same payload. The simplest pattern: track processed deliveries by `payload["id"]`. ```python theme={null} def handle(payload: dict) -> None: delivery_id = payload["id"] with db.transaction(): if db.processed_deliveries.exists(delivery_id): return # already handled db.processed_deliveries.insert(delivery_id, processed_at=now()) dispatch(payload) ``` Keep delivery IDs for at least 30 days. If you can, insert the dedup row in the same transaction as the side effect — that closes a window where a crash mid-handler leaves the dedup row but not the effect. *** ## Retry behavior | Trigger | Behavior | | ----------------------------------- | -------------------------------------------------------------------------------------- | | Receiver returns 2xx | Marked delivered. No retries. | | Receiver returns non-2xx | Retry up to **3 times** with exponential backoff (up to \~10 minutes between attempts) | | Receiver doesn't respond within 30s | Treated as failed; retried | | Receiver TLS error | Treated as failed; retried | | All retries fail | Marked permanently failed; visible in delivery logs | The subscription itself is **not** automatically deactivated on repeated failures — your own monitoring should watch for high failure rates. *** ## Delivery logs and replay Every delivery attempt — success or failure — is logged for \~90 days. To list: ```bash theme={null} curl https://acme.orgo.space/api/v1/webhook_subscriptions/3/delivery_logs \ -H "Api-Token: $ORGO_API_TOKEN" ``` For each failed delivery, the original payload is included — replay it locally without needing Orgo to re-deliver. *** ## Testing Before going live, send a synthetic event to your endpoint: ```bash theme={null} curl -X POST https://acme.orgo.space/api/v1/webhook_subscriptions/3/test \ -H "Api-Token: $ORGO_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{"event": "user.created"}' ``` The synthetic payload uses fixture data (not real user data) but carries the same headers and shape your handler will see in production. Use this in CI to validate end-to-end delivery. *** ## Webhook events Each event type is declared as a "webhook" in the OpenAPI spec — Mintlify renders them in the playground under a Webhooks section. Click into any event to see its full payload schema, headers, and example. The 18 events are listed at the top of this page. *** ## Related * [Handle webhooks](/docs/api-reference/recipes/handle-webhooks) — full receiver walkthrough with idempotency and replay * [Sync your CRM with Orgo](/docs/api-reference/recipes/sync-your-crm-with-orgo) — webhooks in a real-world sync scenario * [Rate limits](/docs/api-reference/concepts/rate-limits) — why webhooks beat polling # Bulk delete contacts Source: https://orgo.space/docs/api-reference/contact/bulk-delete-contacts /api-reference/openapi.json post /api/v1/contacts/bulk-delete Deletes multiple contacts in a single request. Expects a JSON body with a "contacts" array of contact IDs. Skips contacts that have successful product payments and returns a summary with deleted and skipped counts. Enforces tenant isolation on each contact. Requires HR_LOCAL or FINANCIAL_LOCAL permission. # Create a contact Source: https://orgo.space/docs/api-reference/contact/create-a-contact /api-reference/openapi.json post /api/v1/contacts Creates a new contact record. If an email is provided, checks for duplicates against both contacts and existing user accounts, returning HTTP 409 if a conflict is found. Sets the source to MANUAL and persists any custom field values from the request. Requires HR_LOCAL or FINANCIAL_LOCAL permission. # Delete a contact Source: https://orgo.space/docs/api-reference/contact/delete-a-contact /api-reference/openapi.json delete /api/v1/contacts/{id} Permanently deletes a contact. Blocked if the contact has any successful product payments attached. Requires HR_LOCAL or FINANCIAL_LOCAL permission scoped to the contact local center. # Export contacts as CSV Source: https://orgo.space/docs/api-reference/contact/export-contacts-as-csv /api-reference/openapi.json get /api/v1/contacts-csv Exports contacts in CSV format. Requires HR_TENANT permission, or HR_LOCAL with a localCenter filter parameter. Creates an audit log entry recording the export action and request URI. Returns up to 500 records per page. # Get a contact Source: https://orgo.space/docs/api-reference/contact/get-a-contact /api-reference/openapi.json get /api/v1/contacts/{id} Retrieves a single contact by ID. Requires HR_LOCAL or FINANCIAL_LOCAL permission scoped to the contact local center. # Get contact newsletter statistics Source: https://orgo.space/docs/api-reference/contact/get-contact-newsletter-statistics /api-reference/openapi.json get /api/v1/contact/newsletter-stats Returns aggregated newsletter subscription statistics for the current tenant, including counts of subscribed, unsubscribed, not-selected, and total contacts. Requires HR_LOCAL or FINANCIAL_LOCAL permission. Pagination is disabled; returns a single JSON object. # Get contact status statistics Source: https://orgo.space/docs/api-reference/contact/get-contact-status-statistics /api-reference/openapi.json get /api/v1/contact/status-stats Returns aggregated contact status statistics for the current tenant, showing how many contacts are in each status. Requires HR_LOCAL or FINANCIAL_LOCAL permission. Pagination is disabled; returns a single JSON object. # List contacts Source: https://orgo.space/docs/api-reference/contact/list-contacts /api-reference/openapi.json get /api/v1/contacts Returns a paginated list of contacts for the current tenant. Requires HR_LOCAL or FINANCIAL_LOCAL permission. Contacts are non-member records used for CRM and outreach purposes. Response is intentionally lean — call `GET /contacts/{id}` for full contact details. # Unsubscribe contact from newsletter Source: https://orgo.space/docs/api-reference/contact/unsubscribe-contact-from-newsletter /api-reference/openapi.json get /api/v1/contact/{id}/unsubscribe-from-newsletter Sets the contact newsletter subscription flag to false. Creates an audit log entry recording the unsubscription. Requires HR_TENANT permission. # Update a contact Source: https://orgo.space/docs/api-reference/contact/update-a-contact /api-reference/openapi.json patch /api/v1/contacts/{id} Updates contact fields and persists any custom field values from the request. Requires HR_LOCAL or FINANCIAL_LOCAL permission scoped to the contact local center. # Clone a contract Source: https://orgo.space/docs/api-reference/contract/clone-a-contract /api-reference/openapi.json patch /api/v1/contracts/clone/{id} Creates a duplicate of an existing contract template with a new hash and "Copy " prefix on the name. The cloned contract is persisted immediately. Requires HR_TENANT permission. # Create a contract Source: https://orgo.space/docs/api-reference/contract/create-a-contract /api-reference/openapi.json post /api/v1/contracts Creates a new contract template. Sets the tenant from the authenticated user and validates signature settings (e.g., whether digital signatures are required). Requires ADMIN_TENANT permission. # Delete a contract Source: https://orgo.space/docs/api-reference/contract/delete-a-contract /api-reference/openapi.json delete /api/v1/contracts/{id} Permanently deletes a contract template. Blocked if any contract users have signed (locked) instances of this contract. Requires HR_TENANT permission. # Get a contract Source: https://orgo.space/docs/api-reference/contract/get-a-contract /api-reference/openapi.json get /api/v1/contracts/{id} Retrieves a single contract template by ID, including its content, signature settings, and associated unit. # List contracts Source: https://orgo.space/docs/api-reference/contract/list-contracts /api-reference/openapi.json get /api/v1/contracts Returns all contract templates for the current tenant, ordered by creation date descending. Paginated with up to 500 items per page. # List my contracts Source: https://orgo.space/docs/api-reference/contract/list-my-contracts /api-reference/openapi.json get /api/v1/my_contracts Returns contracts relevant to the authenticated user. Includes contracts marked as displayInProfile that belong to the user groups, plus contracts the user has already signed. Duplicates are removed. Useful for the user profile contract section. # Request contract re-signing Source: https://orgo.space/docs/api-reference/contract/request-contract-re-signing /api-reference/openapi.json patch /api/v1/contracts/{id}/ask-resign Regenerates the contract hash and cancels all existing unsigned contract-user instances by marking them with the current admin as canceledBy and setting the cancellation date. This forces all assigned users to re-sign the updated contract. Requires ADMIN_TENANT permission and tenant isolation is enforced. # Update a contract Source: https://orgo.space/docs/api-reference/contract/update-a-contract /api-reference/openapi.json patch /api/v1/contracts/{id} Updates contract template properties such as name, content, signature settings, or unit assignment. Requires HR_TENANT permission. # Apply default signature to contract Source: https://orgo.space/docs/api-reference/contractuser/apply-default-signature-to-contract /api-reference/openapi.json post /api/v1/contract_users/{id}/use-default-signature Applies the contract default (admin) signature to a contract-user instance. Validates that a default signature exists and that the admin has not already signed. Sets the admin signature, locks the contract, records the signature date, generates a signed PDF document uploaded to S3, generates a contract number if needed, and sends a signing completion notification email. Fails if the contract has no default signature or is already admin-signed. # Create a contract user Source: https://orgo.space/docs/api-reference/contractuser/create-a-contract-user /api-reference/openapi.json post /api/v1/contract_users Assigns a contract to a user or contact. Requires either a user or contact reference and a contract reference. Validates tenant isolation across all linked entities. Populates the placeholder map from the contract template and resolves custom field and placeholder values. HR_LOCAL or HR_TENANT permission is required when assigning to another user. # Create contract user as admin Source: https://orgo.space/docs/api-reference/contractuser/create-contract-user-as-admin /api-reference/openapi.json post /api/v1/contract_users/admin Admin endpoint for assigning a contract to a user or contact with extended write permissions. Uses the contract_user_admin_write serialization group which allows setting additional fields. Requires HR_TENANT permission. # Delete a contract user Source: https://orgo.space/docs/api-reference/contractuser/delete-a-contract-user /api-reference/openapi.json delete /api/v1/contract_users/{id} Permanently deletes a contract-user record. Only the assigned user or an HR_TENANT admin can perform this action. # Edit contract user as admin Source: https://orgo.space/docs/api-reference/contractuser/edit-contract-user-as-admin /api-reference/openapi.json patch /api/v1/contract_users/admin/{id} Admin endpoint for editing a contract-user record with extended write permissions. Uses the contract_user_admin_write serialization group. Requires HR_TENANT permission. # Get a contract user Source: https://orgo.space/docs/api-reference/contractuser/get-a-contract-user /api-reference/openapi.json get /api/v1/contract_users/{id} Retrieves a single contract-user record by ID. A contract user represents an individual instance of a contract assigned to a specific user or contact, including signature status, placeholder values, and validity dates. # List contract users Source: https://orgo.space/docs/api-reference/contractuser/list-contract-users /api-reference/openapi.json get /api/v1/contract_users Returns all contract-user records for the current tenant, ordered by ID descending. Paginated with 30 items per page. # Mark contract users as signed Source: https://orgo.space/docs/api-reference/contractuser/mark-contract-users-as-signed /api-reference/openapi.json post /api/v1/contract_users/mark_as_signed Manually marks a contract-user as fully signed without requiring actual signatures. Sets status to COMPLETE, locks the record, uses the validity start date as the signature date, and records the admin who performed the action. Validates that end date is after start date and enforces tenant isolation. Requires HR_TENANT permission. # Sign membership contract in advance Source: https://orgo.space/docs/api-reference/contractuser/sign-membership-contract-in-advance /api-reference/openapi.json post /api/v1/sign-membership-contract-in_advance Creates or retrieves an unsigned contract-user instance for the tenant membership contract. Looks up the membership contract ID from the tenant fee settings. If an unsigned instance already exists for the user, returns it instead of creating a duplicate. The actual signature and date calculation happens when the user uploads their signature via the media endpoint. # Update a contract user Source: https://orgo.space/docs/api-reference/contractuser/update-a-contract-user /api-reference/openapi.json patch /api/v1/contract_users/{id} Updates a contract-user record. Sanitizes the placeholder map and populates the associated user or contact entity with custom field and placeholder values. Only the assigned user or an HR_TENANT admin can perform this action. # Get a country Source: https://orgo.space/docs/api-reference/country/get-a-country /api-reference/openapi.json get /api/v1/countries/{id} Retrieves a single country by ID. Returns the country name, code, and other reference data. # List countries Source: https://orgo.space/docs/api-reference/country/list-countries /api-reference/openapi.json get /api/v1/countries Returns all countries ordered by name ascending. Paginated with up to 1000 items per page. This is static reference data shared across all tenants. # Get a county Source: https://orgo.space/docs/api-reference/county/get-a-county /api-reference/openapi.json get /api/v1/counties/{id} Retrieves a single county by ID. Returns the county name and associated country reference. # List counties Source: https://orgo.space/docs/api-reference/county/list-counties /api-reference/openapi.json get /api/v1/counties Returns all counties (administrative subdivisions of a country). This is static reference data typically used for address forms and geographic filtering. # Create a course Source: https://orgo.space/docs/api-reference/course/create-a-course /api-reference/openapi.json post /api/v1/courses Creates a new course and sets the current user as creator. Updates tenant onboarding settings if applicable. Requires HR_TENANT permission. # Delete a course Source: https://orgo.space/docs/api-reference/course/delete-a-course /api-reference/openapi.json delete /api/v1/courses/{uuid} Permanently deletes a course. Fails with 400 if the course has any existing enrollments. Requires HR_TENANT permission. # Get a course Source: https://orgo.space/docs/api-reference/course/get-a-course /api-reference/openapi.json get /api/v1/courses/{uuid} Returns full course details including sections, lessons, and enrollment info. HR_TENANT users can view all courses; other users can only access published courses available for their user type. Draft courses return 404 for non-admin users. # List courses Source: https://orgo.space/docs/api-reference/course/list-courses /api-reference/openapi.json get /api/v1/courses Returns a paginated list of courses. Supports search, ordering, and date filters. Tenant isolation is enforced automatically via Doctrine extensions. # Update a course Source: https://orgo.space/docs/api-reference/course/update-a-course /api-reference/openapi.json patch /api/v1/courses/{uuid} Updates course properties such as title, description, status, or user type restrictions. Also updates tenant onboarding settings if applicable. Requires HR_TENANT permission. # Delete a course enrollment Source: https://orgo.space/docs/api-reference/courseenrollment/delete-a-course-enrollment /api-reference/openapi.json delete /api/v1/course_enrollments/{uuid} Removes a course enrollment record. The enrolled user can unenroll themselves, or an HR_TENANT administrator can remove any enrollment. # Enroll in a course Source: https://orgo.space/docs/api-reference/courseenrollment/enroll-in-a-course /api-reference/openapi.json post /api/v1/course_enrollments Self-enrolls the current user in a course. Provide the course reference in the request body. # Enroll student with notification Source: https://orgo.space/docs/api-reference/courseenrollment/enroll-student-with-notification /api-reference/openapi.json post /api/v1/course_enrollments/add_with_notification Admin-enrolls a user in a course and optionally sends a notification email. Pass notify: true in the request body to trigger the enrollment email. Prevents duplicate enrollments. Requires HR_TENANT permission. # Export student enrollments as CSV Source: https://orgo.space/docs/api-reference/courseenrollment/export-student-enrollments-as-csv /api-reference/openapi.json get /api/v1/course-enrollments/export Downloads a CSV file with enrollment data including student name, email, enrolled date, last accessed, progress percentage, status, and completion date. Requires course query parameter and optionally accepts status filter. Requires HR_TENANT permission. # Get a course enrollment Source: https://orgo.space/docs/api-reference/courseenrollment/get-a-course-enrollment /api-reference/openapi.json get /api/v1/course_enrollments/{uuid} Returns enrollment details including progress percentage, status, last accessed date, and completion date. Accessible by the enrolled user or HR_TENANT administrators. # Get user enrollment for a course Source: https://orgo.space/docs/api-reference/courseenrollment/get-user-enrollment-for-a-course /api-reference/openapi.json get /api/v1/course-enrollment-user-course Returns the enrollment record for the current user in a specific course. Filter by course to check enrollment status. Returns a lightweight response with course enrollment details. # List course enrollments Source: https://orgo.space/docs/api-reference/courseenrollment/list-course-enrollments /api-reference/openapi.json get /api/v1/course-enrollments Returns a paginated list of all course enrollments for the current tenant, ordered by enrollment date descending. Used by administrators for managing student lists. # List my course enrollments Source: https://orgo.space/docs/api-reference/courseenrollment/list-my-course-enrollments /api-reference/openapi.json get /api/v1/my-courses-enrollments Returns a lightweight list of the current user's course enrollments with minimal course data. Used for the "My Courses" dashboard section. # List user course enrollments Source: https://orgo.space/docs/api-reference/courseenrollment/list-user-course-enrollments /api-reference/openapi.json get /api/v1/course-enrollment-user Returns all course enrollments for the current user, including course details and progress data. Used for the user profile courses tab. # Update a course enrollment Source: https://orgo.space/docs/api-reference/courseenrollment/update-a-course-enrollment /api-reference/openapi.json patch /api/v1/course_enrollments/{uuid} Updates enrollment fields such as progress, last accessed date, or status. Accessible by the enrolled user (to track their own progress) or HR_TENANT administrators. # Create a course lesson Source: https://orgo.space/docs/api-reference/courselesson/create-a-course-lesson /api-reference/openapi.json post /api/v1/course_lessons Creates a new lesson within a course section. Set the section reference, title, content, and optionally attach media. Requires HR_TENANT permission. # Delete a course lesson Source: https://orgo.space/docs/api-reference/courselesson/delete-a-course-lesson /api-reference/openapi.json delete /api/v1/course_lessons/{uuid} Permanently removes a lesson and its associated media from the course. Requires HR_TENANT permission. # Get a course lesson Source: https://orgo.space/docs/api-reference/courselesson/get-a-course-lesson /api-reference/openapi.json get /api/v1/course_lessons/{uuid} Returns full lesson details including content, media references, and position within its section. Includes detail-level fields not present in the collection endpoint. # List course lessons Source: https://orgo.space/docs/api-reference/courselesson/list-course-lessons /api-reference/openapi.json get /api/v1/course_lessons Returns a paginated list of course lessons. Supports search and ordering filters. Filter by section to get lessons within a specific course section. # Remove media from lesson Source: https://orgo.space/docs/api-reference/courselesson/remove-media-from-lesson /api-reference/openapi.json patch /api/v1/course_lessons/{uuid}/media Removes the attached media file (video, document, etc.) from a lesson. Deletes the Media entity and clears all media-related fields on the lesson. Requires HR_TENANT permission or lesson ownership. # Update a course lesson Source: https://orgo.space/docs/api-reference/courselesson/update-a-course-lesson /api-reference/openapi.json patch /api/v1/course_lessons/{uuid} Updates lesson properties such as title, content, position, or media attachment. Requires HR_TENANT permission. # Delete a lesson attachment Source: https://orgo.space/docs/api-reference/courselessonattachment/delete-a-lesson-attachment /api-reference/openapi.json delete /api/v1/course_lesson_attachments/{uuid} Removes the attachment and its underlying Media row when no other entity references it. Requires HR_TENANT or course-creator ownership. # Get a single lesson attachment Source: https://orgo.space/docs/api-reference/courselessonattachment/get-a-single-lesson-attachment /api-reference/openapi.json get /api/v1/course_lesson_attachments/{uuid} Returns one attachment by UUID. Read access checked via voter. # List lesson attachments Source: https://orgo.space/docs/api-reference/courselessonattachment/list-lesson-attachments /api-reference/openapi.json get /api/v1/course_lesson_attachments Returns attachments for a given lesson. Use the `lesson.uuid` filter (`?lesson.uuid=...`) to scope by lesson. Tenant isolation is enforced by Doctrine extension. # Create a course quiz Source: https://orgo.space/docs/api-reference/coursequiz/create-a-course-quiz /api-reference/openapi.json post /api/v1/course_quizes Creates a new quiz within a course section. Configure the title, passing score, time limit, and maximum attempts. Questions and answers are managed separately. Requires HR_TENANT permission. # Delete a course quiz Source: https://orgo.space/docs/api-reference/coursequiz/delete-a-course-quiz /api-reference/openapi.json delete /api/v1/course_quizes/{uuid} Permanently deletes a quiz along with its questions, answers, and all attempt records. Requires HR_TENANT permission. # Export quiz results as CSV Source: https://orgo.space/docs/api-reference/coursequiz/export-quiz-results-as-csv /api-reference/openapi.json get /api/v1/course-quiz-results/export Downloads a CSV file with all quiz attempts including student name, email, attempt number, score, pass/fail, time spent, and per-question answers with correctness. Requires the quiz query parameter. Requires HR_TENANT permission. # Get a course quiz Source: https://orgo.space/docs/api-reference/coursequiz/get-a-course-quiz /api-reference/openapi.json get /api/v1/course_quizes/{uuid} Returns full quiz details including questions, answers, passing score, and attempt limits. Includes detail-level fields for rendering the quiz interface. # List course quizzes Source: https://orgo.space/docs/api-reference/coursequiz/list-course-quizzes /api-reference/openapi.json get /api/v1/course_quizes Returns a paginated list of course quizzes. Filter by section to get quizzes within a specific course section. # Update a course quiz Source: https://orgo.space/docs/api-reference/coursequiz/update-a-course-quiz /api-reference/openapi.json patch /api/v1/course_quizes/{uuid} Updates quiz properties such as title, passing score, time limit, or maximum attempts. Requires HR_TENANT permission. # Create a course section Source: https://orgo.space/docs/api-reference/coursesection/create-a-course-section /api-reference/openapi.json post /api/v1/course_sections Creates a new section within a course. Set the course reference, title, and position. Lessons and quizzes are added separately. Requires HR_TENANT permission. # Delete a course section Source: https://orgo.space/docs/api-reference/coursesection/delete-a-course-section /api-reference/openapi.json delete /api/v1/course_sections/{uuid} Permanently deletes a section and all its contained lessons and quizzes. Requires HR_TENANT permission. # Get a course section Source: https://orgo.space/docs/api-reference/coursesection/get-a-course-section /api-reference/openapi.json get /api/v1/course_sections/{uuid} Returns full section details including its lessons and quizzes. Includes detail-level fields for rendering the section content tree. # List course sections Source: https://orgo.space/docs/api-reference/coursesection/list-course-sections /api-reference/openapi.json get /api/v1/course_sections Returns a paginated list of course sections. Supports search and ordering filters. Filter by course to get sections within a specific course. # Update a course section Source: https://orgo.space/docs/api-reference/coursesection/update-a-course-section /api-reference/openapi.json patch /api/v1/course_sections/{uuid} Updates section properties such as title, description, or position. Requires HR_TENANT permission. # Create a custom field Source: https://orgo.space/docs/api-reference/customfield/create-a-custom-field /api-reference/openapi.json post /api/v1/custom_fields Creates a new custom field definition for the tenant. Requires ADMIN_TENANT permission, or EVENT_TENANT permission if the discriminator is "event". # Delete a custom field Source: https://orgo.space/docs/api-reference/customfield/delete-a-custom-field /api-reference/openapi.json delete /api/v1/custom_fields/{id} Deletes a custom field and cleans up all references in tenant setting forms (profile, registration, adhesion) and user-type registration form configurations. Requires ADMIN_TENANT for non-event fields or EVENT_TENANT for event-discriminated fields. # Get a custom field Source: https://orgo.space/docs/api-reference/customfield/get-a-custom-field /api-reference/openapi.json get /api/v1/custom_fields/{id} Returns a single custom field definition including its type, options, and configuration. # List custom fields Source: https://orgo.space/docs/api-reference/customfield/list-custom-fields /api-reference/openapi.json get /api/v1/custom_fields Returns all custom fields for the current tenant, ordered by position. Uses a cached provider for common queries (all fields, or filtered by discriminator). Supports discriminator filter (profile, form, event). # Update a custom field Source: https://orgo.space/docs/api-reference/customfield/update-a-custom-field /api-reference/openapi.json patch /api/v1/custom_fields/{id} Updates a custom field definition. Requires ADMIN_TENANT permission and tenant ownership. Validates tenant isolation. # Create a custom field value Source: https://orgo.space/docs/api-reference/customfieldvalue/create-a-custom-field-value /api-reference/openapi.json post /api/v1/custom_field_values Creates a single custom field value attached to one of a user, a contact, or an event attendance (exactly one of `user`, `contact`, `eventAttend` must be set; the others must be omitted or null). The `field` IRI is required. For file-type custom fields, send a `media` IRI and the `value` will be ignored; for other field types, send `value` as a string (callers should JSON-encode multi-option answers themselves before sending). All foreign-key fields take an IRI-reference string in the form `/api/v1/{resource}/{id}` rather than plain numeric ids. Concrete examples are listed in the "Request body" section below. Permission gates per owner type mirror the existing PATCH endpoints on the owning entities: * `user`: caller is the user, has `HR_LOCAL` on the user, or is a parent of the user. * `contact`: caller has `HR_LOCAL` or `FINANCIAL_LOCAL` on the contact. * `eventAttend`: caller is the attendee, has `EVENT_LOCAL` on the event's unit, or has `HR_TENANT`. For contact-attached values the field's tenant must match the contact's tenant and the field's discriminator must be `profile`; for event-attended values the field's tenant must match the event's tenant and the discriminator must be `event`. The user-attached path inherits the existing nested-write behavior, which does not enforce either of those checks today. # Get a custom field value Source: https://orgo.space/docs/api-reference/customfieldvalue/get-a-custom-field-value /api-reference/openapi.json get /api/v1/custom_field_values/{id} Returns a single custom field value with its associated field definition, stored answer, and any linked media. Tenant-isolated through `field.tenant`; cross-tenant reads return 404. # List custom field values Source: https://orgo.space/docs/api-reference/customfieldvalue/list-custom-field-values /api-reference/openapi.json get /api/v1/custom_field_values Returns custom field values whose `field.tenant` matches the authenticated user's tenant. Use the `field`, `user`, or `value` filters (all exact-match) to narrow the result set. The default response is paginated by API Platform's standard mechanism. # Create a dashboard category Source: https://orgo.space/docs/api-reference/dashboardcategory/create-a-dashboard-category /api-reference/openapi.json post /api/v1/dashboard_categories Creates a new dashboard category for organizing widgets. Requires ADMIN_TENANT permission. # Delete a dashboard category Source: https://orgo.space/docs/api-reference/dashboardcategory/delete-a-dashboard-category /api-reference/openapi.json delete /api/v1/dashboard_categories/{id} Permanently removes a dashboard category. Requires ADMIN_TENANT permission and tenant ownership. # Get a dashboard category Source: https://orgo.space/docs/api-reference/dashboardcategory/get-a-dashboard-category /api-reference/openapi.json get /api/v1/dashboard_categories/{id} Returns a single dashboard category by ID. Requires ROLE_USER authentication. # List dashboard categories Source: https://orgo.space/docs/api-reference/dashboardcategory/list-dashboard-categories /api-reference/openapi.json get /api/v1/dashboard_categories Returns all dashboard categories for the current tenant. Pagination is disabled; all categories are returned in a single response. # Update a dashboard category Source: https://orgo.space/docs/api-reference/dashboardcategory/update-a-dashboard-category /api-reference/openapi.json patch /api/v1/dashboard_categories/{id} Updates a dashboard category name or configuration. Requires ADMIN_TENANT permission and tenant ownership. # Create a welcome message Source: https://orgo.space/docs/api-reference/dashboardwelcomemessage/create-a-welcome-message /api-reference/openapi.json post /api/v1/dashboard_welcome_messages Creates a new welcome message for the tenant dashboard. Can be set as default or targeted to a specific user type. Requires ADMIN_TENANT permission. # Delete a welcome message Source: https://orgo.space/docs/api-reference/dashboardwelcomemessage/delete-a-welcome-message /api-reference/openapi.json delete /api/v1/dashboard_welcome_messages/{id} Permanently removes a welcome message. The default welcome message cannot be deleted unless the caller has SUPER_ADMIN permission. Requires ADMIN_TENANT or SUPER_ADMIN permission. # Get a welcome message Source: https://orgo.space/docs/api-reference/dashboardwelcomemessage/get-a-welcome-message /api-reference/openapi.json get /api/v1/dashboard_welcome_messages/{id} Returns a single welcome message by ID. # Get welcome message for current user Source: https://orgo.space/docs/api-reference/dashboardwelcomemessage/get-welcome-message-for-current-user /api-reference/openapi.json get /api/v1/dashboard_welcome_messages/current_user Returns the welcome message(s) applicable to the authenticated user. If the tenant has user types enabled, returns the user-type-specific message. If the tenant setting showGeneralAndUserTypeMessage is enabled, returns both the default and user-type messages. Falls back to the default message if no user-type match is found. # List welcome messages Source: https://orgo.space/docs/api-reference/dashboardwelcomemessage/list-welcome-messages /api-reference/openapi.json get /api/v1/dashboard_welcome_messages Returns all welcome messages configured for the current tenant, up to 100 per page. # Update a welcome message Source: https://orgo.space/docs/api-reference/dashboardwelcomemessage/update-a-welcome-message /api-reference/openapi.json patch /api/v1/dashboard_welcome_messages/{id} Updates a welcome message title, body, or targeting settings. Requires ADMIN_TENANT or SUPER_ADMIN permission. # Create a dashboard widget Source: https://orgo.space/docs/api-reference/dashboardwidget/create-a-dashboard-widget /api-reference/openapi.json post /api/v1/dashboard_widgets Creates a new dashboard widget with the given type and configuration. Requires ADMIN_TENANT permission. # Delete a dashboard widget Source: https://orgo.space/docs/api-reference/dashboardwidget/delete-a-dashboard-widget /api-reference/openapi.json delete /api/v1/dashboard_widgets/{id} Permanently removes a dashboard widget and deletes any associated photos from S3. System widgets cannot be deleted. Requires ADMIN_TENANT permission and tenant ownership. # Get a dashboard widget Source: https://orgo.space/docs/api-reference/dashboardwidget/get-a-dashboard-widget /api-reference/openapi.json get /api/v1/dashboard_widgets/{id} Returns a single dashboard widget by ID with its configuration. Requires ROLE_USER authentication. # List dashboard widgets Source: https://orgo.space/docs/api-reference/dashboardwidget/list-dashboard-widgets /api-reference/openapi.json get /api/v1/dashboard_widgets Returns all dashboard widgets for the current tenant. Pagination is disabled; all widgets are returned in a single response. # Update a dashboard widget Source: https://orgo.space/docs/api-reference/dashboardwidget/update-a-dashboard-widget /api-reference/openapi.json patch /api/v1/dashboard_widgets/{id} Updates a dashboard widget configuration. If the defaultConfiguration contains photos, any removed photos are cleaned up from S3. Requires ADMIN_TENANT permission and tenant ownership. # Create a discussion Source: https://orgo.space/docs/api-reference/discussion/create-a-discussion /api-reference/openapi.json post /api/v1/discussions Creates a new discussion with a main post. Sets the current user as owner, creates an initial view record, sends mention notifications to any users mentioned in the main post body, and auto-assigns issues to the default assignee when applicable. Also updates tenant onboarding progress. # Delete a discussion Source: https://orgo.space/docs/api-reference/discussion/delete-a-discussion /api-reference/openapi.json delete /api/v1/discussions/{id} Deletes a discussion. Only the discussion owner or a tenant admin can perform this action. When deleted by someone other than the main post author, a moderation log entry is created with the discussion title and content for audit purposes. # Get a discussion Source: https://orgo.space/docs/api-reference/discussion/get-a-discussion /api-reference/openapi.json get /api/v1/discussions/{id} Retrieves a single discussion by ID, including its main post, namespace, tags, and metadata such as views count and posts count. # List discussions Source: https://orgo.space/docs/api-reference/discussion/list-discussions /api-reference/openapi.json get /api/v1/discussions Returns a paginated list of discussions within the current tenant. Results are filtered by tenant automatically via Doctrine extensions. Supports standard API Platform filters. # List reported issues Source: https://orgo.space/docs/api-reference/discussion/list-reported-issues /api-reference/openapi.json get /api/v1/issues Returns a paginated list of discussions flagged as issues. These are discussions with issue tracking enabled, including assigned users, issue types, and status tracking. Returns 30 items per page. # Update a discussion Source: https://orgo.space/docs/api-reference/discussion/update-a-discussion /api-reference/openapi.json patch /api/v1/discussions/{id} Updates an existing discussion and its main post. Sanitizes HTML content, processes media attachments, and sends notifications to any newly mentioned users that were not already mentioned before the edit. # Create a discussion namespace Source: https://orgo.space/docs/api-reference/discussionnamespace/create-a-discussion-namespace /api-reference/openapi.json post /api/v1/discussion_namespaces Creates a new discussion namespace. Requires unit-level permission for the target unit. Namespaces serve as containers for organizing discussions within a unit or the tenant. # Delete a discussion namespace Source: https://orgo.space/docs/api-reference/discussionnamespace/delete-a-discussion-namespace /api-reference/openapi.json delete /api/v1/discussion_namespaces/{id} Deletes a discussion namespace. Requires unit-level permission for the namespace. Removing a namespace will cascade to all discussions within it. # Get a discussion namespace Source: https://orgo.space/docs/api-reference/discussionnamespace/get-a-discussion-namespace /api-reference/openapi.json get /api/v1/discussion_namespaces/{id} Retrieves a single discussion namespace by ID, including its configuration, associated unit, and topic types. # Get latest discussion in namespace Source: https://orgo.space/docs/api-reference/discussionnamespace/get-latest-discussion-in-namespace /api-reference/openapi.json get /api/v1/discussion_namespaces/{id}/latest_discussion Retrieves the most recently created discussion within a given namespace, filtered by tenant. Returns the full discussion object with discussion_read serialization groups. Returns null if no discussions exist in the namespace. # List discussion namespaces Source: https://orgo.space/docs/api-reference/discussionnamespace/list-discussion-namespaces /api-reference/openapi.json get /api/v1/discussion_namespaces Returns all discussion namespaces for the current tenant, paginated at 100 items per page. Namespaces organize discussions into categories and can be scoped to specific units. # Update a discussion namespace Source: https://orgo.space/docs/api-reference/discussionnamespace/update-a-discussion-namespace /api-reference/openapi.json patch /api/v1/discussion_namespaces/{id} Updates an existing discussion namespace. Validates that the current user has permission to manage the namespace within its associated unit before applying changes. # Delete a drive file Source: https://orgo.space/docs/api-reference/drive/delete-a-drive-file /api-reference/openapi.json delete /api/v1/drives/{id} Permanently deletes a drive entry and its associated media file. Requires DELETE permission on the object, which is granted to the file owner and unit admins. # Get a drive file Source: https://orgo.space/docs/api-reference/drive/get-a-drive-file /api-reference/openapi.json get /api/v1/drives/{id} Retrieves a single drive entry (file or folder) by ID, including its media reference, owner, parent folder, and unit association. # List drive files Source: https://orgo.space/docs/api-reference/drive/list-drive-files /api-reference/openapi.json get /api/v1/drives Returns a paginated list of drive files and folders for the current tenant, 100 items per page. Results are filtered by tenant and user access permissions via Doctrine extensions. Use query parameters to filter by parent folder, unit, or personal drive. # List latest drive files Source: https://orgo.space/docs/api-reference/drive/list-latest-drive-files /api-reference/openapi.json get /api/v1/drive/latest Returns the 10 most recently uploaded or modified drive files accessible to the current user. Useful for displaying a recent files widget on the dashboard. # Publish a public share link for a drive file Source: https://orgo.space/docs/api-reference/drive/publish-a-public-share-link-for-a-drive-file /api-reference/openapi.json patch /api/v1/drives/{id}/share Generates a unique short slug, creates a 1-year pre-signed S3 URL for the underlying media, and publishes an HTML redirect page to the go.orgo.space bucket. Returns the drive with slugGo and publicShareExpiresAt populated. Only the file owner can share, and only files with attached media are shareable. # Revoke a public share link for a drive file Source: https://orgo.space/docs/api-reference/drive/revoke-a-public-share-link-for-a-drive-file /api-reference/openapi.json patch /api/v1/drives/{id}/revoke-share Removes the published HTML redirect from go.orgo.space and clears the slug and pre-signed URL on the drive. Only the file owner can revoke. # Search drive files Source: https://orgo.space/docs/api-reference/drive/search-drive-files /api-reference/openapi.json get /api/v1/drive/search Full-text search across drive file and folder names accessible to the current user. Requires a search query parameter with at least 2 characters. Returns up to 10 matching results scoped to the user accessible units. Pagination is disabled. # Update a drive file Source: https://orgo.space/docs/api-reference/drive/update-a-drive-file /api-reference/openapi.json patch /api/v1/drives/{id} Updates a drive entry name, parent folder, or other properties. Requires EDIT permission on the object, which is granted to the file owner and unit admins. # Upload a file to drive Source: https://orgo.space/docs/api-reference/drive/upload-a-file-to-drive /api-reference/openapi.json post /api/v1/drives Creates a new drive entry (file or folder). When uploading a file, provide fileName, mediaType, and fileSize in the request body to create the associated Media record. Supports uploading to personal drives with access validation and cross-tenant protection. Sets the current user as owner. # Get an education industry Source: https://orgo.space/docs/api-reference/educationindustry/get-an-education-industry /api-reference/openapi.json get /api/v1/education_industries/{id} Retrieves a single education industry (field of study) by ID. # List education industries Source: https://orgo.space/docs/api-reference/educationindustry/list-education-industries /api-reference/openapi.json get /api/v1/education_industries Returns all education industries (fields of study). Read-only reference data used in user education profiles. Page size defaults to 1000. # Create an email template Source: https://orgo.space/docs/api-reference/emailtemplate/create-an-email-template /api-reference/openapi.json post /api/v1/email_templates Creates a custom email template for the current tenant, overriding the default system template for the specified type. Requires ADMIN_TENANT permission. The template HTML supports placeholders like {{firstName}}, {{organizationName}}, etc. # Delete an email template Source: https://orgo.space/docs/api-reference/emailtemplate/delete-an-email-template /api-reference/openapi.json delete /api/v1/email_templates/{id} Deletes a custom email template. Requires ADMIN_TENANT permission. After deletion, the system will fall back to the built-in default Twig template for that email type. # Get an email template Source: https://orgo.space/docs/api-reference/emailtemplate/get-an-email-template /api-reference/openapi.json get /api/v1/email_templates/{id} Retrieves a single custom email template by ID, including its HTML content, subject line, and type. Requires ADMIN_TENANT permission. # Get default email template by type Source: https://orgo.space/docs/api-reference/emailtemplate/get-default-email-template-by-type /api-reference/openapi.json get /api/v1/email_templates/default-template/{templateType} Returns the built-in default Twig template for a given email type, rendered with placeholder context and the tenant language. Includes the default subject line and available placeholders. Requires ADMIN_TENANT permission. Useful for resetting a template back to system defaults. # Get email template content by type Source: https://orgo.space/docs/api-reference/emailtemplate/get-email-template-content-by-type /api-reference/openapi.json get /api/v1/email_templates/content/{templateType} Returns the active email template content for a given type. If a custom tenant template exists, returns it with source "custom". Otherwise, renders and returns the default Twig template with source "default". Always includes the available placeholders for the template type. Requires ADMIN_TENANT permission. # List email templates Source: https://orgo.space/docs/api-reference/emailtemplate/list-email-templates /api-reference/openapi.json get /api/v1/email_templates Returns a paginated list of custom email templates for the current tenant. Requires ADMIN_TENANT permission. Returns 20 items per page. # Preview an email template Source: https://orgo.space/docs/api-reference/emailtemplate/preview-an-email-template /api-reference/openapi.json post /api/v1/show-preview Renders a preview of an email template by replacing all placeholders with real data from the current user context. Send html and subject in the request body. Returns processed HTML and subject with placeholders resolved to actual values. # Send a test email Source: https://orgo.space/docs/api-reference/emailtemplate/send-a-test-email /api-reference/openapi.json post /api/v1/email_templates/send-test Sends a test email to the current user email address using the provided HTML, subject, and templateType. Placeholders are replaced with the current user data, and the subject is prefixed with [TEST]. Uses the tenant configured from/reply-to addresses. Requires ADMIN_TENANT permission. # Update an email template Source: https://orgo.space/docs/api-reference/emailtemplate/update-an-email-template /api-reference/openapi.json patch /api/v1/email_templates/{id} Updates an existing custom email template subject, HTML content, or type. Requires ADMIN_TENANT permission. # Copy template logo to event Source: https://orgo.space/docs/api-reference/event/copy-template-logo-to-event /api-reference/openapi.json post /api/v1/events/{uuid}/copy-template-logo Copies the hero image from an event template to this event. Downloads the file from S3 and creates a new Media entity, then copies it to the public folder if the event is public or has ticketing. # Create a sub-event Source: https://orgo.space/docs/api-reference/event/create-a-sub-event /api-reference/openapi.json post /api/v1/sub_events Creates a new sub-event within a parent event. Requires parentEvent IRI in the body. Automatically sets tenant, owner, status, and position from parent. Requires event ownership or EVENT_LOCAL permission. # Create an event Source: https://orgo.space/docs/api-reference/event/create-an-event /api-reference/openapi.json post /api/v1/events Creates a new event in draft status. Automatically sets the current user as owner and assigns tenant. If ticketing is enabled, a linked Stripe product is created. Supports propagation to all local centers via the propagateToLocalCenters flag. Non-financial users cannot enable ticketing or public visibility. # Delete a sub-event Source: https://orgo.space/docs/api-reference/event/delete-a-sub-event /api-reference/openapi.json delete /api/v1/sub_events/{uuid} Permanently deletes a sub-event. Permission is checked against the parent event. # Delete an event Source: https://orgo.space/docs/api-reference/event/delete-an-event /api-reference/openapi.json delete /api/v1/events/{uuid} Permanently deletes an event. Fails with 400 if any attendee has a payment attached. Events restricted to a specific user type require EVENT_TENANT permission; otherwise the owner or EVENT_LOCAL role suffices. # Duplicate an event Source: https://orgo.space/docs/api-reference/event/duplicate-an-event /api-reference/openapi.json post /api/v1/events/{uuid}/duplicate Creates a copy of the event with all settings, tickets, vouchers, custom fields, speakers, and agenda. Excludes attendees. The duplicated event is created as a draft. Accepts optional unit IRI to place the copy in a different group. # Export event attendees Source: https://orgo.space/docs/api-reference/event/export-event-attendees /api-reference/openapi.json get /api/v1/events/{uuid}/attendees-export Downloads a CSV file containing all attendees with their name, email, phone, organisation, ticket type, price, registration/RSVP status, partner details, discount codes, and custom field values. Requires event ownership, EVENT_TENANT, or EVENT_LOCAL permission. # Get an event Source: https://orgo.space/docs/api-reference/event/get-an-event /api-reference/openapi.json get /api/v1/events/{uuid} Returns full event details including settings, product/ticketing configuration, and media. Accessible to all authenticated tenant members. # Get analytics for an event Source: https://orgo.space/docs/api-reference/event/get-analytics-for-an-event /api-reference/openapi.json get /api/v1/events/{uuid}/analytics Returns aggregated metrics for the event: attendee counts by registration status, RSVP breakdown, capacity utilization, total/refunded revenue (in cents), per-ticket-tier revenue breakdown, and daily registration counts. Accepts optional from/to query params (ISO 8601) to restrict to a date range. Requires event ownership, EVENT_TENANT, or EVENT_LOCAL permission. # Get events report Source: https://orgo.space/docs/api-reference/event/get-events-report /api-reference/openapi.json get /api/v1/events-report Returns up to 200 events per page for reporting purposes. Uses the same filters as the standard event collection but with a higher page size suitable for dashboards and analytics. # Get public event (anonymous) Source: https://orgo.space/docs/api-reference/event/get-public-event-anonymous /api-reference/openapi.json get /api/v1/get_public_event_anonymous/{uuid} Returns event details for the public registration page, including ticket prices, add-ons, and registration form configuration with resolved custom fields. Response is cached in Redis. Only accessible for events that are public or have ticketing enabled. No authentication required. # List events Source: https://orgo.space/docs/api-reference/event/list-events /api-reference/openapi.json get /api/v1/events Returns a paginated list of events for the current tenant, ordered by start date descending. Filterable by standard API Platform filters. Tenant isolation is enforced automatically via Doctrine extensions. Response is intentionally lean for list use — call `GET /events/{id}` for full event details. # List events for newsletter Source: https://orgo.space/docs/api-reference/event/list-events-for-newsletter /api-reference/openapi.json get /api/v1/get_events_for_newsletter Returns all events in the current tenant that have the newsletterEnabled flag set to true. Used for composing newsletter content. Requires EVENT_TENANT permission. # List membership-restricted tickets for the current user Source: https://orgo.space/docs/api-reference/event/list-membership-restricted-tickets-for-the-current-user /api-reference/openapi.json get /api/v1/events/{uuid}/member_tickets Returns event tickets reserved for specific membership levels that match the current users feeTenantProductPrice. Returns an empty array if the user has no active membership level. Cached per (event, level) tuple in tenantCache with versioned invalidation. # List public events Source: https://orgo.space/docs/api-reference/event/list-public-events /api-reference/openapi.json get /api/v1/public_events Returns published public events for a given tenant. Requires the tenant query parameter (slug). Supports date filtering via dateTimeBegin[after]/dateTimeBegin[before], or past/upcoming flags. Supports custom ordering via order[] parameters. No authentication required. # Publish an event Source: https://orgo.space/docs/api-reference/event/publish-an-event /api-reference/openapi.json patch /api/v1/events_publish/{uuid} Sets the event status to published. For future events, creates a notification and dispatches an async message to notify unit members. Fails if the event is already published. Requires event ownership, EVENT_TENANT, or EVENT_LOCAL permission. # Publish event via Go page Source: https://orgo.space/docs/api-reference/event/publish-event-via-go-page /api-reference/openapi.json patch /api/v1/event-go-publish/{uuid} Generates or updates the static Go landing page for the event. Creates a slug if one does not exist, then uploads the rendered HTML to the Go hosting service. Requires event ownership, EVENT_TENANT, or EVENT_LOCAL permission. # Save event as template Source: https://orgo.space/docs/api-reference/event/save-event-as-template /api-reference/openapi.json post /api/v1/events/{uuid}/save-as-template Creates an event template from the current event configuration, including ticket types, voucher definitions, custom field definitions, and settings. Requires ADMIN_TENANT permission. # Send event invitations Source: https://orgo.space/docs/api-reference/event/send-event-invitations /api-reference/openapi.json post /api/v1/events/{uuid}/send-invites Dispatches an async message to send email invitations to all eligible members. The event must be published unless sending propagated invites. Marks the event invitesSent status as "sending". Pass propagated: true to send invites for all propagated copies. # Update a sub-event Source: https://orgo.space/docs/api-reference/event/update-a-sub-event /api-reference/openapi.json patch /api/v1/sub_events/{uuid} Updates sub-event details. Permission is checked against the parent event owner or EVENT_LOCAL. # Update an event Source: https://orgo.space/docs/api-reference/event/update-an-event /api-reference/openapi.json patch /api/v1/events/{uuid} Updates event details. If ticketing is newly enabled, creates a Stripe product. Copies the event logo to the public S3 folder when the event is public or has ticketing. Requires event ownership or EVENT_LOCAL permission. # Cancel event attendance Source: https://orgo.space/docs/api-reference/eventattend/cancel-event-attendance /api-reference/openapi.json delete /api/v1/event_attends/{id} Removes an event attendance record. Cannot delete attendances with a paid ticket (productPrice must be null). The attendee themselves, event owner, EVENT_TENANT, or EVENT_LOCAL can perform this action. # Confirm invited attendee Source: https://orgo.space/docs/api-reference/eventattend/confirm-invited-attendee /api-reference/openapi.json post /api/v1/event_attends/{id}/confirm Confirms an invited attendee, upgrading their status to success and sending them a ticket with QR code via email. Used for VIP/speaker/comp access. # Download event ticket Source: https://orgo.space/docs/api-reference/eventattend/download-event-ticket /api-reference/openapi.json get /api/v1/event_ticket/{id} Generates and returns a PDF ticket for the attendance record, including a QR code for check-in. Only the attendee or users with HR_LOCAL permission can download the ticket. # Generate guest tickets Source: https://orgo.space/docs/api-reference/eventattend/generate-guest-tickets /api-reference/openapi.json post /api/v1/event_attends/{id}/guest-tickets Creates guest tickets linked to an existing attendee. Max 20 per request. PDFs are generated async and sent via email. # Get an event attendance Source: https://orgo.space/docs/api-reference/eventattend/get-an-event-attendance /api-reference/openapi.json get /api/v1/event_attends/{id} Returns detailed attendance information including registration status, RSVP status, ticket type, payment details, and custom field values. # Invite external user to event Source: https://orgo.space/docs/api-reference/eventattend/invite-external-user-to-event /api-reference/openapi.json post /api/v1/event_attend_invite_external Invites a person by email to an event. Looks up the email against existing Users, then Contacts; if no match is found, creates a new Contact record. Sends an invite email with registration link. Requires event ownership, EVENT_TENANT, or EVENT_LOCAL permission. Pass entity.email and entity.event (UUID) in the request body. # List event attendances Source: https://orgo.space/docs/api-reference/eventattend/list-event-attendances /api-reference/openapi.json get /api/v1/event_attends Returns a paginated list of event attendance records, ordered by ID descending (newest first). Supports client-configurable page size up to 100 items. # List up to 6 unique attendees for an event Source: https://orgo.space/docs/api-reference/eventattend/list-up-to-6-unique-attendees-for-an-event /api-reference/openapi.json get /api/v1/event_attend_sidebar Returns at most 6 distinct attendees (deduped by user/contact across multi-ticket buyers) for the avatar preview widget. Pagination is disabled — itemsPerPage and page query params are ignored. Hard server-side cap of 6 results regardless of client input. # List user event attendances Source: https://orgo.space/docs/api-reference/eventattend/list-user-event-attendances /api-reference/openapi.json get /api/v1/user_event_attends Returns event attendances for the current user with event details, ordered by event start date descending. Supports up to 100 items per page. Includes event-level data in the response for calendar and history views. # Register for an event Source: https://orgo.space/docs/api-reference/eventattend/register-for-an-event /api-reference/openapi.json post /api/v1/event_attends Creates a new event attendance. If the target user differs from the logged-in user, sets the attendance as an invitation and sends an invite email (for events with registration forms). Validates group membership for unit-scoped events, checks max capacity for non-ticketed events, and prevents duplicate registrations. Generates a unique hash for QR code check-in. # Update event attendance Source: https://orgo.space/docs/api-reference/eventattend/update-event-attendance /api-reference/openapi.json patch /api/v1/event_attends/{id} Updates attendance fields such as RSVP or registration status. When setting statusRegistration to "success", validates that payment is completed (for ticketed events) and all required registration form fields are filled. Admins with EVENT_TENANT or EVENT_LOCAL bypass these validation checks. # Delete event media Source: https://orgo.space/docs/api-reference/eventmedia/delete-event-media /api-reference/openapi.json delete /api/v1/event_media/{id} Permanently removes a media item from an event. Requires event ownership, EVENT_TENANT, or EVENT_LOCAL permission on the event unit. # Get event media Source: https://orgo.space/docs/api-reference/eventmedia/get-event-media /api-reference/openapi.json get /api/v1/event_media/{id} Returns a single event media item by ID, including its file URL and metadata. # List event media Source: https://orgo.space/docs/api-reference/eventmedia/list-event-media /api-reference/openapi.json get /api/v1/event_media Returns all media items (images, documents) attached to events for the current tenant, up to 100 per page. # Update event media Source: https://orgo.space/docs/api-reference/eventmedia/update-event-media /api-reference/openapi.json patch /api/v1/event_media/{id} Updates event media metadata such as caption, sort order, or associated file reference. # Upload event media Source: https://orgo.space/docs/api-reference/eventmedia/upload-event-media /api-reference/openapi.json post /api/v1/event_media Attaches a new media item (image or document) to an event. The media file should be associated with the event via the event relationship field. # Add an event speaker Source: https://orgo.space/docs/api-reference/eventspeaker/add-an-event-speaker /api-reference/openapi.json post /api/v1/event_speakers Adds a speaker to an event. Provide either a user or contact reference, not both. Validates that the speaker is not already added to the event. Only the event owner or users with EVENT_LOCAL permission can add speakers. Tenant is automatically set from the event. # Get an event speaker Source: https://orgo.space/docs/api-reference/eventspeaker/get-an-event-speaker /api-reference/openapi.json get /api/v1/event_speakers/{id} Returns a single event speaker record with their details and associated event reference. # List event speakers Source: https://orgo.space/docs/api-reference/eventspeaker/list-event-speakers /api-reference/openapi.json get /api/v1/event_speakers Returns all speakers across events for the current tenant, up to 100 per page. Filter by event to get speakers for a specific event. # Remove an event speaker Source: https://orgo.space/docs/api-reference/eventspeaker/remove-an-event-speaker /api-reference/openapi.json delete /api/v1/event_speakers/{id} Removes a speaker from an event. Requires event ownership or ADMIN_TENANT permission. # Update an event speaker Source: https://orgo.space/docs/api-reference/eventspeaker/update-an-event-speaker /api-reference/openapi.json patch /api/v1/event_speakers/{id} Updates speaker details such as bio, title, or sort order. Requires event ownership or ADMIN_TENANT permission. # Creates a EventStatus resource. Source: https://orgo.space/docs/api-reference/eventstatus/creates-a-eventstatus-resource /api-reference/openapi.json post /api/v1/event_statuses Creates a EventStatus resource. # Removes the EventStatus resource. Source: https://orgo.space/docs/api-reference/eventstatus/removes-the-eventstatus-resource /api-reference/openapi.json delete /api/v1/event_statuses/{id} Removes the EventStatus resource. # Retrieves a EventStatus resource. Source: https://orgo.space/docs/api-reference/eventstatus/retrieves-a-eventstatus-resource /api-reference/openapi.json get /api/v1/event_statuses/{id} Retrieves a EventStatus resource. # Retrieves the collection of EventStatus resources. Source: https://orgo.space/docs/api-reference/eventstatus/retrieves-the-collection-of-eventstatus-resources /api-reference/openapi.json get /api/v1/event_statuses Retrieves the collection of EventStatus resources. # Updates the EventStatus resource. Source: https://orgo.space/docs/api-reference/eventstatus/updates-the-eventstatus-resource /api-reference/openapi.json patch /api/v1/event_statuses/{id} Updates the EventStatus resource. # Creates a EventTemplate resource. Source: https://orgo.space/docs/api-reference/eventtemplate/creates-a-eventtemplate-resource /api-reference/openapi.json post /api/v1/event_templates Creates a EventTemplate resource. # Removes the EventTemplate resource. Source: https://orgo.space/docs/api-reference/eventtemplate/removes-the-eventtemplate-resource /api-reference/openapi.json delete /api/v1/event_templates/{id} Removes the EventTemplate resource. # Retrieves a EventTemplate resource. Source: https://orgo.space/docs/api-reference/eventtemplate/retrieves-a-eventtemplate-resource /api-reference/openapi.json get /api/v1/event_templates/{id} Retrieves a EventTemplate resource. # Retrieves the collection of EventTemplate resources. Source: https://orgo.space/docs/api-reference/eventtemplate/retrieves-the-collection-of-eventtemplate-resources /api-reference/openapi.json get /api/v1/event_templates Retrieves the collection of EventTemplate resources. # Retrieves the collection of EventTemplate resources. Source: https://orgo.space/docs/api-reference/eventtemplate/retrieves-the-collection-of-eventtemplate-resources-1 /api-reference/openapi.json get /api/v1/event_templates_for_create Retrieves the collection of EventTemplate resources. # Updates the EventTemplate resource. Source: https://orgo.space/docs/api-reference/eventtemplate/updates-the-eventtemplate-resource /api-reference/openapi.json patch /api/v1/event_templates/{id} Updates the EventTemplate resource. # Create an event type Source: https://orgo.space/docs/api-reference/eventtype/create-an-event-type /api-reference/openapi.json post /api/v1/event_types Creates a new event type and automatically assigns it to the current tenant. Requires ADMIN_TENANT permission. # Delete an event type Source: https://orgo.space/docs/api-reference/eventtype/delete-an-event-type /api-reference/openapi.json delete /api/v1/event_types/{id} Permanently removes an event type. Requires ADMIN_TENANT permission. Events already using this type are not affected. # Get an event type Source: https://orgo.space/docs/api-reference/eventtype/get-an-event-type /api-reference/openapi.json get /api/v1/event_types/{id} Returns a single event type by ID. Accessible to all authenticated tenant members. # List event types Source: https://orgo.space/docs/api-reference/eventtype/list-event-types /api-reference/openapi.json get /api/v1/event_types Returns all event types for the current tenant (up to 1000 per page). Used to populate event type selectors when creating or filtering events. # Update an event type Source: https://orgo.space/docs/api-reference/eventtype/update-an-event-type /api-reference/openapi.json patch /api/v1/event_types/{id} Updates an event type name or properties. Requires ADMIN_TENANT permission. # Create an event voucher Source: https://orgo.space/docs/api-reference/eventvoucher/create-an-event-voucher /api-reference/openapi.json post /api/v1/event_vouchers Creates a discount voucher for an event. Validates the discount type (percentage or fixed), value (percentage max 100), and code uniqueness per event. Fixed discounts require a currency. Optional limits: maxUses, maxTickets, maxDiscountAmount. Requires EVENT_TENANT permission. # Delete an event voucher Source: https://orgo.space/docs/api-reference/eventvoucher/delete-an-event-voucher /api-reference/openapi.json delete /api/v1/event_vouchers/{uuid} Permanently removes a voucher. Already-applied discounts on existing payments are not affected. Requires EVENT_TENANT permission. # Get an event voucher Source: https://orgo.space/docs/api-reference/eventvoucher/get-an-event-voucher /api-reference/openapi.json get /api/v1/event_vouchers/{uuid} Returns a single voucher with its discount type, value, usage count, and limits. # List event vouchers Source: https://orgo.space/docs/api-reference/eventvoucher/list-event-vouchers /api-reference/openapi.json get /api/v1/event_vouchers Returns all event vouchers for the current tenant, ordered by creation date descending. Filter by event to get vouchers for a specific event. # Update an event voucher Source: https://orgo.space/docs/api-reference/eventvoucher/update-an-event-voucher /api-reference/openapi.json patch /api/v1/event_vouchers/{uuid} Updates voucher properties such as discount value, usage limits, or active status. Requires EVENT_TENANT permission. # Create an experience history entry Source: https://orgo.space/docs/api-reference/experiencehistory/create-an-experience-history-entry /api-reference/openapi.json post /api/v1/experience_histories Creates a new experience history record for the authenticated user. If a different user is specified in the payload, HR_LOCAL permission on that user's local center is required. Otherwise, the entry is automatically assigned to the authenticated user. # Delete an experience history entry Source: https://orgo.space/docs/api-reference/experiencehistory/delete-an-experience-history-entry /api-reference/openapi.json delete /api/v1/experience_histories/{id} Permanently removes an experience history record. Only the owning user or users with HR_LOCAL permission on the user's local center can delete. # Get an experience history entry Source: https://orgo.space/docs/api-reference/experiencehistory/get-an-experience-history-entry /api-reference/openapi.json get /api/v1/experience_histories/{id} Returns a single experience history record including the role/position details, dates, and associated user. # List experience history entries Source: https://orgo.space/docs/api-reference/experiencehistory/list-experience-history-entries /api-reference/openapi.json get /api/v1/experience_histories Returns a paginated list of experience history entries (20 per page). Requires the user query parameter to filter by a specific user. Tenant isolation is enforced automatically via Doctrine extensions. # Update an experience history entry Source: https://orgo.space/docs/api-reference/experiencehistory/update-an-experience-history-entry /api-reference/openapi.json patch /api/v1/experience_histories/{id} Updates an experience history record (role, dates, description, etc.). Only the owning user or users with HR_LOCAL permission on the user's local center can update. # Create a family Source: https://orgo.space/docs/api-reference/familyentity/create-a-family /api-reference/openapi.json post /api/v1/family_entities Creates a new family entity. If familyOwner is provided, the owner is automatically added as a parent-level FamilyMember with management permissions. A user can only own one family per tenant. Families without an owner can only be created by HR_LOCAL admins. # Delete a family Source: https://orgo.space/docs/api-reference/familyentity/delete-a-family /api-reference/openapi.json delete /api/v1/family-entities/{id}/delete Deletes a family and all its members within a transaction. Only the family owner or HR_LOCAL admins can delete. Fails if the family still has members other than the owner -- all members must be removed first. # Delete a family Source: https://orgo.space/docs/api-reference/familyentity/delete-a-family-1 /api-reference/openapi.json delete /api/v1/family_entities/{id} Permanently removes a family entity. Only the family owner or HR_LOCAL admins can delete. The standard Delete operation removes the entity via API Platform's default handler. # Get a family Source: https://orgo.space/docs/api-reference/familyentity/get-a-family /api-reference/openapi.json get /api/v1/family_entities/{id} Returns details of a specific family entity. Only accessible to users within the same tenant. # Get current user families Source: https://orgo.space/docs/api-reference/familyentity/get-current-user-families /api-reference/openapi.json get /api/v1/my-families Returns all families the current user belongs to, including their role, ownership status, and member count. Accepts an optional userId query parameter to view another user's families (requires HR_LOCAL permission or parent management access for that user). # Get family members Source: https://orgo.space/docs/api-reference/familyentity/get-family-members /api-reference/openapi.json get /api/v1/family-entities/{id}/members Returns all members of a family with their details (level, permissions, user profile data). Accessible by family members or HR_LOCAL admins. For child members on a waitlist, also includes waitlist status and UUID. # List families Source: https://orgo.space/docs/api-reference/familyentity/list-families /api-reference/openapi.json get /api/v1/family_entities Returns a paginated list of family entities within the current tenant. Filtered automatically by tenant isolation via Doctrine extensions. # Update a family Source: https://orgo.space/docs/api-reference/familyentity/update-a-family /api-reference/openapi.json patch /api/v1/family_entities/{id} Updates a family entity (name, privacy level, etc.). Only the family owner or users with HR_LOCAL permission for the owner's local center can update. # Update family name Source: https://orgo.space/docs/api-reference/familyentity/update-family-name /api-reference/openapi.json patch /api/v1/family-entities/{id}/update-name Updates the name of a family entity. Only the family owner or HR_LOCAL admins can change the name. Requires a non-empty name field in the JSON payload. # Add a family member Source: https://orgo.space/docs/api-reference/familymember/add-a-family-member /api-reference/openapi.json post /api/v1/family-members/add Adds a new member to a family. Requires familyId and either userId (existing user) or email/name (non-user contact). Only family owners, members with canManageChildren, or HR_LOCAL admins can add members. A user cannot belong to multiple families. Parents/guardians automatically receive child management permissions. # Get a family member Source: https://orgo.space/docs/api-reference/familymember/get-a-family-member /api-reference/openapi.json get /api/v1/family_members/{id} Returns details of a specific family member. Only accessible within the same tenant by the family owner or users with HR_LOCAL permission for the owner's local center. # List family members Source: https://orgo.space/docs/api-reference/familymember/list-family-members /api-reference/openapi.json get /api/v1/family_members Returns a paginated list of all family members within the current tenant. Filtered by tenant isolation via Doctrine extensions. # Remove a family member Source: https://orgo.space/docs/api-reference/familymember/remove-a-family-member /api-reference/openapi.json delete /api/v1/family-members/{id}/remove Removes a member from a family. Only the family owner or HR_LOCAL admins can remove members. The family owner themselves cannot be removed -- delete the family instead. # Update a family member Source: https://orgo.space/docs/api-reference/familymember/update-a-family-member /api-reference/openapi.json patch /api/v1/family-members/{id}/update Updates a family member's level (parent, guardian, child) and management permissions. Only the family owner or HR_LOCAL admins can update. Changing level to parent or guardian automatically grants canManageChildren permission. # Approve a fee payment Source: https://orgo.space/docs/api-reference/feepayment/approve-a-fee-payment /api-reference/openapi.json patch /api/v1/fee-payment-approve/{id} Approves a fee payment batch, setting its status to success. All associated product payments are also marked as successful. For each affected user, recalculates fee validity dates -- using local center fee validity for local center products or tenant-level fee validity otherwise. Deduplicates user processing to avoid N+1 updates. Requires FINANCIAL_LOCAL permission. # Create a fee payment Source: https://orgo.space/docs/api-reference/feepayment/create-a-fee-payment /api-reference/openapi.json post /api/v1/fee_payments Creates a new fee payment batch record. This is a standard CRUD create with no custom controller logic. The fee payment acts as a container for individual product payments that are linked separately. Requires FINANCIAL_LOCAL permission. # Delete a fee payment Source: https://orgo.space/docs/api-reference/feepayment/delete-a-fee-payment /api-reference/openapi.json delete /api/v1/fee_payments/{id} Permanently deletes a fee payment batch record. This is a standard CRUD delete with no custom controller logic. Requires FINANCIAL_LOCAL permission for the fee payment local center. # Get a fee payment Source: https://orgo.space/docs/api-reference/feepayment/get-a-fee-payment /api-reference/openapi.json get /api/v1/fee_payments/{id} Retrieves a single fee payment by ID with additional item-level detail (fee_read_item group includes associated product payments). Requires FINANCIAL_LOCAL permission for the fee payment local center. # List fee payments Source: https://orgo.space/docs/api-reference/feepayment/list-fee-payments /api-reference/openapi.json get /api/v1/fee_payments Returns a list of fee payment records for the local center. Fee payments represent bulk offline payment batches (e.g. cash collected at a meeting) that group multiple individual product payments. Requires FINANCIAL_LOCAL permission. # Update a fee payment Source: https://orgo.space/docs/api-reference/feepayment/update-a-fee-payment /api-reference/openapi.json patch /api/v1/fee_payments/{id} Updates a fee payment batch record. This is a standard CRUD update with no custom controller logic. Requires FINANCIAL_LOCAL permission for the fee payment local center. # Create a form Source: https://orgo.space/docs/api-reference/form/create-a-form /api-reference/openapi.json post /api/v1/forms Creates a new form in the current tenant. The form is created in DRAFT status by default. # Delete a form Source: https://orgo.space/docs/api-reference/form/delete-a-form /api-reference/openapi.json delete /api/v1/forms/{uuid} Soft-deletes a form by setting its status to DELETED. The form record is preserved in the database for audit purposes but hidden from listings. # Get a form Source: https://orgo.space/docs/api-reference/form/get-a-form /api-reference/openapi.json get /api/v1/forms/{uuid} Retrieves a single form by UUID. Returns full form details including fields configuration and settings. # Get form statistics Source: https://orgo.space/docs/api-reference/form/get-form-statistics /api-reference/openapi.json get /api/v1/forms/{uuid}/statistics Returns cached form analytics including submission overview (total, confirmed, pending, completion rate), per-field statistics with value distributions for choice fields and grouped text responses, and a list of the latest 100 confirmed submissions. Requires form ownership or EVENT_TENANT/COMMUNICATION_TENANT permission in the same tenant. # Get form submissions table Source: https://orgo.space/docs/api-reference/form/get-form-submissions-table /api-reference/openapi.json get /api/v1/forms/{uuid}/submissions/table Returns a paginated table view of confirmed form submissions with dynamic columns based on form fields. Supports export mode (up to 10,000 rows) via ?export=true query parameter. Columns adapt based on submission mode (anonymous forms hide submitter columns). Requires form ownership or EVENT_TENANT/COMMUNICATION_TENANT permission in the same tenant. # Get public form (anonymous) Source: https://orgo.space/docs/api-reference/form/get-public-form-anonymous /api-reference/openapi.json get /api/v1/get_public_form_anonymous/{uuid} Retrieves a form for public anonymous access. Only available for PUBLISHED or CLOSED forms. Checks device fingerprint (IP + User-Agent hash) against previous submissions when uniqueSubmissions is enabled, returning hasSubmitted and uniqueSubmissionsEnabled flags. Uses public_form_read_anonymous serialization group. # List forms Source: https://orgo.space/docs/api-reference/form/list-forms /api-reference/openapi.json get /api/v1/forms Returns a paginated list of forms belonging to the current tenant. Results are filtered by tenant via Doctrine extensions. Default pagination is 12 items per page. # Publish a form Source: https://orgo.space/docs/api-reference/form/publish-a-form /api-reference/openapi.json patch /api/v1/form-go-publish/{uuid} Publishes a form by generating a unique 7-character alphanumeric short slug (if not already set) and uploading a shareable page to S3 for short link and social media previews. Requires form ownership or EVENT_TENANT/COMMUNICATION_TENANT permission. # Recalculate form statistics Source: https://orgo.space/docs/api-reference/form/recalculate-form-statistics /api-reference/openapi.json post /api/v1/forms/{uuid}/recalculate_statistics Forces a full recalculation of form statistics, bypassing the cache. Returns the recalculated totals and timestamp. Useful when statistics appear stale. Requires form ownership or EVENT_TENANT/COMMUNICATION_TENANT permission in the same tenant. # Resolve form by slug Source: https://orgo.space/docs/api-reference/form/resolve-form-by-slug /api-reference/openapi.json get /api/v1/resolve-slug-go/{slugGo} Resolves a short slug (slugGo) to its target entity. Searches forms, newsletters, and products in order. Returns the entity type (form/newsletter/product) and its UUID or slug. Throws 404 if no matching entity is found. # Update a form Source: https://orgo.space/docs/api-reference/form/update-a-form /api-reference/openapi.json patch /api/v1/forms/{uuid} Partially updates an existing form. Can modify title, description, settings, and status fields. # Create a form field Source: https://orgo.space/docs/api-reference/formfield/create-a-form-field /api-reference/openapi.json post /api/v1/form_fields Creates a new form field linked to a form. Each form field wraps a custom field definition that specifies the field type (input, dropdown, radio, checkboxes, etc.) and options. # Delete a form field Source: https://orgo.space/docs/api-reference/formfield/delete-a-form-field /api-reference/openapi.json delete /api/v1/form_fields/{id} Permanently removes a form field and its associated custom field definition. Existing submission answers referencing this field are orphaned. # Get a form field Source: https://orgo.space/docs/api-reference/formfield/get-a-form-field /api-reference/openapi.json get /api/v1/form_fields/{id} Retrieves a single form field by ID, including its linked custom field definition and configuration. # List form fields Source: https://orgo.space/docs/api-reference/formfield/list-form-fields /api-reference/openapi.json get /api/v1/form_fields Returns form fields ordered by position (ASC). Filter by form using ?form= query parameter to get fields for a specific form. # Update a form field Source: https://orgo.space/docs/api-reference/formfield/update-a-form-field /api-reference/openapi.json patch /api/v1/form_fields/{id} Partially updates a form field. Can modify position, mandatory flag, description, and linked custom field properties. # Create a form submission Source: https://orgo.space/docs/api-reference/formsubmission/create-a-form-submission /api-reference/openapi.json post /api/v1/form_submissions Creates a new form submission with associated answers. Submissions can be linked to a user, contact, or submitted anonymously depending on the form submission mode. # Delete a form submission Source: https://orgo.space/docs/api-reference/formsubmission/delete-a-form-submission /api-reference/openapi.json delete /api/v1/form_submissions/{id} Permanently removes a form submission and its associated answers. # Get a form submission Source: https://orgo.space/docs/api-reference/formsubmission/get-a-form-submission /api-reference/openapi.json get /api/v1/form_submissions/{id} Retrieves a single form submission by ID, including submitter information and answer references. # Get form submission details Source: https://orgo.space/docs/api-reference/formsubmission/get-form-submission-details /api-reference/openapi.json get /api/v1/form_submissions/{id}/details Returns detailed view of a single submission including submitter info (user/contact/anonymous), all form fields with their answers (both raw and formatted values), and field metadata (type, mandatory, description). Only the form owner can access submission details. # List form submissions Source: https://orgo.space/docs/api-reference/formsubmission/list-form-submissions /api-reference/openapi.json get /api/v1/form_submissions Returns a paginated list of form submissions. Filter by form using ?form= query parameter. Results are tenant-isolated. # Update a form submission Source: https://orgo.space/docs/api-reference/formsubmission/update-a-form-submission /api-reference/openapi.json patch /api/v1/form_submissions/{id} Partially updates a form submission. Can modify validity status and other writable fields. # Creates a FormSubmissionAnswer resource. Source: https://orgo.space/docs/api-reference/formsubmissionanswer/creates-a-formsubmissionanswer-resource /api-reference/openapi.json post /api/v1/form_submission_answers Creates a FormSubmissionAnswer resource. # Removes the FormSubmissionAnswer resource. Source: https://orgo.space/docs/api-reference/formsubmissionanswer/removes-the-formsubmissionanswer-resource /api-reference/openapi.json delete /api/v1/form_submission_answers/{id} Removes the FormSubmissionAnswer resource. # Retrieves a FormSubmissionAnswer resource. Source: https://orgo.space/docs/api-reference/formsubmissionanswer/retrieves-a-formsubmissionanswer-resource /api-reference/openapi.json get /api/v1/form_submission_answers/{id} Retrieves a FormSubmissionAnswer resource. # Retrieves the collection of FormSubmissionAnswer resources. Source: https://orgo.space/docs/api-reference/formsubmissionanswer/retrieves-the-collection-of-formsubmissionanswer-resources /api-reference/openapi.json get /api/v1/form_submission_answers Retrieves the collection of FormSubmissionAnswer resources. # Updates the FormSubmissionAnswer resource. Source: https://orgo.space/docs/api-reference/formsubmissionanswer/updates-the-formsubmissionanswer-resource /api-reference/openapi.json patch /api/v1/form_submission_answers/{id} Updates the FormSubmissionAnswer resource. # Create a goal Source: https://orgo.space/docs/api-reference/goal/create-a-goal /api-reference/openapi.json post /api/v1/goals Creates a new goal within a project. A project reference is required. Inherits the tenant from the project. Automatically assigns the next available position if not specified. Requires PROJECT_ACCESS permission on the parent project. # Delete a goal Source: https://orgo.space/docs/api-reference/goal/delete-a-goal /api-reference/openapi.json delete /api/v1/goals/{uuid} Permanently removes a goal from its project. Requires PROJECT_EDIT permission (stricter than read access) on the parent project. # Get a goal Source: https://orgo.space/docs/api-reference/goal/get-a-goal /api-reference/openapi.json get /api/v1/goals/{uuid} Retrieves a single goal by ID. Requires PROJECT_ACCESS permission on the parent project. # List goals Source: https://orgo.space/docs/api-reference/goal/list-goals /api-reference/openapi.json get /api/v1/goals Returns a paginated list of goals ordered by position (ASC). Default pagination is 50 items per page. Filter by project using query parameters. # Update a goal Source: https://orgo.space/docs/api-reference/goal/update-a-goal /api-reference/openapi.json patch /api/v1/goals/{uuid} Partially updates a goal (name, description, position, status, etc.). Requires PROJECT_ACCESS permission on the parent project. # Create a group Source: https://orgo.space/docs/api-reference/group/create-a-group /api-reference/openapi.json post /api/v1/groups Creates a new group and adds the current user as admin member with auto-follow. Tenant settings control who can create groups (ROLE_USER or higher). Community groups (isJoinable) can only be created by tenant admins. Project groups automatically receive default issue statuses and types. # Delete a group Source: https://orgo.space/docs/api-reference/group/delete-a-group /api-reference/openapi.json delete /api/v1/groups/{id} Deletes a group permanently. Cannot delete groups that have an associated newsletter; remove the newsletter first or archive the group instead. Requires group admin access. # Get a group Source: https://orgo.space/docs/api-reference/group/get-a-group /api-reference/openapi.json get /api/v1/groups/{id} Retrieves a single group by ID. Access is validated based on group visibility settings and the user membership/role within the group. # List groups Source: https://orgo.space/docs/api-reference/group/list-groups /api-reference/openapi.json get /api/v1/groups Returns a paginated list of groups within the current tenant. The query isJoinable=1&status=ACTIVE is cached for performance. Supports filters for status, isJoinable, category, and other fields. # List my groups Source: https://orgo.space/docs/api-reference/group/list-my-groups /api-reference/openapi.json get /api/v1/my-groups Returns all groups, role groups, units, and local centers the current user is a member of. Results are filtered by the user effective user type and ordered with role groups, unit-type units, and local centers first, followed by regular groups. # Update a group Source: https://orgo.space/docs/api-reference/group/update-a-group /api-reference/openapi.json patch /api/v1/groups/{id} Updates group properties such as name, description, visibility, and settings. Validates group-specific permissions including parent/category constraints. Requires group admin access. # Create a group category Source: https://orgo.space/docs/api-reference/groupcategory/create-a-group-category /api-reference/openapi.json post /api/v1/group_categories Creates a new group category for organizing groups. Restricted to tenant HR administrators. # Delete a group category Source: https://orgo.space/docs/api-reference/groupcategory/delete-a-group-category /api-reference/openapi.json delete /api/v1/group_categories/{id} Deletes a group category. Groups assigned to this category will become uncategorized. Restricted to tenant HR administrators. # Get a group category Source: https://orgo.space/docs/api-reference/groupcategory/get-a-group-category /api-reference/openapi.json get /api/v1/group_categories/{id} Retrieves a single group category by ID. Restricted to tenant HR administrators. # List group categories Source: https://orgo.space/docs/api-reference/groupcategory/list-group-categories /api-reference/openapi.json get /api/v1/group_categories Returns all group categories for the current tenant. Categories are used to organize and classify groups. # Update a group category Source: https://orgo.space/docs/api-reference/groupcategory/update-a-group-category /api-reference/openapi.json patch /api/v1/group_categories/{id} Updates the name or other properties of a group category. Restricted to tenant HR administrators. # Create identity as anonymous Source: https://orgo.space/docs/api-reference/identity/create-identity-as-anonymous /api-reference/openapi.json post /api/v1/identity/create/anonymous Creates a new identity verification record without authentication. Used during anonymous payment flows (subscriptions or one-time payments). Requires a paymentUid or userId in the payload along with the document image. Triggers OCR processing via Lambda and notifies the financial team. Returns only the identity hash (for Romanian new ID type) or a success flag to limit data exposure. # Create identity as member Source: https://orgo.space/docs/api-reference/identity/create-identity-as-member /api-reference/openapi.json post /api/v1/identity/create/member Creates a new identity verification record as an authenticated member. Links the identity to a subscription profile or product payment (via paymentUid), or directly to the user. Uploads the document image, triggers OCR via Lambda, and optimizes the media. For subscriptions with automated identity validation, may return a Stripe checkout redirect. Notifies the financial team via email. # Get an identity verification Source: https://orgo.space/docs/api-reference/identity/get-an-identity-verification /api-reference/openapi.json get /api/v1/identity/{id} Returns the details of an identity verification record including document data, status, and associated media. Access is controlled by IdentityService.checkAccess -- typically restricted to the identity owner and financial/HR admins. # Reject an identity Source: https://orgo.space/docs/api-reference/identity/reject-an-identity /api-reference/openapi.json patch /api/v1/identity/{id}/reject Rejects an identity verification and sends a rejection notification email to the member. If isAdhesion is true in the payload, also resets the user's adhesion status to NEW and removes the uploaded document media. Marks all related payment identity reminders as sent to prevent further reminder emails. # Reopen an identity verification Source: https://orgo.space/docs/api-reference/identity/reopen-an-identity-verification /api-reference/openapi.json patch /api/v1/identity/{id}/reopen Resets a previously validated or rejected identity verification back to PENDING status, allowing the member to re-upload or update documents. Records the admin who performed the reopen action. # Update identity data Source: https://orgo.space/docs/api-reference/identity/update-identity-data /api-reference/openapi.json patch /api/v1/identity/{id}/update-data Updates the extracted data fields of an identity verification (name, ID number, personal number, dates, etc.). If the identity is linked to a contact, also updates the contact's name. Validates the personal number format for Romanian IDs. Optionally removes the back media if mediaBack=false in the payload. # Update identity document Source: https://orgo.space/docs/api-reference/identity/update-identity-document /api-reference/openapi.json post /api/v1/identity/{id}/update-document Replaces the front or back document image of an existing identity verification. Set mediaBack=true in the payload to update the back side. Validates the uploaded file is a valid image format, triggers OCR processing via Lambda, and optimizes the new media. If the identity was previously rejected, automatically resets status to PENDING. # Upload identity document back side Source: https://orgo.space/docs/api-reference/identity/upload-identity-document-back-side /api-reference/openapi.json post /api/v1/identity/upload-media-back Uploads the back side of an identity document for an anonymous flow. Requires the identity hash and optionally paymentUuid/paymentType to validate ownership. Triggers OCR processing on the back image, updates contact name if applicable, and clears the identity hash after processing. If automated identity validation is enabled, may return a Stripe checkout redirect. # Validate an identity Source: https://orgo.space/docs/api-reference/identity/validate-an-identity /api-reference/openapi.json patch /api/v1/identity/{id}/validate Marks an identity verification as validated by an admin. Requires all mandatory fields (name, ID number, personal number, dates, ID type). Validates that the ID is not expired, the issue date is in the past, and the person is at least 18 years old. Updates linked subscription profiles to IDENTITY_VALIDATED status and captures pending Stripe payments. Sends a validation notification email to the member. # Cancel bank transfer invoice Source: https://orgo.space/docs/api-reference/invoice/cancel-bank-transfer-invoice /api-reference/openapi.json post /api/v1/invoices/cancel-bank-transfer Cancels the most recent pending bank transfer invoice for the authenticated user. Finds the latest unpaid membership renewal invoice and sets its status to voided. Returns 404 if no pending bank transfer is found. No admin permission required -- available to any authenticated member. # Create an invoice Source: https://orgo.space/docs/api-reference/invoice/create-an-invoice /api-reference/openapi.json post /api/v1/invoices Creates a manual invoice with auto-generated invoice number and hash. Sets status to unpaid and type to manual. Validates membership status if applicable. Generates the HTML body from the invoice template with placeholders replaced, builds the request payload for payment links, and automatically sends the invoice email to the recipient. Requires ADMIN_TENANT permission. # Create bank transfer invoice Source: https://orgo.space/docs/api-reference/invoice/create-bank-transfer-invoice /api-reference/openapi.json post /api/v1/invoices/create-for-bank-transfer Creates an unpaid membership renewal invoice for bank transfer payment by the authenticated user. Supports two modes: interval-based fees (pass fees object with date ranges and amounts) or regular fees (uses the user assigned product price). Validates no other pending bank transfer invoice exists. Returns the invoice series, amount, currency, and banking info (account holder, IBAN) for the user to complete the transfer. No admin permission required -- available to any authenticated member. # Delete an invoice Source: https://orgo.space/docs/api-reference/invoice/delete-an-invoice /api-reference/openapi.json delete /api/v1/invoices/{id} Permanently deletes an invoice. This is a standard CRUD delete with no custom controller logic. Requires ADMIN_TENANT permission. # Download invoice PDF Source: https://orgo.space/docs/api-reference/invoice/download-invoice-pdf /api-reference/openapi.json get /api/v1/invoices/{id}/download Generates and downloads the invoice as a PDF file (or HTML fallback if wkhtmltopdf is unavailable). The filename follows the format "Invoice - {TenantShortName} - {InvoiceNumber}.pdf". Requires ADMIN_TENANT permission. # Get an invoice Source: https://orgo.space/docs/api-reference/invoice/get-an-invoice /api-reference/openapi.json get /api/v1/invoices/{id} Retrieves a single invoice by ID, including billing details, status, body HTML, and associated user/contact/company. Requires ADMIN_TENANT permission. # List invoices Source: https://orgo.space/docs/api-reference/invoice/list-invoices /api-reference/openapi.json get /api/v1/invoices Returns a paginated list of invoices for the tenant (20 per page). Requires ADMIN_TENANT permission. Supports standard API Platform filters. # Mark invoice as paid Source: https://orgo.space/docs/api-reference/invoice/mark-invoice-as-paid /api-reference/openapi.json patch /api/v1/invoices/{id}/mark-as-paid Manually marks an invoice as paid for offline/bank transfer payments. Creates a ProductPayment record linked to the invoice. For membership invoices, updates the user or company fee validity dates and syncs membership to company users if applicable. For event registration invoices, confirms event registrations and sends ticket confirmation emails. Adds a visual PAID badge to the invoice HTML and sends the updated invoice by email. Requires ADMIN_TENANT permission. # Refund a paid invoice Source: https://orgo.space/docs/api-reference/invoice/refund-a-paid-invoice /api-reference/openapi.json patch /api/v1/invoices/{id}/refund Marks a paid invoice as refunded (record-keeping only; no payment gateway call). Sets status to refunded, records refundedBy and dateRefunded, and unwinds linked side-effects: ProductPayment becomes refunded; event registration EventAttends are canceled and ticket capacity is released; user fee validity is recomputed from remaining paid payments; company membership is rolled back from history. Adds a REFUNDED badge to the invoice HTML. Does not send email. Requires ADMIN_TENANT permission. # Send invoice by email Source: https://orgo.space/docs/api-reference/invoice/send-invoice-by-email /api-reference/openapi.json get /api/v1/invoices/{id}/send-email Sends the invoice to the recipient via email using the InvoiceService. The email includes the invoice HTML body. Can be used to resend invoices. Requires ADMIN_TENANT permission. # Update an invoice Source: https://orgo.space/docs/api-reference/invoice/update-an-invoice /api-reference/openapi.json patch /api/v1/invoices/{id} Updates an invoice and regenerates the HTML body from the template. Validates membership status if applicable. For non-event-registration invoices, also regenerates the request payload. Event registration invoices preserve their original payload format (with ticket details and eventUuid). Requires ADMIN_TENANT permission. # Void an invoice Source: https://orgo.space/docs/api-reference/invoice/void-an-invoice /api-reference/openapi.json patch /api/v1/invoices/{id}/void Voids an invoice, setting its status to voided. For event registration invoices, also cancels associated event registrations (releasing ticket capacity) and sets the linked ProductPayment status to canceled. Requires ADMIN_TENANT permission. # Create an invoice template Source: https://orgo.space/docs/api-reference/invoicetemplate/create-an-invoice-template /api-reference/openapi.json post /api/v1/invoice_templates Creates a new invoice template for the tenant. Requires the invoice feature to be enabled in tenant settings. If isDefault is set to true, all other templates for the tenant are unset as default. Requires ADMIN_TENANT permission. # Delete an invoice template Source: https://orgo.space/docs/api-reference/invoicetemplate/delete-an-invoice-template /api-reference/openapi.json delete /api/v1/invoice_templates/{id} Permanently deletes an invoice template. This is a standard CRUD delete with no custom controller logic. Requires ADMIN_TENANT permission. # Get an invoice template Source: https://orgo.space/docs/api-reference/invoicetemplate/get-an-invoice-template /api-reference/openapi.json get /api/v1/invoice_templates/{id} Retrieves a single invoice template by ID. Requires ADMIN_TENANT permission. # List invoice templates Source: https://orgo.space/docs/api-reference/invoicetemplate/list-invoice-templates /api-reference/openapi.json get /api/v1/invoice_templates Returns a paginated list of invoice templates for the tenant (50 per page). Templates define default tax rates, memos, footers, and custom fields applied to new invoices. Requires ADMIN_TENANT permission. # Update an invoice template Source: https://orgo.space/docs/api-reference/invoicetemplate/update-an-invoice-template /api-reference/openapi.json patch /api/v1/invoice_templates/{id} Updates an existing invoice template. If isDefault is set to true, all other templates for the tenant are unset as default. Enforces tenant isolation. Requires ADMIN_TENANT permission. # Create an issue status Source: https://orgo.space/docs/api-reference/issuestatus/create-an-issue-status /api-reference/openapi.json post /api/v1/issue_statuses Creates a new issue status at tenant or unit level. For project-specific statuses, set the project field and PROJECT_ACCESS is required. For support ticket statuses, unit-level permission is validated. Includes name, color, position, and isClosed flag. # Delete an issue status Source: https://orgo.space/docs/api-reference/issuestatus/delete-an-issue-status /api-reference/openapi.json delete /api/v1/issue_statuses/{id} Deletes an issue status. Unit-level permission is validated before deletion. Consider reassigning tasks/tickets using this status before deleting. # Get an issue status Source: https://orgo.space/docs/api-reference/issuestatus/get-an-issue-status /api-reference/openapi.json get /api/v1/issue_statuses/{id} Retrieves a single issue status by its identifier, including name, color, position, and whether it represents a closed state. # List issue statuses Source: https://orgo.space/docs/api-reference/issuestatus/list-issue-statuses /api-reference/openapi.json get /api/v1/issue_statuses Returns issue statuses ordered by position ascending. Must filter by either tenantSupport (tenant ID) or unit (unit ID) query parameter. Validates user access to the specified unit or tenant. # Update an issue status Source: https://orgo.space/docs/api-reference/issuestatus/update-an-issue-status /api-reference/openapi.json patch /api/v1/issue_statuses/{id} Updates an issue status (name, color, position, isClosed). For project-specific statuses, PROJECT_ACCESS is required. For tenant/unit-level statuses, appropriate unit permission is validated. # Create an issue type Source: https://orgo.space/docs/api-reference/issuetype/create-an-issue-type /api-reference/openapi.json post /api/v1/issue_types Creates a new issue type (e.g., bug, feature request, question) at tenant or unit level. If a unit is specified, unit-level permission is validated. Otherwise, the type is created at tenant level. # Delete an issue type Source: https://orgo.space/docs/api-reference/issuetype/delete-an-issue-type /api-reference/openapi.json delete /api/v1/issue_types/{id} Deletes an issue type. Unit-level permission is validated before deletion. Consider reassigning tickets using this type before deleting. # Get an issue type Source: https://orgo.space/docs/api-reference/issuetype/get-an-issue-type /api-reference/openapi.json get /api/v1/issue_types/{id} Retrieves a single issue type by its identifier, including its name, icon, and position. # List issue types Source: https://orgo.space/docs/api-reference/issuetype/list-issue-types /api-reference/openapi.json get /api/v1/issue_types Returns issue types ordered by position ascending. Must filter by either tenantSupport (tenant ID) or unit (unit ID) query parameter. Validates user access to the specified unit or tenant. # Update an issue type Source: https://orgo.space/docs/api-reference/issuetype/update-an-issue-type /api-reference/openapi.json patch /api/v1/issue_types/{id} Updates an issue type (name, icon, position). Unit-level permission is validated. If the type belongs to the tenant level, tenant permission is required. # Create a local center Source: https://orgo.space/docs/api-reference/localcenter/create-a-local-center /api-reference/openapi.json post /api/v1/local_centers Creates a new local center within the tenant. A local center represents a geographic branch or chapter. Requires HR_TENANT permission. # Delete a local center Source: https://orgo.space/docs/api-reference/localcenter/delete-a-local-center /api-reference/openapi.json delete /api/v1/local_centers/{id} Deletes a local center. If the center has blocking constraints (active members or related data), performs a soft delete by setting status to CLOSED with an end date. Otherwise performs a hard delete. Requires ADMIN_TENANT permission. # Get a local center Source: https://orgo.space/docs/api-reference/localcenter/get-a-local-center /api-reference/openapi.json get /api/v1/local_centers/{id} Retrieves a single local center by ID, including its associated town, region, contact details, and active/closed status. # List all local centers unpaginated Source: https://orgo.space/docs/api-reference/localcenter/list-all-local-centers-unpaginated /api-reference/openapi.json get /api/v1/local_centers_all Returns all local centers in a single response (up to 1000). Uses the same cached provider as the paginated endpoint. Designed for dropdown selectors and maps where all centers are needed at once. # List local centers Source: https://orgo.space/docs/api-reference/localcenter/list-local-centers /api-reference/openapi.json get /api/v1/local_centers Returns a paginated list of local centers ordered by town name. Results are cached when no filters are applied or only status=ACTIVE is set. Supports standard API Platform filters for status, town, and region. Default page size is 100 (max 1000). # List local centers for map display Source: https://orgo.space/docs/api-reference/localcenter/list-local-centers-for-map-display /api-reference/openapi.json get /api/v1/local-centers-map Returns lightweight local center data optimized for map rendering. Includes only coordinates, name, and contact info. Uses cached queries for performance. Authenticated users resolve tenant from token. # List local centers for public map display Source: https://orgo.space/docs/api-reference/localcenter/list-local-centers-for-public-map-display /api-reference/openapi.json get /api/v1/local-centers-map-public Public version of map data endpoint. Requires tenantSlug query parameter. Designed for iframe embedding. # List public local centers Source: https://orgo.space/docs/api-reference/localcenter/list-public-local-centers /api-reference/openapi.json get /api/v1/local-centers-public Returns local centers with public-facing information only. No authentication required. Designed for registration flows and public organization pages where users select their local center. # Update a local center Source: https://orgo.space/docs/api-reference/localcenter/update-a-local-center /api-reference/openapi.json patch /api/v1/local_centers/{id} Updates local center properties such as contact details, address, and settings. Requires ADMIN_LOCAL permission on the specific local center. # Approve a local center request Source: https://orgo.space/docs/api-reference/localcenterrequest/approve-a-local-center-request /api-reference/openapi.json patch /api/v1/local_center_requests/{id}/approve Approves a pending transfer request. Moves the user to the new local center, ends their role at the old center, and creates a new role assignment at the new center. Sets status to APPROVED and sends a notification email to the user. # Create a local center transfer request Source: https://orgo.space/docs/api-reference/localcenterrequest/create-a-local-center-transfer-request /api-reference/openapi.json post /api/v1/local_center_requests Creates a request to transfer a user to a different local center. Sets status to PENDING and records the current local center. Validates the request and sends a notification email to HR admins of the target local center. The caller can submit for themselves or on behalf of another user by providing the user field. # Decline a local center request Source: https://orgo.space/docs/api-reference/localcenterrequest/decline-a-local-center-request /api-reference/openapi.json patch /api/v1/local_center_requests/{id}/decline Declines a pending transfer request. Sets status to DECLINED and the user remains at their current local center. Sends a notification email to the user informing them of the decision. # Get a local center request Source: https://orgo.space/docs/api-reference/localcenterrequest/get-a-local-center-request /api-reference/openapi.json get /api/v1/local_center_requests/{id} Retrieves a single local center transfer request. Accessible to HR admins of the target local center or the user who submitted the request. # List local center requests Source: https://orgo.space/docs/api-reference/localcenterrequest/list-local-center-requests /api-reference/openapi.json get /api/v1/local_center_requests Returns all local center transfer requests ordered by request date (newest first). Results are automatically tenant-isolated via Doctrine extensions. # Add a user preference Source: https://orgo.space/docs/api-reference/localcenteruserpreference/add-a-user-preference /api-reference/openapi.json post /api/v1/local_center_user_preferences Adds a local center to the current user favorites. Send "localCenterId" in the request body. If the local center is already a favorite, returns success without creating a duplicate. # Delete a user preference Source: https://orgo.space/docs/api-reference/localcenteruserpreference/delete-a-user-preference /api-reference/openapi.json delete /api/v1/local_center_user_preferences/{id} Removes a local center from the current user favorites. Users can only remove their own favorites. Returns the updated favorite status and local center ID. # Get a user preference Source: https://orgo.space/docs/api-reference/localcenteruserpreference/get-a-user-preference /api-reference/openapi.json get /api/v1/local_center_user_preferences/{id} Retrieves a single local center favorite entry by ID, including the associated local center details. # List user preferences Source: https://orgo.space/docs/api-reference/localcenteruserpreference/list-user-preferences /api-reference/openapi.json get /api/v1/local_center_user_preferences Returns all local center favorites for the current user. Used to display preferred/bookmarked local centers in the UI. # Create a user type Source: https://orgo.space/docs/api-reference/localcenterusertype/create-a-user-type /api-reference/openapi.json post /api/v1/local_center_user_types Creates a new local center user type for categorizing members within local centers. Requires HR_TENANT permission. # Delete a user type Source: https://orgo.space/docs/api-reference/localcenterusertype/delete-a-user-type /api-reference/openapi.json delete /api/v1/local_center_user_types/{id} Permanently deletes a local center user type. Ensure no users are currently assigned this type before deletion. Requires ADMIN_TENANT permission. # Get a user type Source: https://orgo.space/docs/api-reference/localcenterusertype/get-a-user-type /api-reference/openapi.json get /api/v1/local_center_user_types/{id} Retrieves a single local center user type by ID, including its name and configuration. # List user types Source: https://orgo.space/docs/api-reference/localcenterusertype/list-user-types /api-reference/openapi.json get /api/v1/local_center_user_types Returns all local center user types for the current tenant. User types categorize members within local centers (e.g., volunteer, board member, regular member). # Creates a user token. Source: https://orgo.space/docs/api-reference/login-check/creates-a-user-token /api-reference/openapi.json post /api/v1/login-check Creates a user token. # Creates a Newsletter resource. Source: https://orgo.space/docs/api-reference/newsletter/creates-a-newsletter-resource /api-reference/openapi.json post /api/v1/newsletters Creates a Newsletter resource. # Removes the Newsletter resource. Source: https://orgo.space/docs/api-reference/newsletter/removes-the-newsletter-resource /api-reference/openapi.json delete /api/v1/newsletters/{uuid} Removes the Newsletter resource. # Retrieves a Newsletter resource. Source: https://orgo.space/docs/api-reference/newsletter/retrieves-a-newsletter-resource /api-reference/openapi.json get /api/v1/newsletters/{uuid} Retrieves a Newsletter resource. # Retrieves a Newsletter resource. Source: https://orgo.space/docs/api-reference/newsletter/retrieves-a-newsletter-resource-1 /api-reference/openapi.json get /api/v1/newsletters/{uuid}/non-openers-count Retrieves a Newsletter resource. # Retrieves a Newsletter resource. Source: https://orgo.space/docs/api-reference/newsletter/retrieves-a-newsletter-resource-2 /api-reference/openapi.json get /api/v1/newsletters_gallery/{uuid} Retrieves a Newsletter resource. # Retrieves a Newsletter resource. Source: https://orgo.space/docs/api-reference/newsletter/retrieves-a-newsletter-resource-3 /api-reference/openapi.json get /api/v1/newsletters_public/{uuid} Retrieves a Newsletter resource. # Retrieves the collection of Newsletter resources. Source: https://orgo.space/docs/api-reference/newsletter/retrieves-the-collection-of-newsletter-resources /api-reference/openapi.json get /api/v1/newsletters Retrieves the collection of Newsletter resources. # Retrieves the collection of Newsletter resources. Source: https://orgo.space/docs/api-reference/newsletter/retrieves-the-collection-of-newsletter-resources-1 /api-reference/openapi.json get /api/v1/newsletters_gallery Retrieves the collection of Newsletter resources. # Updates the Newsletter resource. Source: https://orgo.space/docs/api-reference/newsletter/updates-the-newsletter-resource /api-reference/openapi.json patch /api/v1/newsletters/{uuid} Updates the Newsletter resource. # Updates the Newsletter resource. Source: https://orgo.space/docs/api-reference/newsletter/updates-the-newsletter-resource-1 /api-reference/openapi.json patch /api/v1/newsletters/{uuid}/clone Updates the Newsletter resource. # Updates the Newsletter resource. Source: https://orgo.space/docs/api-reference/newsletter/updates-the-newsletter-resource-2 /api-reference/openapi.json patch /api/v1/newsletters/{uuid}/clone-non-openers Updates the Newsletter resource. # Updates the Newsletter resource. Source: https://orgo.space/docs/api-reference/newsletter/updates-the-newsletter-resource-3 /api-reference/openapi.json patch /api/v1/newsletters/{uuid}/publish-go Updates the Newsletter resource. # Updates the Newsletter resource. Source: https://orgo.space/docs/api-reference/newsletter/updates-the-newsletter-resource-4 /api-reference/openapi.json patch /api/v1/newsletters/{uuid}/schedule Updates the Newsletter resource. # Updates the Newsletter resource. Source: https://orgo.space/docs/api-reference/newsletter/updates-the-newsletter-resource-5 /api-reference/openapi.json patch /api/v1/newsletters/{uuid}/send Updates the Newsletter resource. # Creates a NewsletterTemplate resource. Source: https://orgo.space/docs/api-reference/newslettertemplate/creates-a-newslettertemplate-resource /api-reference/openapi.json post /api/v1/newsletter_templates Creates a NewsletterTemplate resource. # Removes the NewsletterTemplate resource. Source: https://orgo.space/docs/api-reference/newslettertemplate/removes-the-newslettertemplate-resource /api-reference/openapi.json delete /api/v1/newsletter_templates/{id} Removes the NewsletterTemplate resource. # Retrieves a NewsletterTemplate resource. Source: https://orgo.space/docs/api-reference/newslettertemplate/retrieves-a-newslettertemplate-resource /api-reference/openapi.json get /api/v1/newsletter_templates/{id} Retrieves a NewsletterTemplate resource. # Retrieves the collection of NewsletterTemplate resources. Source: https://orgo.space/docs/api-reference/newslettertemplate/retrieves-the-collection-of-newslettertemplate-resources /api-reference/openapi.json get /api/v1/newsletter_templates Retrieves the collection of NewsletterTemplate resources. # Updates the NewsletterTemplate resource. Source: https://orgo.space/docs/api-reference/newslettertemplate/updates-the-newslettertemplate-resource /api-reference/openapi.json patch /api/v1/newsletter_template/{id}/send Updates the NewsletterTemplate resource. # Updates the NewsletterTemplate resource. Source: https://orgo.space/docs/api-reference/newslettertemplate/updates-the-newslettertemplate-resource-1 /api-reference/openapi.json patch /api/v1/newsletter_templates/{id} Updates the NewsletterTemplate resource. # Create an objective Source: https://orgo.space/docs/api-reference/objective/create-an-objective /api-reference/openapi.json post /api/v1/objectives Creates a new objective within a project. Requires PROJECT_ACCESS on the target project. Automatically assigns the project tenant and sets position to the next available value if not provided. # Delete an objective Source: https://orgo.space/docs/api-reference/objective/delete-an-objective /api-reference/openapi.json delete /api/v1/objectives/{uuid} Permanently removes an objective. Requires PROJECT_EDIT permission on the parent project (stricter than read/update access). # Get an objective Source: https://orgo.space/docs/api-reference/objective/get-an-objective /api-reference/openapi.json get /api/v1/objectives/{uuid} Returns a single objective. Requires PROJECT_ACCESS permission on the parent project. # List objectives Source: https://orgo.space/docs/api-reference/objective/list-objectives /api-reference/openapi.json get /api/v1/objectives Returns objectives ordered by position (ASC). Filtered by tenant automatically via Doctrine extensions. # Update an objective Source: https://orgo.space/docs/api-reference/objective/update-an-objective /api-reference/openapi.json patch /api/v1/objectives/{uuid} Updates an existing objective. Requires PROJECT_ACCESS on the parent project. Validates the objective still belongs to a valid project. # Create an official gazette entry Source: https://orgo.space/docs/api-reference/officialgazette/create-an-official-gazette-entry /api-reference/openapi.json post /api/v1/official_gazettes Creates a new official gazette entry (decision, announcement, resolution). Requires HR_TENANT permission. # Delete an official gazette entry Source: https://orgo.space/docs/api-reference/officialgazette/delete-an-official-gazette-entry /api-reference/openapi.json delete /api/v1/official_gazettes/{id} Permanently removes an official gazette entry. Requires HR_TENANT permission on the entry. # Get an official gazette entry Source: https://orgo.space/docs/api-reference/officialgazette/get-an-official-gazette-entry /api-reference/openapi.json get /api/v1/official_gazettes/{id} Returns a single official gazette entry by ID. Official gazettes are formal organizational documents (decisions, announcements, resolutions). # List official gazette entries Source: https://orgo.space/docs/api-reference/officialgazette/list-official-gazette-entries /api-reference/openapi.json get /api/v1/official_gazettes Returns official gazette entries ordered by documentDate (DESC) then by ID (DESC). Filtered by tenant automatically. # Update an official gazette entry Source: https://orgo.space/docs/api-reference/officialgazette/update-an-official-gazette-entry /api-reference/openapi.json patch /api/v1/official_gazettes/{id} Updates an existing official gazette entry. Requires HR_TENANT permission on the entry. # Get an official gazette type Source: https://orgo.space/docs/api-reference/officialgazettetype/get-an-official-gazette-type /api-reference/openapi.json get /api/v1/official_gazette_types/{id} Returns a single official gazette type by ID. Read-only reference data. # List official gazette types Source: https://orgo.space/docs/api-reference/officialgazettetype/list-official-gazette-types /api-reference/openapi.json get /api/v1/official_gazette_types Returns all available official gazette types (e.g. decision, announcement, resolution). Read-only reference data. # Create a discussion post Source: https://orgo.space/docs/api-reference/post/create-a-discussion-post /api-reference/openapi.json post /api/v1/posts Creates a new comment on a discussion. Requires the discussion ID in the request body. Sanitizes HTML content, processes media attachments and @mentions (up to 50), sends notifications to mentioned users and discussion followers via async message queue, and auto-follows the discussion for the commenter. # Delete a discussion post Source: https://orgo.space/docs/api-reference/post/delete-a-discussion-post /api-reference/openapi.json delete /api/v1/posts/{id} Deletes a discussion comment. Only the post owner or a tenant admin can delete. If the post has visible replies, it is soft-deleted (content cleared but structure preserved). Admin deletions of other users posts are logged for audit purposes. # Delete a post reply Source: https://orgo.space/docs/api-reference/post/delete-a-post-reply /api-reference/openapi.json delete /api/v1/posts/{id}/reply Deletes a reply to a comment. Requires COMMUNICATION_TENANT permission or ownership of the reply. If the reply has visible children, it is soft-deleted to preserve thread structure. Otherwise, the reply is hard-deleted and the parent comment children count is decremented. Admin deletions are logged. # Get a discussion post Source: https://orgo.space/docs/api-reference/post/get-a-discussion-post /api-reference/openapi.json get /api/v1/posts/{id} Retrieves a single post by ID, including its content, owner, media attachments, mentions, reactions summary, and moderation status. # Get reactions for a post Source: https://orgo.space/docs/api-reference/post/get-reactions-for-a-post /api-reference/openapi.json get /api/v1/posts/get_reactions_list/{id} Returns all reactions on a post, grouped by reaction type ID. Each group contains an array of users (name, ID, logo) who reacted with that type. Validates that the current user belongs to the same tenant and has access to the discussion unit. # List discussion posts Source: https://orgo.space/docs/api-reference/post/list-discussion-posts /api-reference/openapi.json get /api/v1/posts Returns a paginated list of posts for a discussion, ordered by date created ascending. Requires a filter parameter: either discussion (ID), parent (post ID for replies), or owner (user ID, must match current user). Enriches each post with the current user reaction data. # List discussion posts (legacy) Source: https://orgo.space/docs/api-reference/post/list-discussion-posts-legacy /api-reference/openapi.json get /api/v1/post_discussions Legacy endpoint for listing discussion posts, maintained for mobile app backward compatibility. Uses post_discussion_read serialization group. Prefer the standard /posts collection endpoint for new integrations. # Moderate a discussion post Source: https://orgo.space/docs/api-reference/post/moderate-a-discussion-post /api-reference/openapi.json patch /api/v1/posts/{id}/moderate Hides a post from public view by marking it as moderated. Requires COMMUNICATION_LOCAL permission on the discussion. Decrements the discussion posts count, creates a moderation log entry with the original content, and links the log to the post. Fails if the post is already moderated. # Moderate a post reply Source: https://orgo.space/docs/api-reference/post/moderate-a-post-reply /api-reference/openapi.json patch /api/v1/posts/{id}/moderate-reply Hides a reply from public view by marking it as moderated. Requires COMMUNICATION_LOCAL permission on the discussion. Decrements the parent comment visible children count and creates a moderation log entry. Fails if the reply is already moderated. # Remove moderation from a post Source: https://orgo.space/docs/api-reference/post/remove-moderation-from-a-post /api-reference/openapi.json patch /api/v1/posts/{id}/moderate-remove Restores a previously moderated post to public visibility. Requires COMMUNICATION_LOCAL permission on the discussion. Increments the discussion posts count back and creates an unmoderation log entry. Fails if the post is not currently moderated. # Remove moderation from a reply Source: https://orgo.space/docs/api-reference/post/remove-moderation-from-a-reply /api-reference/openapi.json patch /api/v1/posts/{id}/moderate-remove-reply Restores a previously moderated reply to public visibility. Requires COMMUNICATION_LOCAL permission on the discussion. Increments the parent comment visible children count and creates an unmoderation log entry. Fails if the reply is not currently moderated. # Reply to a discussion post Source: https://orgo.space/docs/api-reference/post/reply-to-a-discussion-post /api-reference/openapi.json post /api/v1/post-reply Creates a nested reply to an existing comment. Requires the parent post ID in the request body. Validates tenant isolation and unit access, processes media attachments and @mentions (up to 50), and sends a notification to the parent comment owner (unless replying to own comment). # Report a discussion post Source: https://orgo.space/docs/api-reference/post/report-a-discussion-post /api-reference/openapi.json patch /api/v1/posts/{id}/report Flags a post as inappropriate by creating a PostReport record linked to the current user. Each user can only report a given post once; duplicate reports return a 400 error. # Update a discussion post Source: https://orgo.space/docs/api-reference/post/update-a-discussion-post /api-reference/openapi.json patch /api/v1/posts/{id} Updates an existing post. Only the post owner can edit it. Handles mention updates by comparing existing and new mentions, and sends notifications only to newly mentioned users. Supports updating content and media attachments. # Create a product Source: https://orgo.space/docs/api-reference/product/create-a-product /api-reference/openapi.json post /api/v1/products Creates a new product and syncs it to Stripe. Automatically generates slug, slugGo, and slugEnGo identifiers. For fee-type products, sets the local center default fee product if not already configured. For donation-type products, registers as the tenant default donation product if none exists. For manual invoice products, configures internal invoice settings. Requires FINANCIAL_TENANT or FINANCIAL_LOCAL permission. # Delete a product Source: https://orgo.space/docs/api-reference/product/delete-a-product /api-reference/openapi.json delete /api/v1/products/{uuid} Deletes a product if it has no existing payments. If the product has a Stripe product ID, archives it in Stripe. Returns 400 if any payment is linked to this product. Requires FINANCIAL_TENANT or FINANCIAL_LOCAL permission. # Get a product Source: https://orgo.space/docs/api-reference/product/get-a-product /api-reference/openapi.json get /api/v1/products/{uuid} Retrieves a single product by UUID. For fee-type products, filters out hidden prices and prices outside their valid date range for non-HR users. HR_TENANT users see all prices regardless of visibility or date validity. # Get payment page comments Source: https://orgo.space/docs/api-reference/product/get-payment-page-comments /api-reference/openapi.json get /api/v1/get-payment-page-comments/{uuid} Returns paginated donor comments for a donation product public page. Supports page query parameter (30 comments per page). Donor names are anonymized to first name and last initial for public entries, or shown as "anonymous" for non-public ones. Requires the product commentSection setting to be enabled. # Get payment page info Source: https://orgo.space/docs/api-reference/product/get-payment-page-info /api-reference/openapi.json get /api/v1/get-payment-page-info/{uuid} Returns public donation page statistics including comment count, top payments (with anonymized donor names), recent donation activity from the last 20% timeframe, and top recurring payment. Only available for donation-type products with commentSection or newestAndTopDonationSection settings enabled. # Get payment page payments Source: https://orgo.space/docs/api-reference/product/get-payment-page-payments /api-reference/openapi.json get /api/v1/get-payment-page-payments/{uuid} Returns paginated latest payments for a donation product public page. Supports page query parameter (50 payments per page). Donor names are anonymized to first name and last initial, or shown as "anonymous" for non-public entries. Requires the product newestAndTopDonationSection setting to be enabled. # Get product by slug Source: https://orgo.space/docs/api-reference/product/get-product-by-slug /api-reference/openapi.json get /api/v1/product_by_slug Looks up a product by its slug and tenant slug. Requires query parameters: slug (product slug) and tenant (tenant slug). Returns the product with product_read serialization group. Used for public-facing product pages. # Get public product details Source: https://orgo.space/docs/api-reference/product/get-public-product-details /api-reference/openapi.json get /api/v1/product/public/{uuid} Returns product details via the public endpoint (no authentication required for external products). For fee-type products, filters out hidden prices and prices outside their valid date range for non-HR users. Response includes tenant-specific cache headers. # Get tenant fee product Source: https://orgo.space/docs/api-reference/product/get-tenant-fee-product /api-reference/openapi.json get /api/v1/tenant_fee_product/{uuid} Retrieves the tenant-level fee (membership) product by UUID. Filters out hidden product prices for non-HR users, so regular members only see prices they are eligible to select. # List my products Source: https://orgo.space/docs/api-reference/product/list-my-products /api-reference/openapi.json get /api/v1/my-products Returns products available to the authenticated user based on their permissions and local center membership. Supports filters: exists[localCenter], exists[organisation], exists[isArchived], exists[hasLocalCenterOption], type, and excludeType. Fee product visibility is restricted by online payment eligibility settings, and hidden prices are filtered for non-HR users. # List showcased products Source: https://orgo.space/docs/api-reference/product/list-showcased-products /api-reference/openapi.json get /api/v1/get-showcased-products Returns products marked as showcased for the authenticated user, filtered by their roles and local center. Also includes products the user has active subscriptions to. Results are deduplicated by product ID. # Publish a product Source: https://orgo.space/docs/api-reference/product/publish-a-product /api-reference/openapi.json patch /api/v1/product-go-publish/{uuid} Publishes a product landing page via the GoPublisher service, uploading the product folder to the static hosting platform. Accepts an optional isEn flag in the request body to generate an English version. Requires FINANCIAL_TENANT or FINANCIAL_LOCAL permission. # Update a product Source: https://orgo.space/docs/api-reference/product/update-a-product /api-reference/openapi.json patch /api/v1/products/{uuid} Updates product fields and syncs changes to Stripe. If the Stripe product ID is stale, clears it and re-creates the Stripe product. Republishes the Go landing page if a slugGo exists. Non-HR users are automatically scoped to their local center. Requires FINANCIAL_TENANT or FINANCIAL_LOCAL permission. # Update product without Stripe sync Source: https://orgo.space/docs/api-reference/product/update-product-without-stripe-sync /api-reference/openapi.json patch /api/v1/products/{uuid}/stripeless Updates product fields without triggering Stripe synchronization. Useful for updating metadata or non-financial fields that do not affect the Stripe product configuration. Non-HR users are automatically scoped to their local center. Requires FINANCIAL_TENANT or FINANCIAL_LOCAL permission. # Create a product option Source: https://orgo.space/docs/api-reference/productoption/create-a-product-option /api-reference/openapi.json post /api/v1/product_options Creates a new option for a product (e.g. payment plan, duration variant). Requires FINANCIAL_TENANT permission. Validates access rights on the parent product. # Delete a product option Source: https://orgo.space/docs/api-reference/productoption/delete-a-product-option /api-reference/openapi.json delete /api/v1/product_options/{id} Permanently removes a product option. Requires FINANCIAL_TENANT permission. Fails if any ProductPayment or SubscriptionProfile records reference this option, to prevent orphaned payment data. # Get a product option Source: https://orgo.space/docs/api-reference/productoption/get-a-product-option /api-reference/openapi.json get /api/v1/product_options/{id} Returns a single product option by ID. # Update a product option Source: https://orgo.space/docs/api-reference/productoption/update-a-product-option /api-reference/openapi.json patch /api/v1/product_options/{id} Updates an existing product option. Requires FINANCIAL_TENANT permission. Validates access rights on the parent product. # Accept a payment Source: https://orgo.space/docs/api-reference/productpayment/accept-a-payment /api-reference/openapi.json patch /api/v1/product-payment/{id}/accept Captures a held Stripe payment intent, completing the charge. Requires the payer to have a validated identity before acceptance. Sets the payment status to success and records the accepting user and date. Requires FINANCIAL_LOCAL permission. # Approve payment comment Source: https://orgo.space/docs/api-reference/productpayment/approve-payment-comment /api-reference/openapi.json patch /api/v1/product-payment/{id}/accept-comment Approves a user-submitted comment on a donation payment, making it visible on the public donation page. Only applies to donation-type products with a non-empty comment. Requires FINANCIAL_LOCAL permission. # Cancel a payment Source: https://orgo.space/docs/api-reference/productpayment/cancel-a-payment /api-reference/openapi.json patch /api/v1/product-payment/{id}/cancel Cancels a payment that is in pending_accept status via Stripe payment intent cancellation. The payment must not yet be captured. Sets the status to refunded and records the accepting user and date. Requires FINANCIAL_LOCAL permission. # Download payment proof PDF Source: https://orgo.space/docs/api-reference/productpayment/download-payment-proof-pdf /api-reference/openapi.json get /api/v1/product-payment/{id}/proof Generates and downloads a PDF proof document for the payment. Requires the payer to have a validated identity with uploaded ID document. The PDF is populated from the tenant HTML template with placeholders for name, address, ID details, amounts, payment dates, validator signature, and Stripe/Orgo payment IDs. Requires FINANCIAL_LOCAL permission or payment ownership. # Generate invoice for payment Source: https://orgo.space/docs/api-reference/productpayment/generate-invoice-for-payment /api-reference/openapi.json patch /api/v1/product-payment/{id}/generate-invoice Generates an invoice for a successful event registration payment. Creates an Invoice entity with billing details pre-filled from the payer (user or contact), auto-generates invoice number and series, applies the default invoice template, and links the invoice to the payment. Only works for payments with status "success" that have associated event registrations and no existing invoice. Requires ADMIN_TENANT permission. # Get a product payment Source: https://orgo.space/docs/api-reference/productpayment/get-a-product-payment /api-reference/openapi.json get /api/v1/product_payments/{id} Retrieves a single product payment by ID. Accessible by the payment owner or users with FINANCIAL_LOCAL permission for the payment local center. # List product payments Source: https://orgo.space/docs/api-reference/productpayment/list-product-payments /api-reference/openapi.json get /api/v1/product_payments Returns a paginated list of product payments. Collection security is enforced via SecureSearchCollectionFilter and Doctrine extensions based on the user role. Regular users see only their own payments; FINANCIAL_LOCAL users see payments for their local center. Response is intentionally lean — call `GET /product_payments/{id}` for full payment details. # Refund a payment Source: https://orgo.space/docs/api-reference/productpayment/refund-a-payment /api-reference/openapi.json patch /api/v1/product-payment/{id}/refund Processes a full refund through Stripe for a successful payment. Side effects: sets payment status to refunded, cancels any linked event registrations (releasing ticket capacity and decrementing sold counts), and recalculates fee validity dates for membership products. Only payments with status "success" can be refunded. Requires FINANCIAL_LOCAL permission. # Reject payment comment Source: https://orgo.space/docs/api-reference/productpayment/reject-payment-comment /api-reference/openapi.json patch /api/v1/product-payment/{id}/reject-comment Rejects a user-submitted comment on a donation payment, preventing it from appearing on the public donation page. Only applies to donation-type products with a non-empty comment. Requires FINANCIAL_LOCAL permission. # Create a product price Source: https://orgo.space/docs/api-reference/productprice/create-a-product-price /api-reference/openapi.json post /api/v1/product_prices Creates a new price tier for a product and syncs it to Stripe if a connected Stripe account exists. For event products, validates that ticket dates fall within the event timeframe. For fee products, supports version chaining via previousVersion field, which automatically sets validTo on the previous version. For bundle prices, auto-creates a hidden zero-price variant for bundle members. Requires FINANCIAL_TENANT or FINANCIAL_LOCAL permission. # Delete a product price Source: https://orgo.space/docs/api-reference/productprice/delete-a-product-price /api-reference/openapi.json delete /api/v1/product_prices/{id} Deletes a product price if no payments are attached to it. If the price has a Stripe price ID, archives it in Stripe (skipped for demo tenants). Returns 400 if any payment references this price. Requires FINANCIAL_TENANT or FINANCIAL_LOCAL permission. # Get a product price Source: https://orgo.space/docs/api-reference/productprice/get-a-product-price /api-reference/openapi.json get /api/v1/product_prices/{id} Retrieves a single product price by ID. Returns price details including amount, currency, validity dates, and Stripe price ID. # Get public product price Source: https://orgo.space/docs/api-reference/productprice/get-public-product-price /api-reference/openapi.json get /api/v1/product_prices/public/{id} Retrieves a product price via the public endpoint. Accessible to authenticated users or for default prices (isDefault=true) without authentication. Used for public payment pages and external checkout flows. # Update a product price Source: https://orgo.space/docs/api-reference/productprice/update-a-product-price /api-reference/openapi.json patch /api/v1/product_prices/{id} Updates a product price and syncs changes to Stripe. The price amount cannot be changed if payments already exist for this price tier. The tenant default fee price cannot be set as hidden (admin-assignable only). Lifetime membership prices automatically set the overwrite month period. Creates a Stripe price if the product has a Stripe ID but the price does not. Requires FINANCIAL_TENANT or FINANCIAL_LOCAL permission. # Create a product price addon Source: https://orgo.space/docs/api-reference/productpriceaddon/create-a-product-price-addon /api-reference/openapi.json post /api/v1/product_price_addons Creates a new addon for event ticket prices. Requires EVENT_TENANT permission. At least one ProductPrice must be linked. All linked prices must belong to the same product and tenant. Name is required, price cannot be negative, and maxQuantityPerTicket defaults to 1. Invalidates public event caches for all related events. # Delete a product price addon Source: https://orgo.space/docs/api-reference/productpriceaddon/delete-a-product-price-addon /api-reference/openapi.json delete /api/v1/product_price_addons/{id} Permanently removes a product price addon. Requires EVENT_TENANT permission and tenant ownership. Fails if any purchases (EventAttendAddon) exist for this addon -- archive it instead. Invalidates public event caches for all related events. # Get a product price addon Source: https://orgo.space/docs/api-reference/productpriceaddon/get-a-product-price-addon /api-reference/openapi.json get /api/v1/product_price_addons/{id} Returns a single product price addon by ID. Addons are optional extras attached to event ticket prices (e.g. meals, parking, merchandise). Requires authentication. # List product price addons Source: https://orgo.space/docs/api-reference/productpriceaddon/list-product-price-addons /api-reference/openapi.json get /api/v1/product_price_addons Returns product price addons (up to 100 per page). Requires authentication. # Update a product price addon Source: https://orgo.space/docs/api-reference/productpriceaddon/update-a-product-price-addon /api-reference/openapi.json patch /api/v1/product_price_addons/{id} Updates an existing product price addon. Requires EVENT_TENANT permission and tenant ownership. Name cannot be empty, price cannot be negative, and maxQuantityPerTicket minimum is 1. Invalidates public event caches for all related events. # Get a profession job Source: https://orgo.space/docs/api-reference/professionjob/get-a-profession-job /api-reference/openapi.json get /api/v1/profession_jobs/{id} Retrieves a single profession job by ID, including its name and associated profession industry. # List profession jobs Source: https://orgo.space/docs/api-reference/professionjob/list-profession-jobs /api-reference/openapi.json get /api/v1/profession_jobs Returns all profession jobs ordered alphabetically. Profession jobs represent specific job titles within a profession industry (e.g., "Software Engineer" under "Technology"). Read-only reference data used in user profiles. # Bulk toggle profession statuses Source: https://orgo.space/docs/api-reference/professiontype/bulk-toggle-profession-statuses /api-reference/openapi.json get /api/v1/status_profession_types/bulk_toggle_status/{action}/{type} Enables or disables all professions of a given type in bulk for the current tenant. The "action" path parameter must be "enable" or "disable", and "type" must be "custom" or "default". Processes in batches of 20 for performance. Restricted to tenant administrators. # Create a profession industry Source: https://orgo.space/docs/api-reference/professiontype/create-a-profession-industry /api-reference/openapi.json post /api/v1/profession_types Creates a new profession industry. The tenant is automatically set from the current user context. Custom professions are scoped to the creating tenant. # Delete a profession industry Source: https://orgo.space/docs/api-reference/professiontype/delete-a-profession-industry /api-reference/openapi.json delete /api/v1/profession_types/{id} Permanently deletes a profession industry. Only custom (tenant-owned) professions can be deleted. Tenant isolation is enforced. Restricted to tenant administrators. # Get a profession industry Source: https://orgo.space/docs/api-reference/professiontype/get-a-profession-industry /api-reference/openapi.json get /api/v1/profession_types/{id} Retrieves a single profession industry by ID, including its name and parent hierarchy. # List profession industries Source: https://orgo.space/docs/api-reference/professiontype/list-profession-industries /api-reference/openapi.json get /api/v1/profession_types Returns all profession industries (sectors/fields). Supports "tenantSlug" query parameter to filter by tenant and include per-tenant disabled status. Use "all=true" to include disabled professions. Without a tenantSlug, returns all professions with isDisabled=false. # Toggle profession status Source: https://orgo.space/docs/api-reference/professiontype/toggle-profession-status /api-reference/openapi.json post /api/v1/profession_types/toggle_status Toggles a profession industry enabled/disabled status for the current tenant. Send "professionTypeId" in the request body. If the profession is currently enabled, it becomes disabled (and vice versa). Does not delete the profession; only controls tenant-level visibility. Restricted to tenant administrators. # Update a profession industry Source: https://orgo.space/docs/api-reference/professiontype/update-a-profession-industry /api-reference/openapi.json patch /api/v1/profession_types/{id} Updates a profession industry name or properties. Restricted to tenant administrators. # Create a profile status Source: https://orgo.space/docs/api-reference/profilestatus/create-a-profile-status /api-reference/openapi.json post /api/v1/profile_statuses Creates a new profile status for categorizing member states. Requires HR_TENANT or FINANCIAL_TENANT permission. # Delete a profile status Source: https://orgo.space/docs/api-reference/profilestatus/delete-a-profile-status /api-reference/openapi.json delete /api/v1/profile_statuses/{id} Permanently removes a profile status. Requires HR_TENANT or FINANCIAL_TENANT permission. # Get a profile status Source: https://orgo.space/docs/api-reference/profilestatus/get-a-profile-status /api-reference/openapi.json get /api/v1/profile_statuses/{id} Returns a single profile status by ID. Requires HR_TENANT or FINANCIAL_TENANT permission. # List profile statuses Source: https://orgo.space/docs/api-reference/profilestatus/list-profile-statuses /api-reference/openapi.json get /api/v1/profile_statuses Returns all profile statuses for the current tenant. Profile statuses are tenant-defined labels for member states (e.g. Active, Suspended, Alumni). Filtered by tenant automatically. # Replace a profile status Source: https://orgo.space/docs/api-reference/profilestatus/replace-a-profile-status /api-reference/openapi.json put /api/v1/profile_statuses/{id} Fully replaces a profile status. Requires HR_TENANT or FINANCIAL_TENANT permission. # Update a profile status Source: https://orgo.space/docs/api-reference/profilestatus/update-a-profile-status /api-reference/openapi.json patch /api/v1/profile_statuses/{id} Partially updates a profile status. Requires HR_TENANT or FINANCIAL_TENANT permission. # Create a profile tag Source: https://orgo.space/docs/api-reference/profiletag/create-a-profile-tag /api-reference/openapi.json post /api/v1/profile_tags Creates a new profile tag that can be assigned to users or contacts. Requires HR_TENANT permission. # Delete a profile tag Source: https://orgo.space/docs/api-reference/profiletag/delete-a-profile-tag /api-reference/openapi.json delete /api/v1/profile_tags/{id} Permanently removes a profile tag. Requires HR_TENANT permission. # Get a profile tag Source: https://orgo.space/docs/api-reference/profiletag/get-a-profile-tag /api-reference/openapi.json get /api/v1/profile_tags/{id} Returns a single profile tag by ID. Requires HR_TENANT permission. # List profile tags Source: https://orgo.space/docs/api-reference/profiletag/list-profile-tags /api-reference/openapi.json get /api/v1/profile_tags Returns all profile tags for the current tenant. Profile tags are HR-managed labels that can be attached to user or contact profiles for classification and filtering. Requires HR_TENANT permission. # List profile tags for a contact Source: https://orgo.space/docs/api-reference/profiletag/list-profile-tags-for-a-contact /api-reference/openapi.json get /api/v1/contacts/{id}/profile_tags Returns all profile tags assigned to a specific contact. The contact is identified by ID in the URL path. Requires HR_TENANT permission. # List profile tags for a user Source: https://orgo.space/docs/api-reference/profiletag/list-profile-tags-for-a-user /api-reference/openapi.json get /api/v1/users/{id}/profile_tags Returns all profile tags assigned to a specific user. The user is identified by ID in the URL path. Requires HR_TENANT permission. # Update a profile tag Source: https://orgo.space/docs/api-reference/profiletag/update-a-profile-tag /api-reference/openapi.json patch /api/v1/profile_tags/{id} Updates an existing profile tag. Requires HR_TENANT permission. # Add a project member Source: https://orgo.space/docs/api-reference/project/add-a-project-member /api-reference/openapi.json post /api/v1/projects/{uuid}/members Adds a user as a member of the project. Pass userId in the request body. Prevents duplicate memberships. The user must belong to the same tenant. Requires PROJECT_EDIT permission. # Create a project Source: https://orgo.space/docs/api-reference/project/create-a-project /api-reference/openapi.json post /api/v1/projects Creates a new project and automatically generates three default task statuses (To do, In Progress, Done). The current user is set as the owner if not explicitly specified. # Delete a project Source: https://orgo.space/docs/api-reference/project/delete-a-project /api-reference/openapi.json delete /api/v1/projects/{uuid} Permanently deletes a project and all associated tasks, objectives, goals, and statuses. Requires PROJECT_EDIT permission (project owner or tenant admin). # Get a project Source: https://orgo.space/docs/api-reference/project/get-a-project /api-reference/openapi.json get /api/v1/projects/{uuid} Retrieves a single project by its identifier. Requires PROJECT_ACCESS permission (owner, member, or group-based access). # List my projects Source: https://orgo.space/docs/api-reference/project/list-my-projects /api-reference/openapi.json get /api/v1/my-projects Returns projects accessible to the current user. Admin/HR users see all tenant projects. Regular users see projects where they are owner, member, or have group-based access. Ordered by name ascending. # List project members Source: https://orgo.space/docs/api-reference/project/list-project-members /api-reference/openapi.json get /api/v1/projects/{uuid}/members Returns all members of a project ordered by date added (newest first). Requires PROJECT_ACCESS permission on the project. # List projects Source: https://orgo.space/docs/api-reference/project/list-projects /api-reference/openapi.json get /api/v1/projects Returns all projects the current user has access to within their tenant. Filtered automatically by tenant isolation via Doctrine extensions. # Remove a project member Source: https://orgo.space/docs/api-reference/project/remove-a-project-member /api-reference/openapi.json delete /api/v1/projects/{uuid}/members/{userId} Removes a user from the project membership list. The userId is specified in the URL path. Requires PROJECT_EDIT permission on the project. # Update a project Source: https://orgo.space/docs/api-reference/project/update-a-project /api-reference/openapi.json patch /api/v1/projects/{uuid} Updates project properties such as name, description, and status. Requires PROJECT_ACCESS permission. # Create a quiz answer Source: https://orgo.space/docs/api-reference/quizanswer/create-a-quiz-answer /api-reference/openapi.json post /api/v1/quiz_answers Creates a new answer option for a quiz question. Set the question reference, answer text, correctness flag, and position. Multiple answers can be marked as correct for multiple-choice questions. Requires HR_TENANT permission. # Delete a quiz answer Source: https://orgo.space/docs/api-reference/quizanswer/delete-a-quiz-answer /api-reference/openapi.json delete /api/v1/quiz_answers/{uuid} Permanently removes an answer option from a quiz question. Requires HR_TENANT permission. # Get a quiz answer Source: https://orgo.space/docs/api-reference/quizanswer/get-a-quiz-answer /api-reference/openapi.json get /api/v1/quiz_answers/{uuid} Returns a single quiz answer option with its text, correctness flag, and position within the question. # List quiz answers Source: https://orgo.space/docs/api-reference/quizanswer/list-quiz-answers /api-reference/openapi.json get /api/v1/quiz_answers Returns all quiz answer options. Filter by question to get answers for a specific quiz question. # Update a quiz answer Source: https://orgo.space/docs/api-reference/quizanswer/update-a-quiz-answer /api-reference/openapi.json patch /api/v1/quiz_answers/{uuid} Updates answer text, correctness flag, or position within the question. Requires HR_TENANT permission. # Delete a quiz attempt Source: https://orgo.space/docs/api-reference/quizattempt/delete-a-quiz-attempt /api-reference/openapi.json delete /api/v1/quiz_attempts/{uuid} Permanently removes a quiz attempt record. Access controlled by a custom voter (typically HR_TENANT administrators). # Get a quiz attempt Source: https://orgo.space/docs/api-reference/quizattempt/get-a-quiz-attempt /api-reference/openapi.json get /api/v1/quiz_attempts/{uuid} Returns a single quiz attempt with score, pass/fail status, time spent, and per-question answers. Access controlled by a custom voter (typically the attempt owner or HR_TENANT). # List quiz attempts Source: https://orgo.space/docs/api-reference/quizattempt/list-quiz-attempts /api-reference/openapi.json get /api/v1/quiz_attempts Returns a paginated list of quiz attempts. Filter by quiz and/or user to get attempts for a specific quiz or student. # Start a quiz attempt Source: https://orgo.space/docs/api-reference/quizattempt/start-a-quiz-attempt /api-reference/openapi.json post /api/v1/quiz_attempts Creates and immediately scores a quiz attempt. The user must be enrolled in the course containing the quiz. Automatically calculates the attempt number, computes the score server-side from the submitted answers, and marks the attempt as submitted. Pass the quiz reference and answers map in the request body. # Submit a quiz attempt Source: https://orgo.space/docs/api-reference/quizattempt/submit-a-quiz-attempt /api-reference/openapi.json put /api/v1/quiz_attempts/{uuid} Updates a quiz attempt with final answers. Access controlled by a custom voter (typically the attempt owner). # Create a quiz question Source: https://orgo.space/docs/api-reference/quizquestion/create-a-quiz-question /api-reference/openapi.json post /api/v1/quiz_questions Creates a new question for a quiz. Set the quiz reference, question text, type (single/multiple choice), and position. Answer options are managed separately via the quiz answer endpoints. Requires HR_TENANT permission. # Delete a quiz question Source: https://orgo.space/docs/api-reference/quizquestion/delete-a-quiz-question /api-reference/openapi.json delete /api/v1/quiz_questions/{uuid} Permanently removes a quiz question and its answer options. Existing quiz attempts referencing this question retain their stored answers. Requires HR_TENANT permission. # Get a quiz question Source: https://orgo.space/docs/api-reference/quizquestion/get-a-quiz-question /api-reference/openapi.json get /api/v1/quiz_questions/{uuid} Returns a single quiz question with its text, type, position, and associated answer options including correctness flags. # List quiz questions Source: https://orgo.space/docs/api-reference/quizquestion/list-quiz-questions /api-reference/openapi.json get /api/v1/quiz_questions Returns a paginated list of quiz questions. Filter by quiz to get questions for a specific course quiz. # Update a quiz question Source: https://orgo.space/docs/api-reference/quizquestion/update-a-quiz-question /api-reference/openapi.json patch /api/v1/quiz_questions/{uuid} Updates question text, type, or position within the quiz. Requires HR_TENANT permission. # Build a public event landing page Source: https://orgo.space/docs/api-reference/recipes/build-a-public-event-landing-page Render event details, accept registrations, and show capacity — all via public, no-auth endpoints This walkthrough builds a custom public event page (your own marketing site, an embedded widget on a partner site, a printable poster) that reads from Orgo without requiring visitors to log in. It uses only public endpoints — no Api-Token, no JWT. Who is this for: marketing teams that own a custom landing page outside Orgo's stock event-page template, partner organizations that want to embed Orgo events on their site, or event-aggregator integrations. *** ## What's public, what's not | Operation | Public? | | --------------------------------- | ----------------------------------------------------------------------- | | Read event details | Yes — `GET /api/v1/get_public_event_anonymous/{uuid}` | | List events for a tenant | Yes — `GET /api/v1/public_events` | | Check ticket availability | Yes — `GET /api/v1/events/{uuid}/availability` | | Hold tickets (cart) | Yes — `POST /api/v1/events/{uuid}/ticket-holds` | | Save attendees + complete payment | Yes — `POST /api/v1/public/event/{uuid}/save-attendees` and `/complete` | | Send invites by email | No — requires HR\_LOCAL | | Manually confirm attendance | No — requires admin | Anything visitor-facing is in the public set. Anything that mutates the event itself requires auth. *** ## Prerequisites The event must be: * `status: PUBLISHED` * `isPublic: true` Anonymous reads return `404` for draft or non-public events. This is intentional — the public surface only exposes what the admin has chosen to share. *** ## Step 1 — Fetch event details ```bash theme={null} curl https://acme.orgo.space/api/v1/get_public_event_anonymous/01938d8e-9c4f-7c2a-b8e1-3f7a9b8c4f12 ``` Response: ```json theme={null} { "id": 12, "uuid": "01938d8e-9c4f-7c2a-b8e1-3f7a9b8c4f12", "name": "Annual General Meeting 2026", "slug": "annual-general-meeting-2026", "description": "Quarterly chapter meeting open to all members.", "dateTimeBegin": "2026-03-15T18:00:00+00:00", "dateTimeEnd": "2026-03-15T21:00:00+00:00", "location": "Boston Public Library, 700 Boylston St, Boston, MA 02116", "cover": "https://cdn.orgo.space/events/12/cover.jpg", "attendeeCount": 87, "maxCapacity": 200, "isPublic": true, "hasEventTicketing": true, "products": [ { "uuid": "01938d8e-c2f4-7c2a-b8e1-3f7a9b8c4f99", "name": "General Admission", "customMinPrice": 2500 } ] } ``` `attendeeCount` and `maxCapacity` are the inputs for rendering a "87 of 200 seats taken" indicator. Everything else is straightforward — render as you like. *** ## Step 2 — Check live availability `attendeeCount` from Step 1 is correct at fetch time, but stale within seconds on busy events. For real-time availability: ```bash theme={null} curl https://acme.orgo.space/api/v1/events/01938d8e-9c4f-7c2a-b8e1-3f7a9b8c4f12/availability ``` ```json theme={null} { "availableTickets": 113, "totalCapacity": 200, "soldOut": false } ``` Call this on render and whenever the page is brought back into focus. For sold-out events, show "join waitlist" instead of the registration form (see [WaitlistEntry](/docs/api-reference/waitlistentry)). *** ## Step 3 — Hold tickets while the buyer fills the form For paid events, hold tickets the moment the buyer starts filling the form — otherwise two people could submit checkout at the same time and only one's payment succeeds. ```bash theme={null} curl -X POST https://acme.orgo.space/api/v1/events/01938d8e-9c4f-7c2a-b8e1-3f7a9b8c4f12/ticket-holds \ -H "Content-Type: application/json" \ -d '{ "quantity": 2, "productPrice": "/api/v1/product_prices/22" }' ``` Response: ```json theme={null} { "holdId": "th_a3f8b2c4d6e8f1a3", "quantity": 2, "expiresAt": "2026-03-15T18:15:00+00:00" } ``` Holds expire after 15 minutes. If the buyer abandons the form, the hold releases automatically and the seats are returned to the pool. You can release explicitly: ```bash theme={null} curl -X PATCH https://acme.orgo.space/api/v1/ticket-holds/th_a3f8b2c4d6e8f1a3/release \ -H "Content-Type: application/json" \ -d '{}' ``` *** ## Step 4 — Save attendee details Once the buyer fills in the form (name, email, ticket-type selection), submit: ```bash theme={null} curl -X POST https://acme.orgo.space/api/v1/public/event/01938d8e-9c4f-7c2a-b8e1-3f7a9b8c4f12/save-attendees \ -H "Content-Type: application/json" \ -d '{ "holdId": "th_a3f8b2c4d6e8f1a3", "attendees": [ { "firstName": "Olivia", "lastName": "Brown", "email": "olivia.brown@example.com", "productPrice": "/api/v1/product_prices/22" }, { "firstName": "Daniel", "lastName": "Kowalski", "email": "daniel.kowalski@example.com", "productPrice": "/api/v1/product_prices/22" } ] }' ``` For free events, you can skip the hold step entirely and call `save-attendees` directly — the seat reservation happens here in one shot. *** ## Step 5 — Take payment (paid events only) The save-attendees response includes a Stripe checkout URL. Redirect the buyer: ```json theme={null} { "attendeeIds": [1042, 1043], "checkoutUrl": "https://checkout.stripe.com/c/pay/cs_test_..." } ``` For free events, save-attendees completes the registration immediately — no checkout step. Each attendee gets a QR code by email. For paid events, Stripe redirects back to your `success_url` configured on the checkout session (or Orgo's default attendee-confirmation page). At that point the `ProductPayment` is `SUCCESS` and you can finalize: ```bash theme={null} curl -X POST https://acme.orgo.space/api/v1/public/event/01938d8e-9c4f-7c2a-b8e1-3f7a9b8c4f12/complete \ -H "Content-Type: application/json" \ -d '{"sessionId": "cs_test_..."}' ``` The complete call cross-checks the Stripe session, confirms attendance, sends the confirmation email + QR code, and returns the attendee IDs. *** ## Step 6 — Show "thanks for registering" with the QR After completion, fetch the attendee record to render the QR code (or the email contains a deep link to a public view): ```bash theme={null} curl https://acme.orgo.space/api/v1/public/event-attend/{attendHash}/agenda ``` The hash is unique per attendee and is in the confirmation email link. Show this on a "your ticket" page they can save or screenshot. *** ## Showing capacity and time-zone correctly `dateTimeBegin` and `dateTimeEnd` are ISO 8601 timestamps in UTC. The event also includes `timezone` (an IANA name like `America/New_York`). Render the date in the event's timezone (it's an in-person event), not the visitor's: ```javascript theme={null} const formatter = new Intl.DateTimeFormat("en-US", { timeZone: event.timezone, dateStyle: "full", timeStyle: "short", timeZoneName: "short", }); formatter.format(new Date(event.dateTimeBegin)); // "Sunday, March 15, 2026 at 6:00 PM EST" ``` *** ## Adding to-calendar buttons Build .ics manually from the public event data. Don't link to a hosted Orgo .ics — there's no public endpoint for it; visitors building their own client are expected to generate locally: ```ics theme={null} BEGIN:VCALENDAR VERSION:2.0 BEGIN:VEVENT UID:{uuid}@orgo.space DTSTART:20260315T180000Z DTEND:20260315T210000Z SUMMARY:Annual General Meeting 2026 LOCATION:Boston Public Library, 700 Boylston St, Boston, MA 02116 DESCRIPTION:Quarterly chapter meeting... URL:https://acme.orgo.space/events/annual-general-meeting-2026 END:VEVENT END:VCALENDAR ``` *** ## Common gotchas Cache the event details (Step 1) for \~5 minutes. Never cache `availability` (Step 2) — call it fresh on every render. The capacity number can change second-to-second. Browser JS pop-up blockers can swallow the `window.location` redirect to Stripe. Use a server-side redirect (302) instead of client-side `window.location = checkoutUrl`. Or use a regular `` link styled as a button. For paid events, attendance is `PENDING` until payment completes via `/complete`. The admin UI hides pending until they pay (or filters them under "abandoned carts"). Wait for the `event_attend.updated` webhook with `status: NEW` to know the registration is confirmed. Each attendee gets a magic-link in their confirmation email. The link uses `X-Contact-Hash` auth (see [Authentication](/docs/api-reference/concepts/authentication)) and gives access to the attendee's own record only. Build a public page that consumes those endpoints if you want a self-service "update my details" surface. *** ## What to do next * [Create and sell event tickets](/docs/api-reference/recipes/create-and-sell-event-tickets) — the admin-side setup that produced this event * [Process payments](/docs/api-reference/recipes/process-payments) — payment reconciliation after Stripe completes * [Handle webhooks](/docs/api-reference/recipes/handle-webhooks) — react to new registrations server-side # Create and sell event tickets Source: https://orgo.space/docs/api-reference/recipes/create-and-sell-event-tickets From draft event to ticketed registration with Stripe checkout — five endpoints This walkthrough creates a ticketed event, attaches paid ticket types via Stripe, publishes the landing page, and processes a registration. The full chain covers the [Event](/docs/api-reference/event), [Product](/docs/api-reference/product), and [EventAttend](/docs/api-reference/eventattend) resources. Who is this for: integrations that need to provision events programmatically (recurring training, partner-organized meetups, automated festival setup) or surface Orgo's ticketing into a custom site. *** ## Prerequisites * Stripe connected at the tenant or local-center level (see [Stripe integration](/docs/platform/fees/stripe-integration)). * An admin Api-Token with at least `HR_LOCAL` on the relevant local center. *** ## Step 1 — Create the event as a draft Drafts are invisible to members and the public. You can edit freely while in `DRAFT`. ```bash theme={null} curl -X POST https://acme.orgo.space/api/v1/events \ -H "Api-Token: $ORGO_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "name": "Annual General Meeting 2026", "description": "Quarterly chapter meeting with working-group breakouts and a board Q&A.", "dateTimeBegin": "2026-03-15T18:00:00+00:00", "dateTimeEnd": "2026-03-15T21:00:00+00:00", "timezone": "America/New_York", "location": "Boston Public Library, 700 Boylston St, Boston, MA 02116", "unit": "/api/v1/units/4", "isPublic": true, "maxCapacity": 200, "hasEventTicketing": true, "requiresRegistrationForm": true, "status": "DRAFT" }' ``` The response carries both an integer `id` (used in legacy paths) and a `uuid` (used in modern paths like `/api/v1/events/{uuid}`). Keep the `uuid` for the rest of the flow. ```json theme={null} { "id": 12, "uuid": "01938d8e-9c4f-7c2a-b8e1-3f7a9b8c4f12", "name": "Annual General Meeting 2026", "status": "DRAFT", "slug": "annual-general-meeting-2026", "hasEventTicketing": true } ``` *** ## Step 2 — Create ticket-type products A "ticket type" in Orgo is a `Product` attached to the event. Create one per pricing tier (general admission, member, early-bird, etc). ```bash theme={null} curl -X POST https://acme.orgo.space/api/v1/products \ -H "Api-Token: $ORGO_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "name": "AGM 2026 — General Admission", "description": "Standard ticket for the Annual General Meeting.", "isFee": false, "isExternal": false, "hasOneTimePayment": true, "customMinPrice": 2500, "hasCustomPriceValue": false, "event": "/api/v1/events/01938d8e-9c4f-7c2a-b8e1-3f7a9b8c4f12" }' ``` `customMinPrice` is in cents — `2500` is `$25.00`. Set `hasCustomPriceValue: true` if you want to allow attendees to pay more than the minimum (pay-what-you-want with a floor). Repeat for each ticket type. Each gets its own `uuid` and one `ProductPrice` record. *** ## Step 3 — Publish the event Publishing flips the event from `DRAFT` to `PUBLISHED` and makes the landing page reachable at `https://acme.orgo.space/events/{slug}`. ```bash theme={null} curl -X PATCH https://acme.orgo.space/api/v1/events_publish/01938d8e-9c4f-7c2a-b8e1-3f7a9b8c4f12 \ -H "Api-Token: $ORGO_API_TOKEN" \ -H "Content-Type: application/merge-patch+json" \ -d '{}' ``` After publishing, public callers can fetch the event via `GET /api/v1/get_public_event_anonymous/{uuid}` — no auth required. Two publish endpoints exist: `/api/v1/events_publish/{uuid}` (the standard publish — flips status and notifies invitees if configured) and `/api/v1/event-go-publish/{uuid}` (used by the "Go" landing-page editor). Use the first one from server-to-server integrations. *** ## Step 4 — Register an attendee Two paths: existing User or an external Contact. ### Path A — existing User ```bash theme={null} curl -X POST https://acme.orgo.space/api/v1/event_attends \ -H "Api-Token: $ORGO_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "event": "/api/v1/events/01938d8e-9c4f-7c2a-b8e1-3f7a9b8c4f12", "user": "/api/v1/users/42", "status": "NEW" }' ``` Response includes the registration ID and a QR code (base64) that doubles as the check-in token. ### Path B — external attendee (non-member) For non-Users, invite them by email — Orgo creates a `Contact` for them on confirmation: ```bash theme={null} curl -X POST https://acme.orgo.space/api/v1/event_attend_invite_external \ -H "Api-Token: $ORGO_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "event": "/api/v1/events/01938d8e-9c4f-7c2a-b8e1-3f7a9b8c4f12", "firstName": "Olivia", "lastName": "Brown", "email": "olivia.brown@example.com" }' ``` The recipient receives a magic link they can open without an Orgo account. *** ## Step 5 — Collect payment (Stripe checkout) For paid tickets, the registration triggers a Stripe checkout session. Free events skip this step. The checkout URL returned in the `EventAttend` response (or fetched on demand for the same attendee) leads to Stripe's hosted page. After payment, Stripe webhooks `/api/v1/stripe-webhook` and Orgo flips the `ProductPayment` to `SUCCESS`. You can also subscribe to the `product_payment.updated` webhook to know when payment clears — see [Handle webhooks](/docs/api-reference/recipes/handle-webhooks). *** ## Check-in on the day At the venue, scan the attendee's QR code or look them up by name. Mark them attended: ```bash theme={null} curl -X PATCH https://acme.orgo.space/api/v1/event_attends/1042/confirm \ -H "Api-Token: $ORGO_API_TOKEN" \ -H "Content-Type: application/merge-patch+json" \ -d '{}' ``` *** ## Common gotchas Three causes: (1) `isPublic` is `false` — flip to `true`; (2) the tenant uses a custom domain and your slug collides with an existing route; (3) the event's `dateTimeEnd` is already in the past, in which case the public listing hides it. Stripe needs to be connected at the level the event's `unit` resolves to. If the event is on a local center, that local center needs a Stripe-connected account. Tenant-level Stripe doesn't cascade automatically. Set `hasEventTicketing: true`, `requiresRegistrationForm: true`, and create a Product with `customMinPrice: 0`. Stripe is bypassed for zero-amount tickets but the registration still requires confirmation. Yes — use `POST /api/v1/event_attends/{id}/guest-tickets` after the main registration to add up to N guests. Each guest gets their own QR code. *** ## What to do next * [Send a newsletter campaign](/docs/api-reference/recipes/send-a-newsletter-campaign) — announce the event to your audience * [Handle webhooks](/docs/api-reference/recipes/handle-webhooks) — react to `event_attend.created` to sync registrations into your CRM * [Process payments](/docs/api-reference/recipes/process-payments) — handle refunds and failed payments # Handle webhooks Source: https://orgo.space/docs/api-reference/recipes/handle-webhooks Build a receiver — subscribe, process events idempotently, replay failures This walkthrough implements a production-grade webhook receiver for Orgo events. It covers subscription, idempotent handling, fast responses, and replay. Who is this for: any integration that needs to react to changes in Orgo in near-real-time (CRM sync, member onboarding automation, payment reconciliation, contract-signed notifications). *** ## Available events Eighteen event types, across six entity families. Subscribe to any subset. | Family | Events | | -------------------- | ------------------------------------------------------------------------------- | | **User** | `user.created`, `user.updated`, `user.deleted` | | **Payment** | `product_payment.created`, `product_payment.updated`, `product_payment.deleted` | | **Event attendance** | `event_attend.created`, `event_attend.updated`, `event_attend.deleted` | | **Contract** | `contract_user.created`, `contract_user.updated`, `contract_user.deleted` | | **Role** | `user_role.created`, `user_role.updated`, `user_role.deleted` | | **Contact** | `contact.created`, `contact.updated`, `contact.deleted` | *** ## Step 1 — Subscribe Pick the events you care about and an HTTPS endpoint you control. ```bash theme={null} curl -X POST https://acme.orgo.space/api/v1/webhook_subscriptions \ -H "Api-Token: $ORGO_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "url": "https://your-app.example.com/webhooks/orgo", "events": [ "user.created", "product_payment.created", "product_payment.updated" ], "secret": "whsec_a3f8b2c4d6e8f1a3b5c7d9e1f3a5b7c9", "active": true, "description": "Sync members and payments into our CRM." }' ``` The `secret` is yours to choose — a 32-byte random string is standard. Orgo uses it to sign each delivery so you can verify the payload came from Orgo. Response includes the subscription ID — store it; you'll need it for delivery-log lookups. *** ## Step 2 — Receive the delivery Each event is delivered as an HTTPS `POST` with a JSON body and these headers: | Header | Purpose | | --------------------- | ------------------------------------------------------------------ | | `X-Webhook-Event` | The event type — e.g. `user.created` | | `X-Webhook-Delivery` | Unique delivery ID — log this to correlate with the Orgo dashboard | | `X-Webhook-Timestamp` | Unix timestamp of when the delivery was sent | | `X-Webhook-Signature` | `t=,v1=`, verified in Step 3 | | `User-Agent` | `OrgoWebhook/1.0` | Body shape (Stripe-inspired): ```json theme={null} { "id": "wh_evt_67aa128c2f4a", "event": "user.created", "api_version": "2024-01", "created": 1735689600, "tenant_id": 1, "request": { "id": "req_8c2f4a67aa12" }, "object": { "@id": "/api/v1/users/42", "id": 42, "firstName": "James", "lastName": "Patterson", "email": "james.patterson@example.com", "status": "ACTIVE" }, "previous_attributes": null, "is_update": false, "entity_type": "user", "operation": "created" } ``` For `*.updated` events, `previous_attributes` carries the diff — fields not mentioned didn't change. This is enough to detect specific transitions ("user just unsubscribed", "payment just succeeded") without comparing to a stored snapshot. *** ## Step 3 — Verify the signature Do this before you look at the body. The endpoint is public, so anything that reaches it is unauthenticated until the signature says otherwise. `X-Webhook-Signature` is `t=,v1=`, where `v1` is `HMAC-SHA256(secret, "." + raw request body)`. The `t` is the same value as `X-Webhook-Timestamp`, and it is inside the signed string, so a captured delivery cannot be re-stamped and replayed. ```python theme={null} import hashlib, hmac, time TOLERANCE_SECONDS = 300 def verify(raw_body: bytes, header: str, secret: str) -> bool: parts = dict(p.split("=", 1) for p in header.split(",")) if "t" not in parts or "v1" not in parts: return False if abs(time.time() - int(parts["t"])) > TOLERANCE_SECONDS: return False # replayed, or your clock is wrong expected = hmac.new( secret.encode(), parts["t"].encode() + b"." + raw_body, hashlib.sha256, ).hexdigest() return hmac.compare_digest(expected, parts["v1"]) @app.post("/webhooks/orgo") def receive(): if not verify(request.get_data(), request.headers.get("X-Webhook-Signature", ""), SECRET): return "", 401 ... ``` Three rules the code above is built around: * **Hash the raw bytes.** `request.get_data()`, not `request.get_json()` re-serialized. Key order and whitespace differ after a round trip, and the MAC changes with them. * **Compare in constant time.** `hmac.compare_digest`, `crypto.timingSafeEqual`, `hash_equals`, never `==`. * **Do not deduplicate on the signature.** Retries are re-signed at send time, so the same delivery ID arrives with a different `v1`. Dedupe on the payload `id`, as in Step 4. Returning `401` marks the delivery failed and Orgo retries it, which is what you want when the cause is a secret you have just rotated on one side only. A JavaScript version of the same function is in the [webhooks concept page](/docs/api-reference/concepts/webhooks#authenticating-the-sender). This format shipped in August 2026, replacing a short non-keyed checksum. There is no compatibility header: a receiver comparing the old value must move to the recipe above. *** ## Step 4 — Be idempotent Orgo may deliver the same event twice — retries on transient failures, network races on at-least-once delivery. Your handler must be safe to call repeatedly with the same payload. The simplest pattern: a `processed_deliveries` table keyed by `id` (the top-level event ID, e.g. `wh_evt_67aa128c2f4a`): ```python theme={null} def handle_event(payload: dict) -> None: delivery_id = payload["id"] with db.transaction(): if db.processed_deliveries.exists(delivery_id): return # already handled, no-op db.processed_deliveries.insert(delivery_id, processed_at=now()) dispatch(payload) ``` Insert the row *inside the same transaction* as the side effect, so a crash mid-way doesn't leave the row inserted without the effect. If the effect is in a different system (CRM API call), insert the row only after the effect succeeds. *** ## Step 5 — Respond fast Orgo waits up to 30 seconds for a response before treating the delivery as failed. Long-running work (sending a follow-up email, querying a slow downstream API) should go into a background queue. The webhook handler's job is to acknowledge receipt and durably queue the work — not perform it. ```python theme={null} @app.post("/webhooks/orgo") def receive(): payload = request.get_json() queue.enqueue("process_orgo_event", payload) # < 50ms return "", 200 ``` Return any 2xx; Orgo doesn't care about the body. *** ## Step 6 — Test before going live The test endpoint fires a synthetic event of your chosen type to the subscription URL: ```bash theme={null} curl -X POST https://acme.orgo.space/api/v1/webhook_subscriptions/3/test \ -H "Api-Token: $ORGO_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{"event": "user.created"}' ``` The synthetic payload uses fixture data (not real user data) but carries the same headers and shape your handler will see in production. Use it in CI to validate end-to-end delivery. *** ## Step 7 — Replay failed deliveries Every delivery attempt — success or failure — is logged. To list: ```bash theme={null} curl https://acme.orgo.space/api/v1/webhook_subscriptions/3/delivery_logs \ -H "Api-Token: $ORGO_API_TOKEN" ``` For each failed delivery, the response includes the original payload — you can re-process it locally without needing Orgo to re-deliver. Logs are retained for \~90 days. *** ## Retry behavior | Trigger | Behavior | | ------------------------ | -------------------------------------------------------------------------------- | | Receiver returns 2xx | Marked delivered, no retries | | Receiver returns non-2xx | Retry up to 3 times with exponential backoff (max \~10 minutes between attempts) | | Receiver takes >30s | Treated as failed; retried | | Receiver TLS error | Treated as failed; retried | | All retries fail | Marked permanently failed; appears in delivery logs | The subscription itself is *not* automatically deactivated on repeated failures — your monitoring should watch for high failure rates and either auto-pause or page on-call. *** ## Common gotchas Orgo doesn't guarantee delivery order across event types. The `created` timestamp on each event lets you reconstruct order — sort by `created` before processing if order matters. For per-resource ordering ("two updates to the same user"), use `previous_attributes` to detect skipped transitions. Always route by `tenant_id` in the payload, not by the subscription ID. If a single CRM serves multiple Orgo tenants, each tenant should create its own subscription, and your receiver should route incoming events to the right CRM tenant based on `payload['tenant_id']`. Not currently — list explicit event types in the `events` array. The full list is in the [Webhooks concept page](/docs/api-reference/concepts/webhooks). Subscribing to events that don't yet exist is harmless but won't catch new types if Orgo adds them — patch your subscription when new events ship. *** ## What to do next * [Webhooks (concept)](/docs/api-reference/concepts/webhooks) — the high-level reference * [Sync your CRM with Orgo](/docs/api-reference/recipes/sync-your-crm-with-orgo) — webhooks in context of a full CRM sync * [Process payments](/docs/api-reference/recipes/process-payments) — using `product_payment.updated` to drive payment reconciliation # Integrate "Log in with Orgo" (OAuth) Source: https://orgo.space/docs/api-reference/recipes/integrate-oauth-login End-to-end OAuth 2.0 Authorization Code flow — register the app, redirect, exchange, fetch user info This walkthrough adds "Log in with Orgo" to a third-party application. It uses the OAuth 2.0 authorization code flow with PKCE. Every URL here is on the tenant's own host — `acme.orgo.space` in these examples, or the organization's custom domain. The bare `app.orgo.space` domain resolves no tenant and returns `404`. See [Tenancy](/docs/api-reference/concepts/tenancy). Who is this for: SaaS apps your members use that should not require a second login (member-only forums, member-only deals platforms, internal tools, partner services). *** ## When to use OAuth vs Api-Token * **Api-Token** — your server acts as itself; the data is yours. Use for backend integrations, dashboards, batch jobs. * **OAuth** — your server acts on behalf of an Orgo user; you only see what that user can see. Use when each end-user logs into your app *as themselves*. If you're building a single integration that consumes "all members of Civic Collective", that's an Api-Token. If you're building a forum where each Orgo member logs in individually, that's OAuth. *** ## Prerequisites * A callback URL on your app served over HTTPS (localhost is allowed for development). * For a confidential client: an admin in the Orgo tenant who can create the app. *** ## Step 0 — Read the discovery document Don't hardcode endpoints. Every tenant publishes its own metadata, and `issuer` reflects the host you fetch it from: ```bash theme={null} curl https://acme.orgo.space/.well-known/oauth-authorization-server ``` Use `authorization_endpoint`, `token_endpoint` and `userinfo_endpoint` from the response. Fetch this once per tenant you integrate with — never reuse one tenant's document for another. *** ## Step 1 — Register your client Best for SPAs, mobile apps, and anything that cannot keep a secret. No admin involvement and no authentication needed, but limited to **10 registrations per hour per IP**: ```bash theme={null} curl -X POST https://acme.orgo.space/api/v1/oauth/register \ -H "Content-Type: application/json" \ -d '{ "redirect_uris": ["https://your-app.example.com/oauth/callback"], "client_name": "Civic Forum" }' ``` Returns `201` with a `client_id`. **No secret is issued** — PKCE is your only client authentication. Optional metadata: `client_uri`, `logo_uri`, `policy_uri`, `tos_uri`. In the Orgo admin UI: **Developer → Apps → Create Application**. | Field | What to enter | | ---------------------------- | ---------------------------------------------------------------------------------- | | **Name** | What users see during authorization — "Civic Forum" | | **Redirect URIs** | Exact callback URLs (one per line) — exact match required | | **Scopes** | What the app requests on the consent screen | | **Act on behalf of members** | Off makes the app read-only — see [step 7](#step-7-know-what-your-token-cannot-do) | Orgo returns a **Client ID** and a **Client Secret** (one-time, store server-side only). *** ## Step 2 — Redirect the user to authorize When a user clicks "Log in with Orgo" in your app, redirect them to: ``` https://acme.orgo.space/authorize ?response_type=code &client_id=YOUR_CLIENT_ID &redirect_uri=https://your-app.example.com/oauth/callback &scope=profile+email+groups &state= &code_challenge= &code_challenge_method=S256 ``` | Parameter | Purpose | | ----------------------- | ------------------------------------------------------------------------- | | `response_type` | Always `code` | | `client_id` | The Client ID from Step 1 | | `redirect_uri` | Must match a registered URI exactly (including trailing slash) | | `scope` | Space-separated list — see [scopes](#available-scopes) | | `state` | Random string you generate per-request; check on callback to prevent CSRF | | `code_challenge` | `BASE64URL(SHA256(code_verifier))` | | `code_challenge_method` | Always `S256` | **PKCE is mandatory for every client**, confidential ones included — this is stricter than baseline OAuth 2.0 and matches OAuth 2.1. The server rejects violations with `invalid_request`: * `code_challenge_method` must be `S256`; `plain` is not supported. * Both `code_challenge` and `code_verifier` must match `[A-Za-z0-9-._~]{43,128}`. If the member isn't signed in, Orgo handles login and returns them to the consent screen automatically — including via Google, Apple or Microsoft. You don't handle that. *** ## Step 3 — Receive the callback Orgo sends the user back to your `redirect_uri` with two parameters: ``` https://your-app.example.com/oauth/callback?code=&state= ``` Verify `state` matches the one you stored, then move on. *** ## Step 4 — Exchange the code for an access token Form-encoded body, not JSON. A confidential client does this server-side — the Client Secret must never reach the browser. PKCE only. Sending a `client_secret` here is an error (`invalid_client`): ```bash theme={null} curl -X POST https://acme.orgo.space/api/v1/oauth/token \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "grant_type=authorization_code" \ -d "code=$AUTH_CODE" \ -d "client_id=$CLIENT_ID" \ -d "code_verifier=$PKCE_VERIFIER" \ -d "redirect_uri=https://your-app.example.com/oauth/callback" ``` Send the `code_verifier` **and** authenticate. Pick exactly one authentication method — `client_secret_basic` here, or `client_secret_post` via a `client_secret` field: ```bash theme={null} curl -X POST https://acme.orgo.space/api/v1/oauth/token \ -u "$CLIENT_ID:$CLIENT_SECRET" \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "grant_type=authorization_code" \ -d "code=$AUTH_CODE" \ -d "client_id=$CLIENT_ID" \ -d "code_verifier=$PKCE_VERIFIER" \ -d "redirect_uri=https://your-app.example.com/oauth/callback" ``` Response: ```json theme={null} { "access_token": "eyJ0eXAiOiJKV1QiLCJhbGc...", "token_type": "Bearer", "expires_in": 3600, "refresh_token": "f3c7a...", "scope": "profile email groups" } ``` The code is **single use**. Redeeming it twice fails with `invalid_grant` — and a replay by an authenticated client **revokes the tokens that code already produced**. Never retry a code after a successful exchange. (A retry after a *failed client authentication* is safe: the code stays redeemable so you can fix credentials and try again.) *** ## Step 5 — Use the access token The access token works as a normal Bearer JWT. ```bash theme={null} curl https://acme.orgo.space/api/v1/oauth/userinfo \ -H "Authorization: Bearer $ACCESS_TOKEN" ``` Response: ```json theme={null} { "sub": "42", "name": "James Patterson", "email": "james.patterson@example.com", "picture": "https://cdn.orgo.space/users/42/avatar.jpg", "groups": ["main-group", "boston-local"], "roles": ["ROLE_USER", "ROLE_MEMBER"] } ``` `sub` is the user's stable Orgo ID — use this as the primary key in your app's users table. Email can change; `sub` cannot. You can also use the same access token to call other API endpoints scoped to the user's permissions: ```bash theme={null} curl https://acme.orgo.space/api/v1/me \ -H "Authorization: Bearer $ACCESS_TOKEN" ``` *** ## Step 6 — Refresh expired tokens Access tokens last **1 hour** (`expires_in` in the original response). Refresh tokens last **30 days**. Use the refresh token to get a new pair without sending the user back through the consent screen: ```bash theme={null} curl -X POST https://acme.orgo.space/api/v1/oauth/token \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "grant_type=refresh_token" \ -d "refresh_token=$REFRESH_TOKEN" \ -d "client_id=$CLIENT_ID" ``` Confidential clients authenticate here too, exactly as in step 4. **Refresh tokens rotate.** Each refresh returns a *new* `refresh_token` and invalidates the one you just sent. Persist the new value every time — an app that keeps replaying its original refresh token will work once and then start failing with `invalid_grant`. Do not call refresh on every API request — only when a request returns `401`. *** ## Step 7 — Know what your token cannot do Two limits catch most integrations, and neither is adjustable per request. **An app acts as a member, never as an administrator.** The token is capped to member level (`ROLE_USER`) no matter who authorized it. If a tenant administrator connects your app, it still cannot perform administrator actions. **Read-only apps are gated by HTTP method.** If the app is registered read-only it may use `GET`, `HEAD` and `OPTIONS` only. Anything else returns `403`: ``` This application has read-only access and may not act on your behalf. ``` The gate is by method, not intent — an endpoint that performs a read via `POST` is still blocked. If you need those, register the app with acting enabled. *** ## Available scopes | Scope | What the member is asked to approve | | --------- | ----------------------------------------------------------- | | `profile` | Name, profile picture, display name | | `email` | Email address | | `groups` | Group + local-center memberships | | `roles` | User roles (`ROLE_USER`, `ROLE_MEMBER`, `ROLE_ADMIN`, etc.) | Scopes describe what an application **requests** and what the member **approves** when they authorize it. What the resulting token can actually reach is bounded by the member-level cap and the application's read-only / act-on-behalf setting in [step 7](#step-7-know-what-your-token-cannot-do). Request only what you need — fewer scopes makes the consent screen shorter and clearer. *** ## Common gotchas The `redirect_uri` parameter must match a registered URI *exactly*. Watch for: trailing slashes, `http` vs `https`, port numbers (8080 vs 443), and URL encoding of query strings. Register every variant you use (dev, staging, prod) at creation. Check that your callback handler is reachable from Orgo's servers (not localhost-only behind a firewall) and serves HTTPS (except for `localhost` URIs which can use HTTP). Check browser network tab — Orgo issues a `302` to the callback; if your handler 500s, it shows there. Wrong `client_id`, wrong `client_secret`, or a confidential client omitting its secret entirely (that one returns `401` with `WWW-Authenticate: Basic realm="orgo-oauth"`). A **public** client sending a `client_secret` also fails — it has none, and PKCE is its only authentication. Note that sending `client_secret` *and* `code_verifier` together is correct for a confidential client: PKCE applies to every client. What is not allowed is sending credentials by more than one method at once — Basic header *and* form field — which returns `invalid_request`. Repeated *failed* client authentications for the same `client_id` are throttled: after 10 failures in 5 minutes you get `429` with a `Retry-After` header instead of `401`. This means your credentials are wrong, not that you are calling too often — a request with the correct secret is never throttled, however many failures came before it. Fix the secret rather than backing off. The `groups` scope returns *slug-style* group names, not display names. To resolve to a full `Group` resource, call `GET /api/v1/units?slug=boston-local` separately. Use PKCE without a Client Secret. Generate a verifier (random 43-128 chars), hash it with SHA-256, base64url-encode the hash, send the hash as `code_challenge` on authorize, then send the verifier as `code_verifier` on token exchange. The Client Secret stays unused. Access tokens are RS256 JWTs, but they are **revocable server-side** and revocation takes effect on the **next request**. A token whose signature verifies and whose `exp` is still in the future can still be rejected. Do not treat a local expiry check as proof a token works — handle `401` at any point in a token's lifetime and fall back to refresh, then to re-authorization. Verify signatures against `jwks_uri` from the discovery document. *** ## What to do next * [Authentication](/docs/api-reference/concepts/authentication) — comparison of OAuth vs Api-Token vs JWT vs OTP, and the full discovery reference * [Migrating from legacy SSO](/docs/api-reference/concepts/authentication#legacy-sso-deprecated) — if you already use the `*-sso` handshake * [OAuth Server](/docs/platform/oauth) — admin-side documentation on managing OAuth applications * [Tenancy](/docs/api-reference/concepts/tenancy) — how OAuth tokens carry tenant scope # Issue and track contracts Source: https://orgo.space/docs/api-reference/recipes/issue-and-track-contracts Create a contract template, assign it to members, collect signatures, and bulk-apply default signatures This walkthrough covers the full contract lifecycle — from a reusable template definition to per-member signed PDFs stored in S3. It uses the [Contract](/docs/api-reference/contract) and [ContractUser](/docs/api-reference/contractuser) resources. Who is this for: legal-ops integrations that need to provision new contract templates (annual member agreement, NDA, parental-consent form), bulk-assign them, or programmatically chase signatures. *** ## Concepts * A **Contract** is a *template* — content, placeholders, signature requirements. Tenant-scoped, reusable. * A **ContractUser** is one *instance* of a contract assigned to a specific User or Contact. It carries the signature state, the rendered placeholder values, and the signed PDF. * A **Placeholder** like `{{firstName}}` is resolved at assignment time from the recipient's profile + any custom fields you map. *** ## Step 1 — Create a contract template ```bash theme={null} curl -X POST https://acme.orgo.space/api/v1/contracts \ -H "Api-Token: $ORGO_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "name": "Member Agreement 2026", "content": "

Civic Collective — Member Agreement

This agreement is between Civic Collective and {{firstName}} {{lastName}}, dated {{dateSigned}}.

The member agrees to abide by the code of conduct...

", "unit": "/api/v1/units/4", "requiresDigitalSignature": true, "displayInProfile": true }' ``` The response includes a `hash` field — a unique fingerprint of the contract's content. If you later edit the content materially, you'll need to regenerate the hash via `PATCH /api/v1/contracts/{id}/ask-resign` (see below). ```json theme={null} { "id": 9, "name": "Member Agreement 2026", "hash": "a3f8b2c4d6e8f1a3b5c7d9e1f3a5b7c9", "requiresDigitalSignature": true, "displayInProfile": true, "unit": { "id": 4, "name": "Boston" } } ``` ### `displayInProfile` When `true`, the contract automatically shows up in the profile of every User in the assigned `Unit`. They can self-serve a signature from their member dashboard. When `false`, contracts only appear after explicit assignment via Step 2. *** ## Step 2 — Assign the contract to a member ```bash theme={null} curl -X POST https://acme.orgo.space/api/v1/contract_users \ -H "Api-Token: $ORGO_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "contract": "/api/v1/contracts/9", "user": "/api/v1/users/42", "validityStartDate": "2026-01-15", "validityEndDate": "2027-01-14" }' ``` Either `user` or `contact` is required (not both). For Contacts who haven't yet become Users, contracts can still be assigned — they sign via a magic link. Response: ```json theme={null} { "id": 63, "status": "UNSIGNED", "contract": { "id": 9, "name": "Member Agreement 2026" }, "user": { "id": 42, "fullName": "James Patterson" }, "validityStartDate": "2026-01-15", "validityEndDate": "2027-01-14" } ``` Member receives an email with a sign-now link. *** ## Step 3 — Sign membership contract in advance For the membership-defaults contract (configured on the tenant), there's a shortcut endpoint that creates-or-fetches an unsigned ContractUser for the calling user: ```bash theme={null} curl -X POST https://acme.orgo.space/api/v1/sign-membership-contract-in_advance \ -H "Authorization: Bearer $ORGO_JWT" \ -H "Content-Type: application/json" \ -d '{}' ``` Useful in flows where a member is pre-signing as part of registration. If an unsigned instance already exists, the existing one is returned (no duplicates). *** ## Step 4 — Bulk mark as signed (paper signatures) For members who signed on paper, mark the contract complete without requiring a digital signature: ```bash theme={null} curl -X PATCH https://acme.orgo.space/api/v1/contract_users/mark_as_signed \ -H "Api-Token: $ORGO_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "contractUsers": ["/api/v1/contract_users/63", "/api/v1/contract_users/64"], "dateSigned": "2026-01-15T10:00:00+00:00" }' ``` This sets status to `COMPLETE`, locks the record, and records the calling admin as `signedBy`. Useful for backfilling pre-Orgo contracts. *** ## Step 5 — Apply admin default signature For contracts that require an admin co-signature (after the member signs), Orgo can apply a pre-stored default admin signature in one call: ```bash theme={null} curl -X POST https://acme.orgo.space/api/v1/contract_users/63/use-default-signature \ -H "Api-Token: $ORGO_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{}' ``` This: * Validates a default signature exists for the tenant * Validates the contract hasn't already been admin-signed * Sets the admin signature, locks the record, records the signature date * Generates a signed PDF, uploads to S3 * Generates a contract certificate The admin signature must be uploaded once via the tenant settings before this works. *** ## Step 6 — Force re-signing after content changes When you materially edit a Contract's content, existing unsigned ContractUsers become stale (their placeholder values may no longer match). To regenerate the contract hash and cancel all unsigned instances: ```bash theme={null} curl -X PATCH https://acme.orgo.space/api/v1/contracts/9/ask-resign \ -H "Api-Token: $ORGO_API_TOKEN" \ -H "Content-Type: application/merge-patch+json" \ -d '{}' ``` This sets a new `hash` on the Contract and marks every unsigned ContractUser as canceled (with timestamps + canceledBy). Already-signed instances are untouched. The next assignment cycle generates fresh ContractUser instances with the new content. *** ## Listing and reporting ### Members with unsigned contracts ```bash theme={null} curl "https://acme.orgo.space/api/v1/contract_users?status=UNSIGNED&contract=/api/v1/contracts/9" \ -H "Api-Token: $ORGO_API_TOKEN" ``` ### Member's contracts in their profile ```bash theme={null} curl https://acme.orgo.space/api/v1/my_contracts \ -H "Authorization: Bearer $ORGO_JWT" ``` Returns contracts the authenticated user has signed plus contracts marked `displayInProfile: true` for groups they belong to. *** ## Common gotchas The resolution happens once when the ContractUser is created (or refreshed). If the member's profile is missing `firstName`, the placeholder is replaced with an empty string. Check the user's profile first; for custom-field placeholders, ensure the field is mapped on the Contract template. Contract templates with any signed ContractUser cannot be deleted (audit trail). Either delete the signed instances first (rarely advised), archive the contract by setting `displayInProfile: false` and unassigning, or simply leave it in place. `use-default-signature` requires the tenant to have a stored admin-signature image, configured under **Settings → Branding → Default Signature**. If missing, the endpoint returns `400`. The admin signature appears next to the date on the rendered PDF. Not as separate fields. The convention is to embed annexes inline in the `content` HTML or include them as external links. The signed-PDF generation captures whatever is in `content`. *** ## What to do next * [Onboard a new member](/docs/api-reference/recipes/onboard-a-new-member) — pair contract assignment with the adhesion success * [Handle webhooks](/docs/api-reference/recipes/handle-webhooks) — `contract_user.updated` fires on every signature * [Manage local centers and permissions](/docs/api-reference/recipes/manage-local-centers-and-permissions) — scoping contracts per local center # Manage local centers and permissions Source: https://orgo.space/docs/api-reference/recipes/manage-local-centers-and-permissions Create a local center, assign admins, scope roles, and audit who can do what This walkthrough sets up organizational structure: a new local center (chapter, branch, regional office), the admins who run it, and the per-domain permissions that scope what they can do. It uses the [LocalCenter](/docs/api-reference/localcenter), [Unit](/docs/api-reference/unit), [UserRole](/docs/api-reference/userrole), and Role resources. Who is this for: enterprise-onboarding integrations that spin up multi-tenant structure programmatically, federation tools that synchronize org-chart changes from an upstream system, or admin dashboards that need to audit permissions in bulk. *** ## Concepts ### The three permission domains Orgo splits permissions into three domains. Each domain has its own roles. Granting one doesn't grant the others. | Domain | What it controls | | ------------- | ----------------------------------------------------------------- | | **ADMIN** | Configuration — branding, modules, custom fields, settings | | **HR** | People — registration, profiles, adhesion, contracts, contact CRM | | **FINANCIAL** | Money — products, prices, payments, invoices, refunds | Each domain has three scope levels: **TENANT** (whole org), **PARENT\_LOCAL** (a local center and everything under it), and **LOCAL** (one specific local center). So `HR_LOCAL` means "manages people for this one local center", `ADMIN_TENANT` means "configures the whole organization". The combinations make 9 distinct permission scopes; see [Permissions](/docs/platform/permissions) for the full matrix. ### Where local centers fit A `LocalCenter` is a kind of `Unit`. Units are the generic grouping primitive — local centers, role groups (automatic membership by role), private project teams. Most permission scopes attach to a specific `Unit` (which, for local-scope roles, is the LocalCenter itself). *** ## Step 1 — Create a local center ```bash theme={null} curl -X POST https://acme.orgo.space/api/v1/local_centers \ -H "Api-Token: $ORGO_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "name": "Boston", "description": "Boston chapter — serves Greater Boston and Cambridge.", "country": "/api/v1/countries/1", "town": "/api/v1/towns/1", "address": "123 Beacon Street, Boston, MA 02108", "email": "boston@example.com", "phone": "+1 617 555 0177", "isPublic": true, "isActive": true }' ``` `isPublic: true` makes the local center appear on the public "find your center" map and listing. `isActive: false` hides it from new-member registration forms while keeping it visible to admins. Response carries the integer `id` you'll use for `/api/v1/local_centers/{id}` references throughout the rest of the system. *** ## Step 2 — Create a role definition Roles are the named permission containers ("Chapter Lead", "Treasurer", "Outreach Coordinator"). Create one per distinct responsibility: ```bash theme={null} curl -X POST https://acme.orgo.space/api/v1/roles \ -H "Api-Token: $ORGO_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "name": "Chapter Lead", "description": "Top admin for a local chapter — full HR and FINANCIAL_LOCAL, plus discussion moderation.", "permissions": [ "HR_LOCAL", "FINANCIAL_LOCAL", "ADMIN_LOCAL" ] }' ``` Roles live at the tenant level — they're reusable across local centers. The permission strings are constants; the full list lives at `GET /api/v1/permission_definitions` (or see [Permissions](/docs/platform/permissions)). *** ## Step 3 — Assign the role to a user, scoped to a unit The scoping happens at assignment time. The same role can be assigned to different users with different unit scopes. ```bash theme={null} curl -X POST https://acme.orgo.space/api/v1/user_roles \ -H "Api-Token: $ORGO_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "user": "/api/v1/users/42", "role": "/api/v1/roles/233", "unit": "/api/v1/units/4" }' ``` This grants James Patterson the "Chapter Lead" role *for the Boston local center only*. He cannot HR-manage Manchester members. Multiple `UserRole` assignments stack. A user can be Chapter Lead in Boston, Outreach Coordinator in Manchester, and Treasurer at the tenant level — three separate `UserRole` records. *** ## Step 4 — Audit who has what ### Who admins this local center? ```bash theme={null} curl "https://acme.orgo.space/api/v1/user_roles?unit=/api/v1/units/4" \ -H "Api-Token: $ORGO_API_TOKEN" \ -H "Accept: application/ld+json" ``` The response includes each assignment with the user, role, and assignment date. `hydra:totalItems` gives the count. ### Every assignment for one user ```bash theme={null} curl "https://acme.orgo.space/api/v1/user_roles?user=/api/v1/users/42" \ -H "Api-Token: $ORGO_API_TOKEN" ``` Useful for "show me everything James can do" before revoking. ### The org chart ```bash theme={null} curl https://acme.orgo.space/api/v1/chart-members \ -H "Api-Token: $ORGO_API_TOKEN" ``` Returns a structured view of every person + role across the tenant, suitable for rendering an org chart. *** ## Step 5 — Revoke Delete the `UserRole` record: ```bash theme={null} curl -X DELETE https://acme.orgo.space/api/v1/user_roles/199 \ -H "Api-Token: $ORGO_API_TOKEN" ``` The user's underlying `User` account is untouched — they remain a member; they just lose the elevated permissions immediately. Active sessions are *not* invalidated; revocation takes effect on the next request that re-evaluates permissions (which, for most endpoints, is the next request). *** ## Step 6 — Restructure the hierarchy (parent locals) For federations with regional hierarchy ("Northeast Region" containing Boston, New York, Philadelphia), set a parent on each local center: ```bash theme={null} curl -X PATCH https://acme.orgo.space/api/v1/local_centers/4 \ -H "Api-Token: $ORGO_API_TOKEN" \ -H "Content-Type: application/merge-patch+json" \ -d '{"parent": "/api/v1/local_centers/1"}' ``` Now anyone with `HR_PARENT_LOCAL` on the parent (Northeast Region) can manage all children — Boston, New York, Philadelphia — without needing individual `HR_LOCAL` grants on each. *** ## Step 7 — Self-service join For local centers configured as `isOpen: true`, members can join themselves: ```bash theme={null} curl -X POST https://acme.orgo.space/api/v1/group/join \ -H "Authorization: Bearer $ORGO_JWT" \ -H "Content-Type: application/json" \ -d '{"unit": "/api/v1/units/4"}' ``` Creates a `UserRole` with the default member role for that local center. Useful for self-organizing chapters where any member can join. *** ## Common gotchas `ADMIN_TENANT` is the configuration domain — it grants access to settings, branding, modules. It does NOT grant HR (manage people) or FINANCIAL (manage payments). To grant truly everything, assign all three: `ADMIN_TENANT`, `HR_TENANT`, `FINANCIAL_TENANT`. This is intentional — it separates the "configure the org" role from the "see member PII" role from the "issue refunds" role. Local centers with active members, ongoing fees, or unresolved payments cannot be deleted. Reassign members to another center first (`PATCH /api/v1/users/{id}` setting `localCenter` to the new one), then close out fees, then delete. `PARENT_LOCAL` scope only cascades when the parent relationship is set via `local_centers.parent`. Setting it via the Unit hierarchy alone doesn't grant cascading permissions on local-center-scoped queries. If cascading isn't working, double-check the LocalCenter has `parent` set correctly, not just the Unit. Two options: (1) automatic role groups — create a Unit of type "role group" filtered by membership criteria; new members auto-join. (2) Loop on the client side — paginate through `GET /api/v1/users?localCenter=...` and POST one `UserRole` per. The bulk endpoint doesn't exist for role assignment because the side effects (audit log, permission cache invalidation) are per-user. *** ## What to do next * [Permissions](/docs/platform/permissions) — the full domain × scope matrix * [Onboard a new member](/docs/api-reference/recipes/onboard-a-new-member) — the adhesion side of getting members into a local center * [Tenancy](/docs/api-reference/concepts/tenancy) — how tenant isolation interacts with local-center scoping # Onboard a new member Source: https://orgo.space/docs/api-reference/recipes/onboard-a-new-member End-to-end membership application — from a new contact filling in the form to a fully active member with role and fees This walkthrough takes a prospective member from their first form submission to fully active member, including identity verification, document signing, and admin approval. It chains five endpoints across the [Adhesion](/docs/api-reference/adhesion) and [User](/docs/api-reference/user) resources. Who is this for: integrations that surface Orgo's adhesion flow inside a third-party site (e.g. your organization's marketing page), or admin tools that drive members through the funnel programmatically. *** ## What you'll end up with ``` 1. Adhesion created (NEW) — applicant fills the form 2. ID document uploaded (NEW) — OCR runs, identity record created 3. Signed PDF uploaded (NEW) — required for HR review 4. Submitted for review (PENDING) — HR notified by email 5. Admin transitions (VALIDATED → SUCCESS) — MEMBER role assigned, fee activated, welcome email sent ``` Each step is one API call. Status transitions are explicit — Orgo does not silently advance the application. *** ## Step 1 — Create the draft adhesion The applicant fills in their personal data. From your integration, that becomes a `POST` to `/api/v1/adhesion/create`. The application is created in `NEW` status, editable, and not yet visible to HR. ```bash theme={null} curl -X POST https://acme.orgo.space/api/v1/adhesion/create \ -H "Api-Token: $ORGO_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "firstName": "Sarah", "lastName": "O'\''Connor", "email": "sarah.oconnor@example.com", "dateBirth": "1995-09-08T00:00:00+00:00", "phoneNumber": "+1 617 555 0177", "address": "456 Commonwealth Ave, Boston, MA 02215", "motivation": "I want to contribute to local civic projects.", "localCenter": "/api/v1/local_centers/4" }' ``` Response: ```json theme={null} { "id": 91, "status": "NEW", "firstName": "Sarah", "lastName": "O'Connor", "hasIdDocument": false, "hasSignedDocument": false, "canBeSubmitted": false } ``` Note `canBeSubmitted: false` — that flips to `true` only after both documents (ID + signed) are uploaded. If your integration lets users save and return later (multi-session form), you can `PATCH /api/v1/adhesion/update/{id}` repeatedly until they're ready. Updates are only allowed while the adhesion is in `NEW`. *** ## Step 2 — Upload an ID document ID verification is mandatory. The upload triggers OCR, which extracts personal data into an `Identity` record attached to the application. ```bash theme={null} curl -X POST https://acme.orgo.space/api/v1/adhesion/91/upload-id \ -H "Api-Token: $ORGO_API_TOKEN" \ -F "idMedia=@/path/to/passport.pdf" ``` The OCR runs asynchronously — the response returns immediately with `hasIdDocument: true`, but the extracted fields appear on the `Identity` record a few seconds later. Polling `GET /api/v1/identity/{id}` will show OCR progress. Replacing an existing ID document is supported — re-upload the same endpoint and the previous file plus its OCR data is discarded. *** ## Step 3 — Upload the signed adhesion form The applicant downloads the pre-filled PDF (you can render the template yourself, or hit `GET /api/v1/adhesion/{id}/pdf` to grab the official one), signs it, and uploads the signed version back. ```bash theme={null} curl -X POST https://acme.orgo.space/api/v1/adhesion/91/upload-signed \ -H "Api-Token: $ORGO_API_TOKEN" \ -F "signedMedia=@/path/to/signed-adhesion.pdf" ``` After this call, the adhesion's `canBeSubmitted` flag flips to `true`. *** ## Step 4 — Submit for HR review Once both documents are in place, transition the application from `NEW` to `PENDING`. This sends an email to the responsible HR admin. ```bash theme={null} curl -X PATCH https://acme.orgo.space/api/v1/adhesion/91/send \ -H "Api-Token: $ORGO_API_TOKEN" \ -H "Content-Type: application/merge-patch+json" \ -d '{}' ``` A `409 Conflict` here means one of the documents is missing — check `hasIdDocument` and `hasSignedDocument` on the adhesion first. After this point, the applicant cannot edit the application themselves. HR can still record interview notes via `PATCH /api/v1/adhesion/{id}/interview`. *** ## Step 5 — Admin transitions to approval HR reviews the application, optionally records interview notes, and transitions the status. Each transition has side effects. | Status | When to use | Side effects | | ------------- | -------------------------------------------------- | --------------------------------------------------------- | | `VALIDATED` | Documents check out, data verified | Confirmation email to applicant | | `INTERVIEWED` | Interview complete (between VALIDATED and SUCCESS) | None | | `REJECTED` | Application denied | Rejection email to applicant; terminal state | | `SUCCESS` | Approved | `MEMBER` role assigned, fee activated, welcome email sent | ```bash theme={null} curl -X PATCH https://acme.orgo.space/api/v1/adhesion/91/status \ -H "Api-Token: $ORGO_API_TOKEN" \ -H "Content-Type: application/merge-patch+json" \ -d '{"status": "SUCCESS"}' ``` After `SUCCESS`, the linked `User` is now `ACTIVE`, the membership fee is active, and they can log in. *** ## Common gotchas The email goes to the admin marked as responsible HR for the applicant's local center — not to a blanket inbox. Check **Settings → Users → Permissions** that at least one admin has `HR_LOCAL` on the local center the applicant chose. If none, no email is sent (and `409` is returned by `send`). The OCR fills the `Identity` record, not the `Adhesion` itself. The applicant's submitted form fields stay as-is; HR sees both side by side in the admin UI. You can correct via `PATCH /api/v1/identity/{id}/update-data`. No. For minors, use the family-member flow: `POST /api/v1/register-child` against a parent's authenticated session. This skips ID upload and parental adhesion entirely; the child inherits parent membership. HR with `HR_TENANT` permission can create the User directly: `POST /api/v1/users` followed by `POST /api/v1/user_roles` to assign `MEMBER`. Skip the adhesion altogether. The cost is no audit trail of the application. *** ## What to do next * [Handle webhooks](/docs/api-reference/recipes/handle-webhooks) — subscribe to `user.created` so your CRM is updated the moment the adhesion succeeds * [Issue and track contracts](/docs/api-reference/recipes/issue-and-track-contracts) — assign the membership agreement after the User is activated * [Process payments](/docs/api-reference/recipes/process-payments) — collect the first membership fee # Process payments Source: https://orgo.space/docs/api-reference/recipes/process-payments Collect a payment with Stripe checkout, reconcile via webhooks, issue refunds, and handle bank transfers This walkthrough covers the full payment lifecycle: card payment via Stripe checkout, payment reconciliation via webhook, refund, and the parallel bank-transfer flow with invoice generation. It uses the [Product](/docs/api-reference/product), [ProductPayment](/docs/api-reference/productpayment), and [Invoice](/docs/api-reference/invoice) resources. Who is this for: backend integrations that drive the membership fee collection, ticket sales, or donation campaigns; finance-ops tools that automate refunds and reconcile against accounting systems. *** ## Architecture Orgo doesn't process card data directly — that's Stripe's job. Orgo orchestrates the flow: ``` 1. Create a Product (or Product already exists from setup) 2. Generate Stripe checkout URL — Orgo creates the Stripe session 3. Member pays on Stripe — Orgo never sees the card 4. Stripe webhook → Orgo — payment captured 5. Orgo webhook → your system — product_payment.updated fires 6. You reconcile — update CRM, send receipt, etc. ``` Bank-transfer flow is parallel: ``` 1. Issue Invoice — generates PDF, emails to member 2. Member sends transfer — out-of-band 3. Admin marks as paid — via UI or API 4. Orgo webhook → your system — product_payment.updated fires (same as card) ``` Same downstream event from your system's perspective. That's deliberate — your reconciliation code handles both cases identically. *** ## Card payment — Stripe checkout ### Step 1 — Generate a checkout URL For a membership product the member is buying: ```bash theme={null} curl https://acme.orgo.space/api/v1/companies/01938d8e-c2f4-7c2a-b8e1-3f7a9b8c4f88/payment-checkout \ -H "Api-Token: $ORGO_API_TOKEN" ``` For event-ticket purchases, the checkout URL comes back automatically inside the `EventAttend` response when the event has paid tickets — see [Create and sell event tickets](/docs/api-reference/recipes/create-and-sell-event-tickets). Response includes a `checkoutUrl`: ```json theme={null} { "checkoutUrl": "https://checkout.stripe.com/c/pay/cs_test_a1B2c3D4e5F6...", "sessionId": "cs_test_a1B2c3D4e5F6", "expiresAt": "2026-01-15T11:30:00+00:00" } ``` Redirect the user to `checkoutUrl`. Stripe handles the card collection. ### Step 2 — Stripe completes the charge On Stripe's side, the charge succeeds (or fails). Stripe POSTs to Orgo's webhook at `/api/v1/stripe-webhook`. This is invisible to your integration — Orgo handles it. Internally, Orgo creates a `ProductPayment` record with `status: SUCCESS` (or `FAILED`). ### Step 3 — React via webhook Subscribe to `product_payment.updated`: ```bash theme={null} curl -X POST https://acme.orgo.space/api/v1/webhook_subscriptions \ -H "Api-Token: $ORGO_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "url": "https://your-app.example.com/webhooks/orgo", "events": ["product_payment.created", "product_payment.updated"], "secret": "whsec_a3f8b2c4d6e8f1a3b5c7d9e1f3a5b7c9" }' ``` In your handler: ```python theme={null} def handle(payload): if payload["event"] != "product_payment.updated": return if payload["object"]["status"] == "SUCCESS": record_payment_in_accounting(payload["object"]) send_thank_you_email(payload["object"]["user"]) ``` See [Handle webhooks](/docs/api-reference/recipes/handle-webhooks) for the full receiver pattern. *** ## Refunding a paid charge When a member requests a refund (cancelled event, mistaken purchase, dispute settlement), call the refund endpoint: ```bash theme={null} curl -X PATCH https://acme.orgo.space/api/v1/product-payment/107/refund \ -H "Api-Token: $ORGO_API_TOKEN" \ -H "Content-Type: application/merge-patch+json" \ -d '{ "amount": 5000, "reason": "duplicate" }' ``` `amount` in cents. Omit for a full refund. `reason` is passed through to Stripe — common values: `duplicate`, `fraudulent`, `requested_by_customer`. Used for Stripe's dispute analytics. The refund returns immediately with the updated ProductPayment showing `status: REFUNDED`. Stripe processes the actual transfer over the following 5-10 business days. For partial refunds, call repeatedly until cumulative amount equals the original charge. Refunds are not reversible. Once issued, the funds are returned to the cardholder. To re-charge, the cardholder must complete a new checkout. *** ## Bank transfer with invoice For members who pay by bank transfer (corporate memberships, multi-thousand-dollar annual fees, regions where cards are uncommon), the flow is: ### Step 1 — Issue an invoice ```bash theme={null} curl -X POST https://acme.orgo.space/api/v1/invoices/create-for-bank-transfer \ -H "Api-Token: $ORGO_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "productPrice": "/api/v1/product_prices/22", "billingName": "James Patterson", "billingAddress": "123 Beacon Street, Boston, MA 02108", "billingEmail": "james.patterson@example.com", "vatNumber": null }' ``` Response: ```json theme={null} { "id": 284, "number": "INV-2026-00284", "status": "PENDING", "amount": 5000, "currency": "USD", "pdfUrl": "https://cdn.orgo.space/invoices/INV-2026-00284.pdf", "dateDue": "2026-02-14T10:30:00+00:00" } ``` A PDF is generated and emailed to `billingEmail`. The member transfers funds to the account printed on the invoice. ### Step 2 — Mark as paid When you see the transfer hit the bank, mark the invoice: ```bash theme={null} curl -X PATCH https://acme.orgo.space/api/v1/invoices/284/mark-as-paid \ -H "Api-Token: $ORGO_API_TOKEN" \ -H "Content-Type: application/merge-patch+json" \ -d '{"datePaid": "2026-01-18T14:22:00+00:00"}' ``` This creates the linked ProductPayment with `status: SUCCESS` and `method: BANK_TRANSFER`. Your webhook receiver sees the same `product_payment.updated` event it sees for card payments. ### Cancellation, void, refund | Action | Endpoint | When to use | | --------------------- | --------------------------------------------- | --------------------------------------------------------- | | Cancel before payment | `PATCH /api/v1/invoices/cancel-bank-transfer` | Member changed mind; invoice never paid | | Void | `PATCH /api/v1/invoices/{id}/void` | Issued in error; correct accounting record | | Refund | `PATCH /api/v1/invoices/{id}/refund` | Paid invoice needs to be refunded (creates a credit memo) | ### Resending the invoice email ```bash theme={null} curl -X PATCH https://acme.orgo.space/api/v1/invoices/284/send-email \ -H "Api-Token: $ORGO_API_TOKEN" \ -H "Content-Type: application/merge-patch+json" \ -d '{}' ``` Useful when the member's accounts-payable department asks for a copy. *** ## Reporting and reconciliation ### All payments in a date range ```bash theme={null} curl "https://acme.orgo.space/api/v1/product_payments?datePaid[after]=2026-01-01&datePaid[before]=2026-01-31&order[datePaid]=asc" \ -H "Api-Token: $ORGO_API_TOKEN" \ -H "Accept: application/ld+json" ``` `hydra:totalItems` gives you the count, the array gives you the data. Paginate as usual. ### Sum of successful payments There's no aggregation endpoint — fetch the page and sum locally. For monthly reporting, this is fine. For dashboards refreshing every minute, cache the result. ### Stuck-pending invoices ```bash theme={null} curl "https://acme.orgo.space/api/v1/invoices?status=PENDING&dateDue[before]=$(date -u +%Y-%m-%dT%H:%M:%SZ)" \ -H "Api-Token: $ORGO_API_TOKEN" ``` Returns invoices past their due date but still unpaid — your dunning list. *** ## Common gotchas Stripe is connected at the local-center level (preferred) or the tenant level. The product's `unit` determines which Stripe account is used. If the unit doesn't have Stripe connected, checkout creation fails. Check **Settings → Local Centers → \[Center] → Payments**. Two causes: (1) the subscription wasn't `active` at the time of the event — check the subscription state; (2) the receiver returned non-2xx 3 times in a row, so delivery is in the failed log. Hit `GET /api/v1/webhook_subscriptions/{id}/delivery_logs` and replay. Stripe processes refunds asynchronously — typically 5-10 business days for cards, longer for some debit cards and most international cards. Check the refund status in Stripe's dashboard for the authoritative answer. No. Invoices are immutable once issued (legal requirement). Void the existing invoice and issue a corrected one. The void preserves the audit trail; the new invoice carries a new number. Not via this endpoint. Orgo's payment surface routes everything through Stripe's hosted checkout. For card-on-file MOTO/subscription charges, use the SubscriptionProfile resource — Stripe handles the recurring billing. *** ## What to do next * [Handle webhooks](/docs/api-reference/recipes/handle-webhooks) — react to payment events * [Create and sell event tickets](/docs/api-reference/recipes/create-and-sell-event-tickets) — payment in the ticketing context * [Sync your CRM with Orgo](/docs/api-reference/recipes/sync-your-crm-with-orgo) — push payment events into your accounting system # Run a board election Source: https://orgo.space/docs/api-reference/recipes/run-a-board-election Set up a multi-question vote, eligible-voter list, open and close voting, export results This walkthrough runs an end-to-end e-voting session: board elections, by-law changes, motion votes. It uses the [VoteCollection](/docs/api-reference/votecollection) and Vote resources. Who is this for: governance automation that needs to spin up scheduled votes (annual board elections, quarterly motion ratification), or integrations that synchronize vote outcomes back to a federation's records. *** ## Concepts * A **VoteCollection** is one voting session — usually one meeting, one ratification cycle, or one election. It groups one or more `Vote` records. * A **Vote** is a single question — "Elect Treasurer", "Approve Article 4 amendment". A VoteCollection can have many votes voted on together. * Voting can be **secret** (no audit trail of who voted what) or **public** (each ballot recorded against the voter). *** ## Step 1 — Create the vote collection ```bash theme={null} curl -X POST https://acme.orgo.space/api/v1/vote_collections \ -H "Api-Token: $ORGO_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "name": "Board Election — Spring 2026", "description": "Cast your vote for three open seats on the Boston chapter board.", "dateOpen": "2026-03-15T18:00:00+00:00", "dateClose": "2026-03-15T21:00:00+00:00", "isSecret": true, "unit": "/api/v1/units/4" }' ``` `unit` determines eligibility — only active members in that unit (and any sub-units) can vote. The collection is created in `DRAFT`. You can add questions and edit eligibility while in DRAFT; once published, the question set is locked. Response: ```json theme={null} { "id": 22, "name": "Board Election — Spring 2026", "status": "DRAFT", "isSecret": true, "dateOpen": "2026-03-15T18:00:00+00:00", "dateClose": "2026-03-15T21:00:00+00:00" } ``` *** ## Step 2 — Add questions (Votes) ```bash theme={null} curl -X POST https://acme.orgo.space/api/v1/votes \ -H "Api-Token: $ORGO_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "voteCollection": "/api/v1/vote_collections/22", "question": "Elect the Boston chapter board for 2026-2027.", "questionType": "MULTIPLE_CHOICE", "maxChoices": 3, "minChoices": 1, "choices": [ {"label": "James Patterson"}, {"label": "Emma Whitfield"}, {"label": "Sarah O'\''Connor"}, {"label": "Michael Chen"}, {"label": "Olivia Brown"} ] }' ``` For each question, set `questionType`: | Type | Use for | | ----------------- | ------------------------------------------------------------------ | | `SINGLE_CHOICE` | One-of-many — e.g. "Approve the budget?" with Yes/No/Abstain | | `MULTIPLE_CHOICE` | Up to N selections — e.g. "Pick 3 board members from 5 candidates" | | `RANKED_CHOICE` | Order preferences — e.g. instant-runoff voting | | `OPEN_TEXT` | Free-form responses — for surveys, not binding votes | Add as many questions as the meeting needs. They appear in the order you create them. *** ## Step 3 — Publish (members get notified) Once questions are in place, publish: ```bash theme={null} curl -X PATCH https://acme.orgo.space/api/v1/vote_collections/22 \ -H "Api-Token: $ORGO_API_TOKEN" \ -H "Content-Type: application/merge-patch+json" \ -d '{"status": "PUBLISHED"}' ``` This sends a notification to every eligible voter — push notification + email — with a link to the vote landing page. After this point, you cannot add or edit questions. You can still postpone the open/close dates. *** ## Step 4 — Open voting When the meeting starts (or the calendar reaches `dateOpen` automatically): ```bash theme={null} curl -X PATCH https://acme.orgo.space/api/v1/vote_collections/22 \ -H "Api-Token: $ORGO_API_TOKEN" \ -H "Content-Type: application/merge-patch+json" \ -d '{"status": "OPEN"}' ``` Members can now cast ballots via the member dashboard or `POST /api/v1/votes/{id}/cast` (per question). The `GET /api/v1/has_live_votes` endpoint returns `true` for any user with at least one open VoteCollection they haven't yet voted in — your member app can use this to surface "you have unfinished votes" badges. *** ## Step 5 — Close voting and tally When `dateClose` passes (or you close it manually): ```bash theme={null} curl -X PATCH https://acme.orgo.space/api/v1/vote_collections/22/close \ -H "Api-Token: $ORGO_API_TOKEN" \ -H "Content-Type: application/merge-patch+json" \ -d '{}' ``` Tallying runs automatically. Results are visible immediately on the collection. ```bash theme={null} curl https://acme.orgo.space/api/v1/vote_collections/22 \ -H "Api-Token: $ORGO_API_TOKEN" ``` Response includes per-question results: ```json theme={null} { "id": 22, "status": "CLOSED", "voteCount": 142, "eligibleVoterCount": 312, "turnout": 0.455, "votes": [ { "id": 45, "question": "Elect the Boston chapter board for 2026-2027.", "results": [ {"label": "James Patterson", "count": 98, "percentage": 0.69}, {"label": "Emma Whitfield", "count": 87, "percentage": 0.61}, {"label": "Sarah O'Connor", "count": 76, "percentage": 0.54}, {"label": "Michael Chen", "count": 54, "percentage": 0.38}, {"label": "Olivia Brown", "count": 21, "percentage": 0.15} ] } ] } ``` *** ## Step 6 — Export results For board minutes, federation reporting, or external compliance, export the full result set as CSV: ```bash theme={null} curl https://acme.orgo.space/api/v1/vote_collections/22/export \ -H "Api-Token: $ORGO_API_TOKEN" \ -H "Accept: text/csv" \ -o spring-2026-board-election.csv ``` For non-secret votes, the CSV includes each voter and their choice. For secret votes, only the aggregated counts. *** ## Step 7 — Archive After the results are circulated and the board minutes are signed: ```bash theme={null} curl -X PATCH https://acme.orgo.space/api/v1/vote_collections/22/archive \ -H "Api-Token: $ORGO_API_TOKEN" \ -H "Content-Type: application/merge-patch+json" \ -d '{}' ``` Archived collections are hidden from the default listing (`GET /api/v1/vote_collections`) but accessible via `?status=ARCHIVED`. Results remain queryable indefinitely. *** ## Cloning for the next cycle To run "the same election" next year, clone instead of recreating: ```bash theme={null} curl -X POST https://acme.orgo.space/api/v1/vote_collections/22/clone \ -H "Api-Token: $ORGO_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "name": "Board Election — Spring 2027", "dateOpen": "2027-03-14T18:00:00+00:00", "dateClose": "2027-03-14T21:00:00+00:00" }' ``` Copies the questions and choices into a fresh DRAFT. Update candidate names and re-publish. *** ## Common gotchas The eligibility filter is `User.status == ACTIVE AND member of (unit OR child-units) AND isFeeActive`. Lapsed members (fee expired) are excluded. To include them, transition them to ACTIVE first via the fee renewal flow. Notifications respect the member's notification preferences. If they've disabled push + email for "governance" notifications, they won't be alerted — but they can still cast a vote via the member dashboard while the collection is OPEN. Voters with no email at all are listed in `eligibleVoterCount` but cannot be reached. Yes, while the collection is `OPEN`. Re-cast via `POST /api/v1/votes/{id}/cast`; the latest choice wins. Once `CLOSED`, votes are locked. There's no native quorum gate. Run the close manually and check `turnout` against your bylaws before treating the result as binding. For meetings that may not reach quorum, extend `dateClose` to give more time, or proxy votes (which Orgo doesn't model — capture as `OPEN_TEXT` questions and reconcile out-of-band). Orgo reports raw counts — tie-breaking is governance-level (board chair casts deciding vote, coin flip, runoff election). For a runoff, clone the collection with just the tied candidates and run again. *** ## What to do next * [Permissions](/docs/platform/permissions) — only `HR_LOCAL` and above can create vote collections * [Run a board election](/docs/platform/e-voting) — the admin-side documentation * [Handle webhooks](/docs/api-reference/recipes/handle-webhooks) — react to vote results being finalized # Send a newsletter campaign Source: https://orgo.space/docs/api-reference/recipes/send-a-newsletter-campaign Compose, segment, and send a newsletter — and clone it to non-openers a week later This walkthrough drafts a newsletter, targets a specific audience, sends it, and demonstrates a follow-up pattern (re-sending to people who didn't open). It uses the [Newsletter](/docs/api-reference/newsletter) and [Contact](/docs/api-reference/contact) resources. Who is this for: marketing-automation pipelines that compose campaigns from a CRM, A/B testers running variations, or admin tools that schedule sends ahead of time. *** ## Step 1 — Draft the newsletter Newsletters are owned by a `Unit` — usually a local center or the tenant root. The audience is implicitly everyone in that unit who has newsletter opt-in. ```bash theme={null} curl -X POST https://acme.orgo.space/api/v1/newsletters \ -H "Api-Token: $ORGO_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "name": "January 2026 — Boston Update", "subject": "What'\''s happening at Civic Collective in January", "fromName": "Civic Collective — Boston", "fromEmail": "boston@example.com", "replyToEmail": "boston@example.com", "unit": "/api/v1/units/4", "content": "

January Update

Hello {{firstName}},

Here'\''s what'\''s coming up...

" }' ``` Response: ```json theme={null} { "id": 44, "uuid": "01938d8e-c2f4-7c2a-b8e1-3f7a9b8c4f44", "name": "January 2026 — Boston Update", "status": "DRAFT", "estimatedRecipientCount": 312 } ``` `estimatedRecipientCount` is the count of recipients the current audience filter would target *right now*. It is recalculated each time you fetch the newsletter. ### Placeholders `{{firstName}}`, `{{lastName}}`, `{{email}}` and any tenant custom field are resolved per recipient. Use them anywhere in `content` and they're substituted at send time. *** ## Step 2 — Preview and test-send Always send a test to yourself first. ```bash theme={null} curl -X POST https://acme.orgo.space/api/v1/email_templates/send-test \ -H "Api-Token: $ORGO_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "newsletter": "/api/v1/newsletters/01938d8e-c2f4-7c2a-b8e1-3f7a9b8c4f44", "toEmail": "james.patterson@example.com" }' ``` Check the test email rendered correctly — placeholder substitution, links, images, and unsubscribe footer. *** ## Step 3 — Choose: schedule or send now ### Send immediately ```bash theme={null} curl -X PATCH https://acme.orgo.space/api/v1/newsletters/01938d8e-c2f4-7c2a-b8e1-3f7a9b8c4f44/send \ -H "Api-Token: $ORGO_API_TOKEN" \ -H "Content-Type: application/merge-patch+json" \ -d '{}' ``` Status flips to `SENT`. The actual delivery is queued — large campaigns take a few minutes to flush through SES. ### Schedule for later ```bash theme={null} curl -X PATCH https://acme.orgo.space/api/v1/newsletters/01938d8e-c2f4-7c2a-b8e1-3f7a9b8c4f44/schedule \ -H "Api-Token: $ORGO_API_TOKEN" \ -H "Content-Type: application/merge-patch+json" \ -d '{"sendDate": "2026-01-20T09:00:00-05:00"}' ``` Status flips to `SCHEDULED` and the worker picks it up at the specified time. *** ## Step 4 — Resend to non-openers (one week later) A standard pattern: wait 5-7 days after the initial send, then re-send (with a new subject line) only to people who haven't opened. First check how many would be re-targeted: ```bash theme={null} curl https://acme.orgo.space/api/v1/newsletters/01938d8e-c2f4-7c2a-b8e1-3f7a9b8c4f44/non-openers-count \ -H "Api-Token: $ORGO_API_TOKEN" ``` Then clone the original into a new draft targeting only those non-openers: ```bash theme={null} curl -X POST https://acme.orgo.space/api/v1/newsletters/01938d8e-c2f4-7c2a-b8e1-3f7a9b8c4f44/clone-non-openers \ -H "Api-Token: $ORGO_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "subject": "Reminder — what'\''s happening at Civic Collective in January" }' ``` The clone keeps the body content but you can edit before sending. Then `PATCH /api/v1/newsletters/{uuid}/send` as usual. *** ## Step 5 — Read engagement statistics Once the send completes (typically a few minutes after triggering), opens and clicks start streaming in. Fetch them on the newsletter resource: ```bash theme={null} curl https://acme.orgo.space/api/v1/newsletters/01938d8e-c2f4-7c2a-b8e1-3f7a9b8c4f44 \ -H "Api-Token: $ORGO_API_TOKEN" ``` The response includes `recipientCount`, `openCount`, `clickCount`, and `unsubscribeCount`. *** ## Common gotchas Two filters apply: (1) the `Unit` membership (only people in or under that unit), (2) `isNewsletterSubscribed: true` on each recipient (User or Contact). Run the audience filter manually with `GET /api/v1/users?unit=...&isNewsletterSubscribed=true` to see the same count. Placeholders are case-sensitive and must match exactly. `{{FirstName}}` won't work; neither will `{{ firstName }}` (with spaces). If a recipient's field is null, the placeholder resolves to an empty string — consider wrapping with HTML so empty fields don't leave dangling punctuation. SES has per-tenant sending limits. New tenants are sandboxed (50 emails/day, verified-recipient only) until granted production access. Check `Settings → Developers → Email` for the current quota. Contact support to lift sandbox. Not directly — there's no first-class A/B testing UI. The pattern is: send the campaign to a 10% sample (filter the audience tighter), wait, compare open rates against a held-back variant, then send the winner to the rest. *** ## What to do next * [Sync your CRM with Orgo](/docs/api-reference/recipes/sync-your-crm-with-orgo) — keep contacts subscribed in sync with your CRM source-of-truth * [Handle webhooks](/docs/api-reference/recipes/handle-webhooks) — react to `contact.updated` when someone unsubscribes * [Rate limits](/docs/api-reference/concepts/rate-limits) — newsletter sends carry email-cost rate limits # Sync your CRM with Orgo Source: https://orgo.space/docs/api-reference/recipes/sync-your-crm-with-orgo Two-way contact sync — bulk import from your CRM into Orgo, react to changes via webhooks This walkthrough sets up a two-way sync between an external CRM (HubSpot, Salesforce, Attio, or a homegrown one) and Orgo's [Contact](/docs/api-reference/contact) resource. The pattern: bulk push contacts on a schedule, then keep them in sync incrementally via webhooks. Who is this for: marketing-ops integrations that own the CRM and need to project membership/contact data into Orgo so it can be used in newsletters, event invites, and audience filters. *** ## Architecture in two paragraphs Your CRM is the source of truth for *contact details*. Orgo is the source of truth for *what that contact has done* inside Orgo — events attended, payments made, contracts signed, newsletter engagement. The sync pushes contact details one way and pulls Orgo activity the other way. Day-to-day, both sides change. Without webhooks, you'd have to poll Orgo for "what changed since yesterday?" — expensive and slow. With webhooks, Orgo tells you the moment a contact subscribes, a payment clears, or a contract is signed. We use webhooks for the Orgo → CRM direction. *** ## Step 1 — Bulk import from CRM to Orgo (initial load) Iterate over your CRM and create one Contact per record. The endpoint `POST /api/v1/contacts` returns `409 Conflict` if an email already exists in Orgo (either as a Contact or as a User), so you can rerun safely. ```bash theme={null} curl -X POST https://acme.orgo.space/api/v1/contacts \ -H "Api-Token: $ORGO_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "name": "Olivia Brown", "email": "olivia.brown@example.com", "phone": "+1 415 555 0192", "localCenter": "/api/v1/local_centers/4", "isNewsletterSubscribed": true, "notes": "Imported from HubSpot on 2026-01-15. Source: trade-show signup." }' ``` For thousands of contacts, parallelize with a concurrency cap of \~10 — the per-endpoint rate limit on Contact create is generous, but Stripe/SES upstream limits aren't (some Contact creates trigger welcome emails). ### Conflict handling When `POST` returns `409`, the email already exists. Options: * **Skip** — your CRM was already in sync; no action needed. * **Merge** — look up the existing Contact by email (`GET /api/v1/contacts?email=...`) and `PATCH` it with the fresher CRM data. ```bash theme={null} # Find the existing contact curl "https://acme.orgo.space/api/v1/contacts?email=olivia.brown@example.com" \ -H "Api-Token: $ORGO_API_TOKEN" # Merge CRM updates into it curl -X PATCH https://acme.orgo.space/api/v1/contacts/85 \ -H "Api-Token: $ORGO_API_TOKEN" \ -H "Content-Type: application/merge-patch+json" \ -d '{ "phone": "+1 415 555 0199", "notes": "Updated from HubSpot 2026-01-15." }' ``` *** ## Step 2 — Tag contacts for audience filtering Tags are how Orgo segments contacts in newsletter audiences and event invite filters. Sync your CRM segments to Orgo `ProfileTag` entries. ```bash theme={null} # Create a tag (idempotent — returns 409 if it exists; treat as success) curl -X POST https://acme.orgo.space/api/v1/profile_tags \ -H "Api-Token: $ORGO_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{"name": "donor-2026"}' # Attach the tag to a contact curl -X POST https://acme.orgo.space/api/v1/contacts/85/profile_tags \ -H "Api-Token: $ORGO_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{"profileTag": "/api/v1/profile_tags/14"}' ``` For high-volume tag syncs, run them after the initial Contact import (one round-trip per contact-tag pair is acceptable up to \~10k contacts). *** ## Step 3 — Subscribe to Orgo events Register a webhook so Orgo pushes updates the moment they happen — no polling needed. ```bash theme={null} curl -X POST https://acme.orgo.space/api/v1/webhook_subscriptions \ -H "Api-Token: $ORGO_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "url": "https://your-app.example.com/webhooks/orgo", "events": [ "contact.created", "contact.updated", "contact.deleted", "user.created", "user.updated", "product_payment.created" ], "secret": "whsec_a3f8b2c4d6e8f1a3b5c7d9e1f3a5b7c9", "active": true, "description": "Sync contact + member changes into CRM" }' ``` See [Handle webhooks](/docs/api-reference/recipes/handle-webhooks) for the receiver implementation. *** ## Step 4 — Receive and write back to CRM When Orgo fires a `contact.updated` webhook, your handler: 1. Verifies the signature. 2. Looks up the same contact in your CRM by email. 3. Writes back the fields Orgo owns (newsletter opt-in, last event attended, total payments). The payload shape (Stripe-inspired): ```json theme={null} { "id": "wh_evt_67aa128c2f4a", "event": "contact.updated", "tenant_id": 1, "created": 1735689600, "object": { "@id": "/api/v1/contacts/85", "id": 85, "name": "Olivia Brown", "email": "olivia.brown@example.com", "isNewsletterSubscribed": false }, "previous_attributes": { "isNewsletterSubscribed": true } } ``` `previous_attributes` is the diff — fields not mentioned didn't change. This is enough to detect "unsubscribed" events without diffing against a stored snapshot. *** ## Step 5 — Incremental backfill (catching up after webhook downtime) If your webhook receiver was down for a while, replay missed events with the delivery-log endpoint: ```bash theme={null} curl https://acme.orgo.space/api/v1/webhook_subscriptions/3/delivery_logs \ -H "Api-Token: $ORGO_API_TOKEN" ``` This lists every delivery attempt, success or failure. For each failed delivery, the payload is available — re-process them locally. For longer outages (more than a few days, beyond the log retention), do a delta poll instead: ```bash theme={null} # All contacts updated since the last sync timestamp curl "https://acme.orgo.space/api/v1/contacts?dateUpdated[after]=2026-01-10T00:00:00Z&order[dateUpdated]=asc" \ -H "Api-Token: $ORGO_API_TOKEN" ``` Paginate through and merge into your CRM. Record the highest `dateUpdated` seen as the watermark for the next sync. *** ## Common gotchas Orgo deduplicates by email — but only on `POST /api/v1/contacts`. If your CRM has multiple records for the same person under different emails, Orgo will store them as separate Contacts. Dedupe in your CRM first, or merge in Orgo by `DELETE`-ing the older one and `PATCH`-ing the survivor. When a Contact becomes a User (via adhesion success or invite acceptance), Orgo keeps the Contact record but flips the linked User's status. The `user.created` webhook fires; subscribe to it and update your CRM to point at the User. The Contact remains for historical audit. Check `GET /api/v1/webhook_subscriptions/3/delivery_logs`. Common causes: receiver returning a non-2xx, receiver taking >30s to respond, TLS certificate issues. Orgo retries 3 times with exponential backoff before giving up. Only if you also have authority to skip the adhesion (HR\_TENANT). `POST /api/v1/users` works server-to-server and creates a `NEW` user with an unverified email. The user can't log in until they verify their email. For most CRM use cases, Contacts are the right primitive — promote selected ones to User via the adhesion flow when they're ready to become members. *** ## What to do next * [Handle webhooks](/docs/api-reference/recipes/handle-webhooks) — the receiver implementation in detail * [Send a newsletter campaign](/docs/api-reference/recipes/send-a-newsletter-campaign) — once contacts are synced, target them * [Onboard a new member](/docs/api-reference/recipes/onboard-a-new-member) — promote a Contact into a full member # Delete a referral Source: https://orgo.space/docs/api-reference/referral/delete-a-referral /api-reference/openapi.json delete /api/v1/referrals/{hash} Permanently removes a referral. Requires ADMIN_TENANT permission on the referral user. # Get a referral Source: https://orgo.space/docs/api-reference/referral/get-a-referral /api-reference/openapi.json get /api/v1/referrals/{hash} Returns a single referral with its current status and associated referral users (vouchers). # List referrals Source: https://orgo.space/docs/api-reference/referral/list-referrals /api-reference/openapi.json get /api/v1/referrals Returns a paginated list of referrals within the tenant. Referrals track the vouch-based signup process where existing members vouch for prospective members. # Update a referral Source: https://orgo.space/docs/api-reference/referral/update-a-referral /api-reference/openapi.json patch /api/v1/referrals/{hash} Updates a referral record. Requires ADMIN_TENANT permission. Can be used to change referral status or other administrative fields. # Create a referral user Source: https://orgo.space/docs/api-reference/referraluser/create-a-referral-user /api-reference/openapi.json post /api/v1/referral_users Creates a voucher record for a referral. The authenticated user is set as the voucher unless HR_LOCAL permission allows vouching on behalf of another user. Validates the referral is not already complete (STATUS_SUCCESS). Checks for duplicate vouchers, updates the referral status based on progress, and sends email notifications to all tenant admins with referral progress details. # Delete a referral user Source: https://orgo.space/docs/api-reference/referraluser/delete-a-referral-user /api-reference/openapi.json delete /api/v1/referral_users/{id} Removes a voucher record from a referral. Requires ADMIN_TENANT permission on the referral user. # Get a referral user Source: https://orgo.space/docs/api-reference/referraluser/get-a-referral-user /api-reference/openapi.json get /api/v1/referral_users/{id} Returns a single referral user record. Accessible by the vouching user themselves or users with HR_LOCAL permission on the user local center. # List referral users Source: https://orgo.space/docs/api-reference/referraluser/list-referral-users /api-reference/openapi.json get /api/v1/referral_users Returns a paginated list of referral user records (vouchers). Each record represents one user vouching for a prospective member. # Create a region Source: https://orgo.space/docs/api-reference/region/create-a-region /api-reference/openapi.json post /api/v1/regions Creates a new geographic region within the tenant. Requires ROLE_ADMIN_TENANT permission. # Delete a region Source: https://orgo.space/docs/api-reference/region/delete-a-region /api-reference/openapi.json delete /api/v1/regions/{id} Permanently removes a region. Requires ROLE_ADMIN_TENANT permission. Ensure no local centers are still assigned to this region before deleting. # Get a region Source: https://orgo.space/docs/api-reference/region/get-a-region /api-reference/openapi.json get /api/v1/regions/{id} Returns a single region. Regions are geographic subdivisions used for organizing local centers and users within a tenant. # List regions Source: https://orgo.space/docs/api-reference/region/list-regions /api-reference/openapi.json get /api/v1/regions Returns all regions within the tenant. Returns up to 1000 items per page. Used for populating region dropdowns and geographic filtering. # Update a region Source: https://orgo.space/docs/api-reference/region/update-a-region /api-reference/openapi.json patch /api/v1/regions/{id} Partially updates a region. Requires ROLE_ADMIN_TENANT permission. # Approve a resignation request Source: https://orgo.space/docs/api-reference/resignationrequest/approve-a-resignation-request /api-reference/openapi.json patch /api/v1/resignation_requests/{id}/approve Approves a pending resignation request. Sets status to APPROVED, records the approving user and resignation date. If the tenant setting autoCloseAccountsThatResign is enabled, the member is set to INACTIVE. Otherwise, the stayActive flag on the request determines the member status. Optionally reassigns the member to a guest user type, clears their adhesion if applicable, and ends all active user roles. Sends an approval notification email. # Create a resignation request Source: https://orgo.space/docs/api-reference/resignationrequest/create-a-resignation-request /api-reference/openapi.json post /api/v1/resignation_requests Creates a new resignation request with PENDING status. Sets the authenticated user as the requestedBy. If no target user is specified, the request is created for the authenticated user. Validates the request and sends a notification email to relevant administrators. # Delete a resignation request Source: https://orgo.space/docs/api-reference/resignationrequest/delete-a-resignation-request /api-reference/openapi.json delete /api/v1/resignation_requests/{id} Permanently removes a resignation request. Allowed for ROLE_ADMIN_TENANT, or the user who created the request, or the user the request was created for. # Get a resignation request Source: https://orgo.space/docs/api-reference/resignationrequest/get-a-resignation-request /api-reference/openapi.json get /api/v1/resignation_requests/{id} Returns a single resignation request. Access is checked via the ResignationRequestService to verify the user has permission to view it (request owner, requested-by user, or HR admin). # List resignation requests Source: https://orgo.space/docs/api-reference/resignationrequest/list-resignation-requests /api-reference/openapi.json get /api/v1/resignation_requests Returns a paginated list of resignation requests ordered by creation date (newest first). Returns 30 items per page. # Create a role Source: https://orgo.space/docs/api-reference/role/create-a-role /api-reference/openapi.json post /api/v1/roles Creates a new role within the tenant. Roles define positions within the organizational structure and can be assigned to users within units. Restricted to tenant administrators. # Delete a role Source: https://orgo.space/docs/api-reference/role/delete-a-role /api-reference/openapi.json delete /api/v1/roles/{id} Deletes a role from the tenant. Fails with an error if the role is currently assigned as a user type on any unit. Restricted to tenant administrators with tenant isolation enforced. # Get a role Source: https://orgo.space/docs/api-reference/role/get-a-role /api-reference/openapi.json get /api/v1/roles/{id} Retrieves a single role by ID. Tenant isolation is enforced: only roles belonging to the current user tenant are accessible. # List roles Source: https://orgo.space/docs/api-reference/role/list-roles /api-reference/openapi.json get /api/v1/roles Returns all roles for the current tenant, ordered by unit type. Results are cached when no filters are applied. Page size defaults to 1000. Supports standard API Platform filters. # Update a role Source: https://orgo.space/docs/api-reference/role/update-a-role /api-reference/openapi.json patch /api/v1/roles/{id} Updates role properties such as name and permissions. Automatically recalculates permissions for users assigned to this role (up to 300 users inline; larger sets require async processing). Restricted to tenant administrators. # Create a role group Source: https://orgo.space/docs/api-reference/rolegroup/create-a-role-group /api-reference/openapi.json post /api/v1/role_groups Creates a new role group with optional role and industry associations. Send "roles" (array of role IDs) and/or "industries" (array of industry IDs) in the request body alongside standard fields. Roles must belong to the same tenant. Requires tenant admin permission. # Delete a role group Source: https://orgo.space/docs/api-reference/rolegroup/delete-a-role-group /api-reference/openapi.json delete /api/v1/role_groups/{id} Deletes a role group and its associated role/industry assignments. Validates admin access before deletion. Requires HR_TENANT permission. # Get a role group Source: https://orgo.space/docs/api-reference/rolegroup/get-a-role-group /api-reference/openapi.json get /api/v1/role_groups/{id} Retrieves a single role group with full item-level detail including associated roles and industries. Requires HR_TENANT permission or active membership in the role group. # List role groups Source: https://orgo.space/docs/api-reference/rolegroup/list-role-groups /api-reference/openapi.json get /api/v1/role_groups Returns a paginated list of role groups within the current tenant. Role groups are special units that aggregate users by their organizational roles and optionally by industries. # Update a role group Source: https://orgo.space/docs/api-reference/rolegroup/update-a-role-group /api-reference/openapi.json patch /api/v1/role_groups/{id} Updates a role group including its name, description, and associated roles and industries. Roles and industries are synced: new ones are added and removed ones are deleted. Send "roles" (array of role IDs) and/or "industries" (array of industry IDs) in the request body. Requires tenant admin permission. # Accept a subscription profile Source: https://orgo.space/docs/api-reference/subscriptionprofile/accept-a-subscription-profile /api-reference/openapi.json patch /api/v1/subscription-profile/{id}/accept Marks a subscription profile as accepted by an administrator. Requires FINANCIAL_TENANT permission. Sets the acceptedBy user and acceptedDate. Validates access via the Stripe connected service before acceptance. # Create a pending subscription Source: https://orgo.space/docs/api-reference/subscriptionprofile/create-a-pending-subscription /api-reference/openapi.json post /api/v1/subscription/create-pending Creates a pending subscription for an authenticated user or external contact. Resolves the product, price, option, and local center from the request payload. For authenticated users, links the subscription to their account and checks identity verification status. For anonymous users, creates or retrieves a Contact record. Supports custom pricing for donations. Rejects duplicates unless the previous subscription was canceled. # Create pending subscription for external contact Source: https://orgo.space/docs/api-reference/subscriptionprofile/create-pending-subscription-for-external-contact /api-reference/openapi.json post /api/v1/subscription/external/create-pending Creates a pending subscription for an external (non-member) contact. Resolves the product, price, option, and local center from the request payload. Creates or retrieves a Contact record by email, sets identity verification status, and stores profile fields (organisation, social links, town). Returns existing subscription if already identity-validated. Rejects if a non-canceled subscription already exists for the same product and contact. # Get a pending subscription Source: https://orgo.space/docs/api-reference/subscriptionprofile/get-a-pending-subscription /api-reference/openapi.json get /api/v1/subscription/get-pending/{id} Retrieves a pending subscription ready for payment. Returns an error if the subscription is already active or canceled, or if identity verification has not been completed (status must be IDENTITY_VALIDATED). # Get a subscription profile Source: https://orgo.space/docs/api-reference/subscriptionprofile/get-a-subscription-profile /api-reference/openapi.json get /api/v1/subscription_profiles/{id} Returns a single subscription profile. Requires FINANCIAL_LOCAL permission or ownership of the subscription profile. # List subscription profiles Source: https://orgo.space/docs/api-reference/subscriptionprofile/list-subscription-profiles /api-reference/openapi.json get /api/v1/subscription_profiles Returns a paginated list of subscription profiles. Security is enforced via GetCollectionWithSecureFilterSubscriber: available to ROLE_USER (own subscriptions) and FINANCIAL_LOCAL (local center subscriptions). Returns 20 items per page. # List subscriptions for external contact Source: https://orgo.space/docs/api-reference/subscriptionprofile/list-subscriptions-for-external-contact /api-reference/openapi.json get /api/v1/subscription_profiles_external Returns subscription profiles with additional contact-level detail for external (non-member) contacts. Includes subscription_contact serialization group. # Create a support team Source: https://orgo.space/docs/api-reference/supportteam/create-a-support-team /api-reference/openapi.json post /api/v1/support_teams Adds a user to the support team. Prevents duplicate entries for the same user. The user must belong to the same tenant. Requires tenant admin permission. # Delete a support team Source: https://orgo.space/docs/api-reference/supportteam/delete-a-support-team /api-reference/openapi.json delete /api/v1/support_teams/{id} Removes a user from the support team. Automatically unassigns the user from all issue types and support ticket discussions they were assigned to. Requires tenant admin permission. # Get a support team Source: https://orgo.space/docs/api-reference/supportteam/get-a-support-team /api-reference/openapi.json get /api/v1/support_teams/{id} Retrieves a single support team member entry. Available to all authenticated users. # List support teams Source: https://orgo.space/docs/api-reference/supportteam/list-support-teams /api-reference/openapi.json get /api/v1/support_teams Returns all support team members for the current tenant. Returns up to 100 items per page. Available to all authenticated users. # Update a support team Source: https://orgo.space/docs/api-reference/supportteam/update-a-support-team /api-reference/openapi.json patch /api/v1/support_teams/{id} Updates a support team member entry. Requires tenant admin permission and same-tenant access. # Create a tag Source: https://orgo.space/docs/api-reference/tag/create-a-tag /api-reference/openapi.json post /api/v1/tags Creates a new tag within the tenant. Requires ADMIN_TENANT permission. # Delete a tag Source: https://orgo.space/docs/api-reference/tag/delete-a-tag /api-reference/openapi.json delete /api/v1/tags/{id} Permanently removes a tag. Requires ADMIN_TENANT permission. Entities previously associated with this tag will lose the association. # Get a tag Source: https://orgo.space/docs/api-reference/tag/get-a-tag /api-reference/openapi.json get /api/v1/tags/{id} Returns a single tag with its name and associated metadata. # List tags Source: https://orgo.space/docs/api-reference/tag/list-tags /api-reference/openapi.json get /api/v1/tags Returns a paginated list of tags within the tenant. Tags are used to categorize and label entities such as users, events, and discussions. # Update a tag Source: https://orgo.space/docs/api-reference/tag/update-a-tag /api-reference/openapi.json patch /api/v1/tags/{id} Partially updates a tag. Requires ADMIN_TENANT permission. # Add a comment to a task Source: https://orgo.space/docs/api-reference/task/add-a-comment-to-a-task /api-reference/openapi.json post /api/v1/tasks/{uuid}/comments Posts a new top-level comment on a task. Supports HTML content (sanitized) and media attachments. Sends in-app notifications and emails to the task assignee and creator. Content is sanitized for UTF-8 encoding and XSS prevention. # Create a task Source: https://orgo.space/docs/api-reference/task/create-a-task /api-reference/openapi.json post /api/v1/tasks Creates a new task within a project. Supports rich content via mainPost (HTML body with media attachments), subtasks/checklist items, and multiple assignees in a single request. Requires PROJECT_ACCESS permission on the target project. # Delete a task Source: https://orgo.space/docs/api-reference/task/delete-a-task /api-reference/openapi.json delete /api/v1/tasks/{uuid} Permanently deletes a task and its associated comments, history, and assignee records. Requires PROJECT_EDIT permission (project owner or tenant admin). # Get a task Source: https://orgo.space/docs/api-reference/task/get-a-task /api-reference/openapi.json get /api/v1/tasks/{uuid} Retrieves a single task with all details including assignees, status, subtasks, and blocking dependencies. Requires PROJECT_ACCESS permission on the parent project. # List my assigned tasks Source: https://orgo.space/docs/api-reference/task/list-my-assigned-tasks /api-reference/openapi.json get /api/v1/my-tasks Returns open tasks assigned to the current user across all active projects. Includes tasks assigned via both legacy assignee field and multi-assignee relationships. Ordered by due date (soonest first, nulls last), then by priority. Accepts an optional limit parameter (default 10, max 50). # List task comments Source: https://orgo.space/docs/api-reference/task/list-task-comments /api-reference/openapi.json get /api/v1/tasks/{uuid}/comments Returns comments on a task ordered by creation date ascending. Supports filtering by parent comment ID for threaded replies. Includes emoji reactions on each comment. Use exists[parent]=false to get only top-level comments. # List tasks Source: https://orgo.space/docs/api-reference/task/list-tasks /api-reference/openapi.json get /api/v1/tasks Returns a paginated list of tasks within the current tenant. Filterable by project, status, assignee, and other standard API Platform filters. # Reply to a task comment Source: https://orgo.space/docs/api-reference/task/reply-to-a-task-comment /api-reference/openapi.json post /api/v1/tasks/{uuid}/comments/reply Posts a reply to an existing task comment. Requires a parent comment ID in the request body. Sends an in-app notification to the parent comment author (unless replying to own comment). Supports media attachments. # Update a task Source: https://orgo.space/docs/api-reference/task/update-a-task /api-reference/openapi.json patch /api/v1/tasks/{uuid} Updates task properties including status, priority, assignees, due date, subtasks, blocking dependencies, and rich content. All changes are tracked in task history. Validates circular dependency chains and prevents closing tasks with incomplete blockers. Accessible by admin, project owner, assignee, or task creator. # Assign user to a task Source: https://orgo.space/docs/api-reference/taskassignee/assign-user-to-a-task /api-reference/openapi.json post /api/v1/task_assignees Assigns a user to a task. Prevents duplicate assignments to the same task. The user must belong to the same tenant. Requires PROJECT_ACCESS permission on the parent project. # Get a task assignee Source: https://orgo.space/docs/api-reference/taskassignee/get-a-task-assignee /api-reference/openapi.json get /api/v1/task_assignees/{uuid} Retrieves a single task assignee record including completion status. Requires PROJECT_ACCESS permission on the parent project. # List task assignees Source: https://orgo.space/docs/api-reference/taskassignee/list-task-assignees /api-reference/openapi.json get /api/v1/task_assignees Returns all assignee records for tasks within the current tenant. Filterable by task or user via standard API Platform filters. # Remove assignee from a task Source: https://orgo.space/docs/api-reference/taskassignee/remove-assignee-from-a-task /api-reference/openapi.json delete /api/v1/task_assignees/{uuid} Removes a user assignment from a task. Requires PROJECT_EDIT permission on the parent project. # Toggle task completion status Source: https://orgo.space/docs/api-reference/taskassignee/toggle-task-completion-status /api-reference/openapi.json post /api/v1/task_assignees/{uuid}/toggle-complete Toggles the completion status of a task assignment for a specific assignee. Only the assigned user themselves or a tenant admin can toggle completion. Requires PROJECT_ACCESS permission on the parent project. # Creates a TenantProfessionDisabled resource. Source: https://orgo.space/docs/api-reference/tenantprofessiondisabled/creates-a-tenantprofessiondisabled-resource /api-reference/openapi.json post /api/v1/tenant_profession_disableds Creates a TenantProfessionDisabled resource. # Removes the TenantProfessionDisabled resource. Source: https://orgo.space/docs/api-reference/tenantprofessiondisabled/removes-the-tenantprofessiondisabled-resource /api-reference/openapi.json delete /api/v1/tenant_profession_disableds/{id} Removes the TenantProfessionDisabled resource. # Retrieves a TenantProfessionDisabled resource. Source: https://orgo.space/docs/api-reference/tenantprofessiondisabled/retrieves-a-tenantprofessiondisabled-resource /api-reference/openapi.json get /api/v1/tenant_profession_disableds/{id} Retrieves a TenantProfessionDisabled resource. # Retrieves the collection of TenantProfessionDisabled resources. Source: https://orgo.space/docs/api-reference/tenantprofessiondisabled/retrieves-the-collection-of-tenantprofessiondisabled-resources /api-reference/openapi.json get /api/v1/tenant_profession_disableds Retrieves the collection of TenantProfessionDisabled resources. # Updates the TenantProfessionDisabled resource. Source: https://orgo.space/docs/api-reference/tenantprofessiondisabled/updates-the-tenantprofessiondisabled-resource /api-reference/openapi.json patch /api/v1/tenant_profession_disableds/{id} Updates the TenantProfessionDisabled resource. # Create a topic Source: https://orgo.space/docs/api-reference/topic/create-a-topic /api-reference/openapi.json post /api/v1/topics Creates a new topic within the tenant. Available to authenticated users. # Delete a topic Source: https://orgo.space/docs/api-reference/topic/delete-a-topic /api-reference/openapi.json delete /api/v1/topics/{id} Permanently removes a topic. Requires ADMIN_TENANT permission. Discussions associated with this topic will lose the association. # Get a topic Source: https://orgo.space/docs/api-reference/topic/get-a-topic /api-reference/openapi.json get /api/v1/topics/{id} Returns a single topic. Requires ADMIN_TENANT permission. # List topics Source: https://orgo.space/docs/api-reference/topic/list-topics /api-reference/openapi.json get /api/v1/topics Returns a paginated list of topics within the tenant. Topics are used to categorize discussions and content. # Update a topic Source: https://orgo.space/docs/api-reference/topic/update-a-topic /api-reference/openapi.json patch /api/v1/topics/{id} Partially updates a topic. Requires ADMIN_TENANT permission. # Create a topic type Source: https://orgo.space/docs/api-reference/topictype/create-a-topic-type /api-reference/openapi.json post /api/v1/topic_types Creates a new topic type that can be used to categorize discussions within namespaces. # Get a topic type Source: https://orgo.space/docs/api-reference/topictype/get-a-topic-type /api-reference/openapi.json get /api/v1/topic_types/{id} Retrieves a single topic type by ID. Topic types define categories that can be assigned to discussions within a namespace. # List topic types Source: https://orgo.space/docs/api-reference/topictype/list-topic-types /api-reference/openapi.json get /api/v1/topic_types Returns all topic types for the current tenant, paginated at 100 items per page. Topic types are used to categorize discussions within namespaces. # Get a town Source: https://orgo.space/docs/api-reference/town/get-a-town /api-reference/openapi.json get /api/v1/towns/{id} Returns a single town with its name, county, country, and population data. # List towns Source: https://orgo.space/docs/api-reference/town/list-towns /api-reference/openapi.json get /api/v1/towns Returns a paginated list of towns ordered by population (descending), then name, then county name. Returns 20 items per page. Used for address selection and geographic filtering. Supports keyword search filtering. # Assign a trainer to a training Source: https://orgo.space/docs/api-reference/trainingtrainer/assign-a-trainer-to-a-training /api-reference/openapi.json post /api/v1/training_trainers Creates a new trainer-to-training assignment, linking a user as a trainer for a specific training event. # Get a training trainer Source: https://orgo.space/docs/api-reference/trainingtrainer/get-a-training-trainer /api-reference/openapi.json get /api/v1/training_trainers/{id} Retrieves a single training trainer assignment by its identifier. # List training trainers Source: https://orgo.space/docs/api-reference/trainingtrainer/list-training-trainers /api-reference/openapi.json get /api/v1/training_trainers Returns all trainer assignments for trainings, paginated at 100 items per page. # Remove a trainer from a training Source: https://orgo.space/docs/api-reference/trainingtrainer/remove-a-trainer-from-a-training /api-reference/openapi.json delete /api/v1/training_trainers/{id} Removes a trainer assignment from a training. Only the training event owner or users with ADMIN_TENANT permission can perform this action. # Create a training type Source: https://orgo.space/docs/api-reference/trainingtype/create-a-training-type /api-reference/openapi.json post /api/v1/training_types Creates a new training type. Requires ADMIN_TENANT permission. # Delete a training type Source: https://orgo.space/docs/api-reference/trainingtype/delete-a-training-type /api-reference/openapi.json delete /api/v1/training_types/{id} Deletes a training type. Requires ADMIN_TENANT permission and tenant ownership of the resource. # Get a training type Source: https://orgo.space/docs/api-reference/trainingtype/get-a-training-type /api-reference/openapi.json get /api/v1/training_types/{id} Retrieves a single training type by its identifier. # List training types Source: https://orgo.space/docs/api-reference/trainingtype/list-training-types /api-reference/openapi.json get /api/v1/training_types Returns all training types for the current tenant, paginated at 1000 items per page. Training types categorize trainings offered within the organization. # Update a training type Source: https://orgo.space/docs/api-reference/trainingtype/update-a-training-type /api-reference/openapi.json patch /api/v1/training_types/{id} Updates an existing training type. Requires ADMIN_TENANT permission and tenant ownership of the resource. # Create a unit Source: https://orgo.space/docs/api-reference/unit/create-a-unit /api-reference/openapi.json post /api/v1/units Creates a new unit under the tenant. If the unit type is marked as local, the unit is automatically assigned to the current user local center. HR_TENANT can create any unit type; HR_LOCAL can create standard units only. Local centers and role groups require HR_TENANT permission. # Delete a unit Source: https://orgo.space/docs/api-reference/unit/delete-a-unit /api-reference/openapi.json delete /api/v1/units/{id} Deletes a unit and its associated data (roles, members, etc.). Requires unit admin access, verified through the unit permission hierarchy. # Get a unit Source: https://orgo.space/docs/api-reference/unit/get-a-unit /api-reference/openapi.json get /api/v1/units/{id} Retrieves a single unit by ID. For groups, validates access based on group visibility and membership. For role groups, requires HR_TENANT permission or active membership in the role group. # List tenant role groups Source: https://orgo.space/docs/api-reference/unit/list-tenant-role-groups /api-reference/openapi.json get /api/v1/tenant-role-groups Returns all role groups configured for the current tenant. Role groups are special units that automatically aggregate users based on their assigned roles. # List unit user roles Source: https://orgo.space/docs/api-reference/unit/list-unit-user-roles /api-reference/openapi.json get /api/v1/unit-user-roles Returns all active units for a given local center with their nested user role assignments. Requires the "localCenter" query parameter and HR_LOCAL permission on that local center. Each unit includes its members with full user details and role information. # List units Source: https://orgo.space/docs/api-reference/unit/list-units /api-reference/openapi.json get /api/v1/units Returns a paginated list of units within the current tenant, ordered by user type. Default page size is 200. Supports standard API Platform filters. # Record a group visit Source: https://orgo.space/docs/api-reference/unit/record-a-group-visit /api-reference/openapi.json post /api/v1/units/{id}/record-visit Records that the current user visited a unit/group page. Used for tracking recently visited groups and activity analytics. No request body needed. # Update a unit Source: https://orgo.space/docs/api-reference/unit/update-a-unit /api-reference/openapi.json patch /api/v1/units/{id} Updates unit properties such as name, description, and settings. Requires unit admin access, verified through the unit permission hierarchy. # Create a unit industry Source: https://orgo.space/docs/api-reference/unitindustry/create-a-unit-industry /api-reference/openapi.json post /api/v1/unit_industries Associates a profession industry with a unit, categorizing the unit under that industry. # Delete a unit industry Source: https://orgo.space/docs/api-reference/unitindustry/delete-a-unit-industry /api-reference/openapi.json delete /api/v1/unit_industries/{id} Removes an industry association from a unit. # Get a unit industry Source: https://orgo.space/docs/api-reference/unitindustry/get-a-unit-industry /api-reference/openapi.json get /api/v1/unit_industries/{id} Retrieves a single unit-industry association by ID. # List unit industries Source: https://orgo.space/docs/api-reference/unitindustry/list-unit-industries /api-reference/openapi.json get /api/v1/unit_industries Returns all industry associations for units within the current tenant. Unit industries link profession industries to specific units for categorization. # Update a unit industry Source: https://orgo.space/docs/api-reference/unitindustry/update-a-unit-industry /api-reference/openapi.json patch /api/v1/unit_industries/{id} Updates the properties of a unit-industry association. # Create a unit role Source: https://orgo.space/docs/api-reference/unitrole/create-a-unit-role /api-reference/openapi.json post /api/v1/unit_roles Assigns a role to a unit, making that role available for user assignments within the unit. # Delete a unit role Source: https://orgo.space/docs/api-reference/unitrole/delete-a-unit-role /api-reference/openapi.json delete /api/v1/unit_roles/{id} Removes a role assignment from a unit. Users currently holding this role within the unit may lose their assignment. # Get a unit role Source: https://orgo.space/docs/api-reference/unitrole/get-a-unit-role /api-reference/openapi.json get /api/v1/unit_roles/{id} Retrieves a single unit-role assignment by ID, including the associated unit and role details. # List unit roles Source: https://orgo.space/docs/api-reference/unitrole/list-unit-roles /api-reference/openapi.json get /api/v1/unit_roles Returns all role assignments within units for the current tenant. Unit roles define which organizational roles are available within a specific unit. # Update a unit role Source: https://orgo.space/docs/api-reference/unitrole/update-a-unit-role /api-reference/openapi.json patch /api/v1/unit_roles/{id} Updates the properties of a unit-role assignment. # Create a unit type Source: https://orgo.space/docs/api-reference/unittype/create-a-unit-type /api-reference/openapi.json post /api/v1/unit_types Creates a new unit type for the tenant. Unit types define the structure of the organizational hierarchy. Restricted to tenant administrators. # Delete a unit type Source: https://orgo.space/docs/api-reference/unittype/delete-a-unit-type /api-reference/openapi.json delete /api/v1/unit_types/{id} Deletes a unit type. Ensure no units are currently using this type before deletion. Tenant isolation is enforced. Restricted to tenant administrators. # Get a unit type Source: https://orgo.space/docs/api-reference/unittype/get-a-unit-type /api-reference/openapi.json get /api/v1/unit_types/{id} Retrieves a single unit type by ID, including its configuration such as whether it is local-scoped. # List unit types Source: https://orgo.space/docs/api-reference/unittype/list-unit-types /api-reference/openapi.json get /api/v1/unit_types Returns all unit types for the current tenant, ordered by discriminator. Unit types define the categories of organizational units (e.g., committee, department, chapter). Page size defaults to 1000. # Update a unit type Source: https://orgo.space/docs/api-reference/unittype/update-a-unit-type /api-reference/openapi.json patch /api/v1/unit_types/{id} Updates unit type properties such as name and local scope setting. Tenant isolation is enforced. Restricted to tenant administrators. # Change user email Source: https://orgo.space/docs/api-reference/user/change-user-email /api-reference/openapi.json patch /api/v1/users/{id}/new-email Initiates an email change for a user. Admins (ADMIN_LOCAL or HR_TENANT) can change the email immediately; non-admin users trigger a confirmation email to the current address. Validates that the new email is not already registered. The change is logged for audit purposes. Accessible by the user themselves, local admins, or parent-level admins. # Change user password Source: https://orgo.space/docs/api-reference/user/change-user-password /api-reference/openapi.json patch /api/v1/users/{id}/new-password Changes the password for a user. Accepts newPassword and optionally currentPassword for verification. If currentPassword is omitted (OTP login flow), the password is set directly. Supports skipPasswordSetup to clear the forcePasswordReset flag without changing the password. Password changes propagate to all accounts sharing the same email across tenants. # Delete a user Source: https://orgo.space/docs/api-reference/user/delete-a-user /api-reference/openapi.json delete /api/v1/users/{id} Permanently deletes a user account. Restricted to ROLE_SUPER_ADMIN only. This action is irreversible and removes all associated data. # Export users as CSV Source: https://orgo.space/docs/api-reference/user/export-users-as-csv /api-reference/openapi.json get /api/v1/users-csv Exports users as a CSV file (up to 500 per page). Requires HR_TENANT permission for full export, or HR_LOCAL with a localCenter filter parameter for scoped export. Logs the export action for audit. Supports the same filters as the standard user list endpoint. Returns text/csv content type. # Get a user Source: https://orgo.space/docs/api-reference/user/get-a-user /api-reference/openapi.json get /api/v1/users/{id} Returns the public profile of a user within the same tenant. Enforces profile privacy settings at both user and tenant level. Deleted users return an error, and inactive users are only visible to HR admins. When tenant-level profile privatization is enabled, only users sharing common units (groups, local centers) or admins can view profiles. # Get current authenticated user Source: https://orgo.space/docs/api-reference/user/get-current-authenticated-user /api-reference/openapi.json get /api/v1/me Returns the full profile of the currently authenticated user including private fields, roles, and tenant settings. Refreshes the user's permissions on each call (unless impersonating). Auto-detects and sets the user's timezone from the HTTP_USER_TIMEZONE header if not already set. Also logs the access event for activity tracking. # Get user identity documents Source: https://orgo.space/docs/api-reference/user/get-user-identity-documents /api-reference/openapi.json get /api/v1/user-identity/{id} Returns the user profile with identity document information (adhesion identity data). Accessible only by the user themselves or users with HR_TENANT permission. # Get user map clusters Source: https://orgo.space/docs/api-reference/user/get-user-map-clusters /api-reference/openapi.json get /api/v1/map-clusters Returns clustered user locations for interactive map display. Requires viewport bounds (north, south, east, west) and optional zoom level. Cluster precision adjusts automatically based on zoom (from 111m at street level to 1110km at world view). Supports filters: status, unit, professionIndustry, localCenter, townCurrent, country, fullMember, customField, permission, feeType, feeStatus, keyword, userType. Returns cluster coordinates with counts and actual bounds for map fitting. # Get user personal drive files Source: https://orgo.space/docs/api-reference/user/get-user-personal-drive-files /api-reference/openapi.json get /api/v1/users/{id}/personal-drive Returns files and folders from a user's personal drive. Supports an optional parent query parameter to navigate subdirectories. Access is controlled by DrivePermissionService -- users can view their own drive, and admins can view drives within their scope. Cross-tenant access is denied. # List user recommendations Source: https://orgo.space/docs/api-reference/user/list-user-recommendations /api-reference/openapi.json get /api/v1/user-recommendations Returns a paginated list of recommended users based on a scoring algorithm (cached for 48 hours). Recommendations are scoped by tenant visibility settings: general unit access or local center access. Returns up to 50 total recommendations with a recommendationScore for each. Supports page and itemsPerPage query parameters. # List users Source: https://orgo.space/docs/api-reference/user/list-users /api-reference/openapi.json get /api/v1/users Returns a paginated list of users in the current tenant (50 per page). Supports standard API Platform filters including keyword search, localCenter, status, professionIndustry, townCurrent, country, permissions, feeType, customField, and ordering. Collection-level tenant isolation is enforced via Doctrine extensions. # List users for map display Source: https://orgo.space/docs/api-reference/user/list-users-for-map-display /api-reference/openapi.json get /api/v1/users-map-list Returns a paginated list of users with map coordinates for list+map views. Includes lightweight user data (name, photo, profession, location) optimized for performance. Respects privacy settings (town privacy, profile privatization) and hides minors unless user has HR permissions. Supports the same filters as map-clusters plus bounds-based filtering. Returns actualBounds calculated from SQL aggregation for initial map positioning. # List users with fee prices Source: https://orgo.space/docs/api-reference/user/list-users-with-fee-prices /api-reference/openapi.json get /api/v1/users-with-fee-price Returns a paginated list of users with fee-related data (fee type, payment status, valid fee date). Intended for financial administration views to review membership fee statuses. # List users with profession data Source: https://orgo.space/docs/api-reference/user/list-users-with-profession-data /api-reference/openapi.json get /api/v1/users-profession Returns a paginated list of users with profession-specific serialization groups (industry, job title, organisation). Useful for member directories filtered by professional attributes. # Register a child account Source: https://orgo.space/docs/api-reference/user/register-a-child-account /api-reference/openapi.json post /api/v1/register-child Creates a child user account linked to the authenticated parent user. Automatically creates or reuses the parent's FamilyEntity and adds both parent and child as FamilyMembers. If the tenant has waitlist enabled and the child's local center qualifies, the child is placed on the waitlist. Supports optional fields: email, gender, dateBirth, phoneNumber, address, localCenter. Returns waitlist entry details if applicable. # Register a member as admin Source: https://orgo.space/docs/api-reference/user/register-a-member-as-admin /api-reference/openapi.json post /api/v1/member-register-by-admin Creates a new user account on behalf of an admin. Requires HR_LOCAL or higher. Sets forcePasswordReset, assigns the user to the admin's local center (if not HR_TENANT), validates email uniqueness, and sends a welcome email with login link. Supports optional rawUserRoles and userType in the payload. The user status is determined by the tenant's defaultStatusForAdminRegistration setting. # Register a new user Source: https://orgo.space/docs/api-reference/user/register-a-new-user /api-reference/openapi.json post /api/v1/users Public self-registration endpoint. Creates a new user in the specified tenant (via tenant IRI or tenantSlug). Includes anti-spam protection (honeypot field, form completion time check). Supports optional parentOptIn, volunteeringOptIn, userTypeSlug for role assignment, referrerId for referral tracking, and companyInvitationHash for company invitation acceptance. If no password is provided, a random one is generated with forcePasswordReset enabled. # Update a user as admin Source: https://orgo.space/docs/api-reference/user/update-a-user-as-admin /api-reference/openapi.json patch /api/v1/users/{id} Updates a user profile with admin-level fields (status, permissions, admin-only attributes). Requires HR_LOCAL permission for the user's local center or parent-level access. Also persists custom field values submitted in the request payload. Permission validation for customPermissions is enforced via a Doctrine listener. # Update own profile Source: https://orgo.space/docs/api-reference/user/update-own-profile /api-reference/openapi.json patch /api/v1/profile-update/{id} Allows a user to update their own profile fields (name, bio, contact info, etc.). The authenticated user can only edit their own profile -- attempting to edit another user's profile returns a 403 error. Also persists custom field values included in the request. # Update user roles Source: https://orgo.space/docs/api-reference/user/update-user-roles /api-reference/openapi.json patch /api/v1/users/{id}/update-roles Bulk-updates all roles for a user. Accepts rawUserRoles (array of roleId_unitId strings) and optional userType. Compares against existing active roles to determine additions and removals. Requires HR_LOCAL or higher permission; tenant setting allowLocalAdminsToModifyUserPermissions can restrict local admins to unit-level roles only. Creates notifications for role changes and updates role groups and permissions. Also supports multiLocalCenterAccess entries when the tenant feature is enabled. # Create an API token Source: https://orgo.space/docs/api-reference/userapitoken/create-an-api-token /api-reference/openapi.json post /api/v1/user-api-tokens Generates a new API token for the authenticated admin user. Accepts optional name, expiresAt, and isReadOnly fields in the request body. The raw token value is returned only once in the response and cannot be retrieved later. Requires ADMIN_TENANT permission. # Delete an API token Source: https://orgo.space/docs/api-reference/userapitoken/delete-an-api-token /api-reference/openapi.json delete /api/v1/user-api-tokens/{id} Permanently deletes an API token. Users can only delete their own tokens. Requires ADMIN_TENANT permission. # List API tokens Source: https://orgo.space/docs/api-reference/userapitoken/list-api-tokens /api-reference/openapi.json get /api/v1/user-api-tokens Returns all API tokens for the current tenant. Requires ADMIN_TENANT permission. Token secrets are not included in the response. # Revoke an API token Source: https://orgo.space/docs/api-reference/userapitoken/revoke-an-api-token /api-reference/openapi.json patch /api/v1/user-api-tokens/{id}/revoke Revokes an active API token, preventing further API access. Users can only revoke their own tokens. Requires ADMIN_TENANT permission. # Accept or reject a connection request Source: https://orgo.space/docs/api-reference/userconnection/accept-or-reject-a-connection-request /api-reference/openapi.json patch /api/v1/user_connections/{id} Updates a pending connection request status. Only the recipient can accept or reject. The connection must be in pending state. # Get a connection Source: https://orgo.space/docs/api-reference/userconnection/get-a-connection /api-reference/openapi.json get /api/v1/user_connections/{id} Retrieves a single connection record. Only the requester or recipient of the connection can view it. # Get connection status with a user Source: https://orgo.space/docs/api-reference/userconnection/get-connection-status-with-a-user /api-reference/openapi.json get /api/v1/user-connection-status/{targetUserId} Returns the connection status between the current user and the target user. Possible statuses: self (same user), connected, pending_sent, pending_received, cooldown (recently rejected, includes cooldownEndDate), or none. # Get total connection count Source: https://orgo.space/docs/api-reference/userconnection/get-total-connection-count /api-reference/openapi.json get /api/v1/user-connection-count Returns the total number of accepted connections for the current user. # List accepted connections Source: https://orgo.space/docs/api-reference/userconnection/list-accepted-connections /api-reference/openapi.json get /api/v1/user-connections-accepted Returns all accepted (active) connections for the current user. # List pending connection requests Source: https://orgo.space/docs/api-reference/userconnection/list-pending-connection-requests /api-reference/openapi.json get /api/v1/user-connections-pending Returns pending connection requests received by the current user that are awaiting a response. # List sent connection requests Source: https://orgo.space/docs/api-reference/userconnection/list-sent-connection-requests /api-reference/openapi.json get /api/v1/user-connections-sent Returns connection requests sent by the current user that are still pending a response from the recipient. # List user connections Source: https://orgo.space/docs/api-reference/userconnection/list-user-connections /api-reference/openapi.json get /api/v1/user-connections Returns a paginated list of user connections for the current user, including pending, accepted, and rejected connections. Paginated at 30 items per page. # Remove a connection Source: https://orgo.space/docs/api-reference/userconnection/remove-a-connection /api-reference/openapi.json delete /api/v1/user_connections/{id} Removes a connection. For accepted connections, fully deletes the record (disconnect). For pending connections, marks as rejected which triggers a cooldown period preventing immediate re-requests. Either party can perform this action. # Send a connection request Source: https://orgo.space/docs/api-reference/userconnection/send-a-connection-request /api-reference/openapi.json post /api/v1/user-connections Sends a connection request from the authenticated user to a target user. Creates a connection with pending status. The recipient must accept before the connection is established. # Create a user list Source: https://orgo.space/docs/api-reference/userlist/create-a-user-list /api-reference/openapi.json post /api/v1/user_lists Creates a new user list. Tenant and owner are set server-side from the authenticated user. Lists can be static (members added manually via user list links) or dynamic (members computed from criteria and scope). Requires HR_TENANT or COMMUNICATION_TENANT permission. # Delete a user list Source: https://orgo.space/docs/api-reference/userlist/delete-a-user-list /api-reference/openapi.json delete /api/v1/user_lists/{id} Deletes a user list and all its member links. Requires HR_TENANT or COMMUNICATION_TENANT permission. # Get a user list Source: https://orgo.space/docs/api-reference/userlist/get-a-user-list /api-reference/openapi.json get /api/v1/user_lists/{id} Retrieves a single user list by its identifier, including its type, criteria, and scope configuration. Requires HR_TENANT or COMMUNICATION_TENANT permission. # Get members from a user list Source: https://orgo.space/docs/api-reference/userlist/get-members-from-a-user-list /api-reference/openapi.json get /api/v1/user_lists/{id}/members/{type} Returns the members of a user list. The type parameter controls filtering: omit for subscribed only, "all" for all members, "not-subscribed" for non-subscribed. For dynamic lists, members are computed from criteria and scope (members only, contacts only, or both). For static lists, returns user list links with user and contact data. # List user lists Source: https://orgo.space/docs/api-reference/userlist/list-user-lists /api-reference/openapi.json get /api/v1/user_lists Returns all user lists for the current tenant. User lists can be static (manually curated) or dynamic (criteria-based). Requires HR_TENANT or COMMUNICATION_TENANT permission. # Update a user list Source: https://orgo.space/docs/api-reference/userlist/update-a-user-list /api-reference/openapi.json patch /api/v1/user_lists/{id} Updates user list properties such as name, criteria, and scope. Requires HR_TENANT or COMMUNICATION_TENANT permission. # Create a user list link Source: https://orgo.space/docs/api-reference/userlistlink/create-a-user-list-link /api-reference/openapi.json post /api/v1/user_list_links Adds a user or contact to a static user list by creating a link record. The link must reference either a user or a contact. Requires ADMIN_TENANT permission. # Delete a user list link Source: https://orgo.space/docs/api-reference/userlistlink/delete-a-user-list-link /api-reference/openapi.json delete /api/v1/user_list_links/{id} Removes a user or contact from a static user list by deleting the link record. Requires ADMIN_TENANT permission. # Get a user list link Source: https://orgo.space/docs/api-reference/userlistlink/get-a-user-list-link /api-reference/openapi.json get /api/v1/user_list_links/{id} Retrieves a single user list link by its identifier, showing the associated user list and linked user or contact. Requires ADMIN_TENANT permission. # List user list links Source: https://orgo.space/docs/api-reference/userlistlink/list-user-list-links /api-reference/openapi.json get /api/v1/user_list_links Returns all user list links for the current tenant. Each link connects a user or contact to a static user list. Requires ADMIN_TENANT permission. # Creates a UserOption resource. Source: https://orgo.space/docs/api-reference/useroption/creates-a-useroption-resource /api-reference/openapi.json post /api/v1/user_options Creates a UserOption resource. # Removes the UserOption resource. Source: https://orgo.space/docs/api-reference/useroption/removes-the-useroption-resource /api-reference/openapi.json delete /api/v1/user_options/{id} Removes the UserOption resource. # Retrieves a UserOption resource. Source: https://orgo.space/docs/api-reference/useroption/retrieves-a-useroption-resource /api-reference/openapi.json get /api/v1/user_options/{id} Retrieves a UserOption resource. # Retrieves the collection of UserOption resources. Source: https://orgo.space/docs/api-reference/useroption/retrieves-the-collection-of-useroption-resources /api-reference/openapi.json get /api/v1/user_options Retrieves the collection of UserOption resources. # Updates the UserOption resource. Source: https://orgo.space/docs/api-reference/useroption/updates-the-useroption-resource /api-reference/openapi.json patch /api/v1/user_options/{id} Updates the UserOption resource. # Create a user role Source: https://orgo.space/docs/api-reference/userrole/create-a-user-role /api-reference/openapi.json post /api/v1/user_roles Assigns a user to a unit with a specific role. Permission checks vary by unit type: RoleGroup requires HR_TENANT or group admin, Group requires group admin, LocalCenter requires HR_LOCAL. Automatically creates a UserUnitRoleGroup record and a follow relationship for the user. Admin flag assignment requires group admin or HR_TENANT permission. # Delete a user role Source: https://orgo.space/docs/api-reference/userrole/delete-a-user-role /api-reference/openapi.json delete /api/v1/user_roles/{id} Removes a user role assignment. Requires HR_LOCAL permission on the user local center (for unit or user-type roles) or HR_TENANT permission. # Get a user role Source: https://orgo.space/docs/api-reference/userrole/get-a-user-role /api-reference/openapi.json get /api/v1/user_roles/{id} Retrieves a single user role assignment by its identifier, including the associated user, unit, and role details. # Join a group via invite link Source: https://orgo.space/docs/api-reference/userrole/join-a-group-via-invite-link /api-reference/openapi.json post /api/v1/group/join Allows the authenticated user to join a group via an invite link. The group must be marked as joinable and belong to the same tenant. Prevents duplicate membership. Sets the user as a regular member (no admin or role assignment). # List members for org chart Source: https://orgo.space/docs/api-reference/userrole/list-members-for-org-chart /api-reference/openapi.json get /api/v1/chart-members Returns user role assignments formatted for organizational chart display, paginated at 100 items per page. Uses a specialized serialization group optimized for chart rendering. # List user roles Source: https://orgo.space/docs/api-reference/userrole/list-user-roles /api-reference/openapi.json get /api/v1/user_roles Returns a paginated list of user role assignments, ordered by end date descending. Paginated at 20 items per page. # Update a user role Source: https://orgo.space/docs/api-reference/userrole/update-a-user-role /api-reference/openapi.json patch /api/v1/user_roles/{id} Updates a user role assignment (e.g., change role, set end date, toggle admin flag). Requires HR_LOCAL permission on the user local center (for unit or user-type roles) or HR_TENANT permission. # Export user role groups as CSV Source: https://orgo.space/docs/api-reference/userunitrolegroup/export-user-role-groups-as-csv /api-reference/openapi.json get /api/v1/users-role-group-csv Exports user-unit-role-group data as a CSV file. Requires the unit query parameter specifying a role group. For non-HR_TENANT users, the role group must belong to a local center where the user has HR_LOCAL permission. Logs the export action for audit purposes. Maximum 500 records per page. # Get a user unit role group Source: https://orgo.space/docs/api-reference/userunitrolegroup/get-a-user-unit-role-group /api-reference/openapi.json get /api/v1/user_unit_role_groups/{id} Retrieves a single user-unit-role-group membership record by its identifier, including the associated user and unit details. # List user unit role groups Source: https://orgo.space/docs/api-reference/userunitrolegroup/list-user-unit-role-groups /api-reference/openapi.json get /api/v1/user_unit_role_groups Returns a paginated list of user-unit-role-group membership records, showing which users belong to which units. Paginated at 50 items per page. # Create a vote Source: https://orgo.space/docs/api-reference/vote/create-a-vote /api-reference/openapi.json post /api/v1/votes Creates a new vote question within a vote collection. Automatically generates two default options. The vote collection must be in editable state (draft). Requires ownership of the vote collection or HR_LOCAL permission. # Delete a vote Source: https://orgo.space/docs/api-reference/vote/delete-a-vote /api-reference/openapi.json delete /api/v1/votes/{id} Deletes a vote question from its collection. The vote collection must be in editable state (not open or locked). Requires HR_LOCAL permission. Event-attached votes can only be deleted by the event owner. # Get a vote Source: https://orgo.space/docs/api-reference/vote/get-a-vote /api-reference/openapi.json get /api/v1/votes/{id} Retrieves a vote with computed results including per-option totals, percentages, total voted, and total eligible voters. Subscribes the client to real-time Mercure updates for live result streaming. # Update a vote Source: https://orgo.space/docs/api-reference/vote/update-a-vote /api-reference/openapi.json patch /api/v1/votes/{id} Updates a vote question. The vote must be in editable state (not locked). For non-general votes, the current user is automatically added as an eligible voter if not already present. Requires ownership or HR_LOCAL permission. # Create a vote box Source: https://orgo.space/docs/api-reference/votebox/create-a-vote-box /api-reference/openapi.json post /api/v1/vote_boxes Submits ballot answers for all questions in a vote collection. All questions must be answered in a single request. For each question, the value is either a single option id (single-choice) or an array of option ids (multiple-choice). Validates voter eligibility, prevents double voting, and checks vote collection status (must be open). For private votes, the user must be on the eligible voters list. Returns a JSON object of the form `{ "seal": "" }` rather than a serialized VoteBox; the seal is a combined integrity token covering every VoteBox created by this submission. # Get a vote box Source: https://orgo.space/docs/api-reference/votebox/get-a-vote-box /api-reference/openapi.json get /api/v1/vote_boxes/{id} Retrieves a single vote box entry containing the recorded answer for a vote question. # Archive a vote collection Source: https://orgo.space/docs/api-reference/votecollection/archive-a-vote-collection /api-reference/openapi.json patch /api/v1/vote_collections/{id}/archive Archives a closed vote collection to remove it from active lists. The collection must not be in editable state (must be closed first). Cannot archive an already archived collection. # Check for active live votes Source: https://orgo.space/docs/api-reference/votecollection/check-for-active-live-votes /api-reference/openapi.json get /api/v1/has_live_votes Returns a boolean indicating whether there are any currently active (open) vote collections the authenticated user is eligible to participate in. Used to show live voting indicators in the UI. # Clone a vote collection Source: https://orgo.space/docs/api-reference/votecollection/clone-a-vote-collection /api-reference/openapi.json patch /api/v1/vote_collections/{id}/clone Creates a complete copy of the vote collection including all questions, options, and eligible voters. The clone starts as a draft with new dates (now to +1 hour). Vote results are not copied. For event-attached votes, only the event owner can clone. # Close a vote collection Source: https://orgo.space/docs/api-reference/votecollection/close-a-vote-collection /api-reference/openapi.json patch /api/v1/vote_collections/{id}/close Manually closes an open vote collection, preventing any further votes from being cast. The collection must be published and currently open (not draft, not already closed). Publishes a real-time Mercure update. # Create a vote collection Source: https://orgo.space/docs/api-reference/votecollection/create-a-vote-collection /api-reference/openapi.json post /api/v1/vote_collections Creates a new vote collection with a default question and two answer options. Validates event/unit/date constraints. For private vote collections, the creator is automatically added as an eligible voter. Requires HR_LOCAL permission. # Delete a vote collection Source: https://orgo.space/docs/api-reference/votecollection/delete-a-vote-collection /api-reference/openapi.json delete /api/v1/vote_collections/{id} Permanently deletes a vote collection and all associated votes, options, and ballot records. Requires ownership or HR_LOCAL permission. # Export vote collection results Source: https://orgo.space/docs/api-reference/votecollection/export-vote-collection-results /api-reference/openapi.json get /api/v1/vote_collections/{id}/export Downloads vote results as a CSV file containing vote questions, answers, and cryptographic seals for audit purposes. The vote collection must be closed before export is allowed. Returns a file attachment response. # Get a vote collection Source: https://orgo.space/docs/api-reference/votecollection/get-a-vote-collection /api-reference/openapi.json get /api/v1/vote_collections/{id} Retrieves a vote collection with computed results for all questions including per-option totals and percentages, total voted, and total eligible counts. Subscribes the client to real-time Mercure updates for live result streaming. # List vote collections Source: https://orgo.space/docs/api-reference/votecollection/list-vote-collections /api-reference/openapi.json get /api/v1/vote_collections Returns a paginated list of vote collections for the current tenant, ordered by creation date descending. Filterable by standard API Platform filters. # Publish a vote collection Source: https://orgo.space/docs/api-reference/votecollection/publish-a-vote-collection /api-reference/openapi.json patch /api/v1/vote_collections/{id}/publish Transitions a vote collection from draft to published state. Validates event/unit/date constraints before publishing. Sends notification emails to eligible voters. Publishes a real-time Mercure update. The collection must be in editable (draft) state. # Update a vote collection Source: https://orgo.space/docs/api-reference/votecollection/update-a-vote-collection /api-reference/openapi.json patch /api/v1/vote_collections/{id} Updates properties of a vote collection such as name, dates, and settings. Requires ownership or HR_LOCAL permission. # Create a vote option Source: https://orgo.space/docs/api-reference/voteoption/create-a-vote-option /api-reference/openapi.json post /api/v1/vote_options Adds a new answer option to a vote question. The vote must be in editable state. Publishes a real-time Mercure update to all connected clients. Requires ownership of the vote collection or HR_LOCAL permission. # Delete a vote option Source: https://orgo.space/docs/api-reference/voteoption/delete-a-vote-option /api-reference/openapi.json delete /api/v1/vote_options/{id} Removes an answer option from a vote question. The vote must be in editable state (not open or locked). Publishes a real-time Mercure update. Requires ownership or HR_LOCAL permission. # Get a vote option Source: https://orgo.space/docs/api-reference/voteoption/get-a-vote-option /api-reference/openapi.json get /api/v1/vote_options/{id} Retrieves a single vote option by its identifier. # Update a vote option Source: https://orgo.space/docs/api-reference/voteoption/update-a-vote-option /api-reference/openapi.json patch /api/v1/vote_options/{id} Updates the title or other properties of a vote option. The vote must be in editable state. Publishes a real-time Mercure update. Requires ownership of the vote collection or HR_LOCAL permission. # Cast a vote as user Source: https://orgo.space/docs/api-reference/voteuser/cast-a-vote-as-user /api-reference/openapi.json post /api/v1/vote_users Adds a user as an eligible voter in a private vote collection. Prevents duplicate entries. The vote collection must be in editable state. Only the vote collection owner can add voters. # Get a vote user Source: https://orgo.space/docs/api-reference/voteuser/get-a-vote-user /api-reference/openapi.json get /api/v1/vote_users/{id} Retrieves details of a single vote user entry including their voting status and alias. # List vote users Source: https://orgo.space/docs/api-reference/voteuser/list-vote-users /api-reference/openapi.json get /api/v1/vote_users Returns a paginated list of users eligible to vote in a vote collection, including their voting status. Returns up to 100 items per page. # Remove a vote user Source: https://orgo.space/docs/api-reference/voteuser/remove-a-vote-user /api-reference/openapi.json delete /api/v1/vote_users/{id} Removes a user from the eligible voters list. Cannot remove users who have already cast their vote. The vote collection must be in editable state. Only the vote collection owner can remove voters. # Update vote user alias Source: https://orgo.space/docs/api-reference/voteuser/update-vote-user-alias /api-reference/openapi.json patch /api/v1/vote_user_alias Updates the display alias for a vote user (used for anonymous voting). Cannot be changed after the user has already voted. Only the vote collection owner can modify aliases. # Bulk approve waitlist entries Source: https://orgo.space/docs/api-reference/waitlistentry/bulk-approve-waitlist-entries /api-reference/openapi.json post /api/v1/waitlist_entries/bulk-approve Approve multiple waitlist entries at once # Bulk change priority Source: https://orgo.space/docs/api-reference/waitlistentry/bulk-change-priority /api-reference/openapi.json post /api/v1/waitlist_entries/bulk-priority Change priority for multiple waitlist entries at once # Bulk reject waitlist entries Source: https://orgo.space/docs/api-reference/waitlistentry/bulk-reject-waitlist-entries /api-reference/openapi.json post /api/v1/waitlist_entries/bulk-reject Reject multiple waitlist entries at once with a reason # Bulk send notifications Source: https://orgo.space/docs/api-reference/waitlistentry/bulk-send-notifications /api-reference/openapi.json post /api/v1/waitlist_entries/bulk-notify Send notifications to multiple waitlist entries at once # Delete a waitlist entry Source: https://orgo.space/docs/api-reference/waitlistentry/delete-a-waitlist-entry /api-reference/openapi.json delete /api/v1/waitlist_entries/{uuid} Deletes a waitlist entry and recalculates queue positions for remaining entries. Users can delete their own entry only if it is in "waiting" status. HR_LOCAL admins can delete any entry. Positions are recalculated within a transaction to ensure consistency. # Get a waitlist entry Source: https://orgo.space/docs/api-reference/waitlistentry/get-a-waitlist-entry /api-reference/openapi.json get /api/v1/waitlist_entries/{uuid} Retrieves a single waitlist entry with full detail including queue position, status, priority, and estimated processing date. Requires HR_LOCAL permission or parent access to the entry user. # Get my waitlist status Source: https://orgo.space/docs/api-reference/waitlistentry/get-my-waitlist-status /api-reference/openapi.json get /api/v1/waitlist_entries/my-status Get current user waitlist status and position # Get public waitlist status Source: https://orgo.space/docs/api-reference/waitlistentry/get-public-waitlist-status /api-reference/openapi.json get /api/v1/waitlist_entries/public/{uuid} Returns the public-facing status of a waitlist entry by UUID. Does not require authentication. Intended for shareable status links. # Get waitlist statistics Source: https://orgo.space/docs/api-reference/waitlistentry/get-waitlist-statistics /api-reference/openapi.json get /api/v1/waitlist_entries_statistics Returns aggregate queue metrics for a specific local center including total waiting, total approved, average wait time, and processing velocity. Requires the localCenter query parameter. Requires HR_LOCAL permission. # Join a waitlist Source: https://orgo.space/docs/api-reference/waitlistentry/join-a-waitlist /api-reference/openapi.json post /api/v1/waitlist_entries Creates a waitlist entry for the authenticated user at a specified local center. Validates eligibility (not already on the waitlist, meets local center requirements). The user is automatically assigned a queue position and priority based on tenant waitlist settings. # List waitlist entries Source: https://orgo.space/docs/api-reference/waitlistentry/list-waitlist-entries /api-reference/openapi.json get /api/v1/waitlist_entries Returns a paginated list of waitlist entries for the current tenant. Supports pagination (default 30, max 100 items per page). Filterable by local center, status, and priority via standard API Platform filters. # Update a waitlist entry Source: https://orgo.space/docs/api-reference/waitlistentry/update-a-waitlist-entry /api-reference/openapi.json patch /api/v1/waitlist_entries/{uuid} Admin-only update of a waitlist entry. Allows changing status, priority, notes, and estimated processing date. Uses admin-specific write groups. Requires HR_LOCAL permission on the entry. # Withdraw from waitlist Source: https://orgo.space/docs/api-reference/waitlistentry/withdraw-from-waitlist /api-reference/openapi.json get /api/v1/waitlist_entries/withdraw/{uuid} User withdraws their own waitlist entry # Create a waitlist priority setting Source: https://orgo.space/docs/api-reference/waitlistprioritysetting/create-a-waitlist-priority-setting /api-reference/openapi.json post /api/v1/waitlist_priority_settings Creates a new waitlist priority setting for a user type. The user type must be marked as isUserType and belong to the same tenant. Only one priority setting per user type is allowed. Requires HR_TENANT permission. # Delete a waitlist priority setting Source: https://orgo.space/docs/api-reference/waitlistprioritysetting/delete-a-waitlist-priority-setting /api-reference/openapi.json delete /api/v1/waitlist_priority_settings/{id} Deletes a waitlist priority setting. Requires ADMIN_TENANT permission. # Get a waitlist priority setting Source: https://orgo.space/docs/api-reference/waitlistprioritysetting/get-a-waitlist-priority-setting /api-reference/openapi.json get /api/v1/waitlist_priority_settings/{id} Retrieves a single waitlist priority setting by its identifier. Requires HR_TENANT permission. # List waitlist priority settings Source: https://orgo.space/docs/api-reference/waitlistprioritysetting/list-waitlist-priority-settings /api-reference/openapi.json get /api/v1/waitlist_priority_settings Returns all waitlist priority settings for the current tenant. Defines how different user types are prioritized in event waitlists. Any authenticated user can view settings. # Update a waitlist priority setting Source: https://orgo.space/docs/api-reference/waitlistprioritysetting/update-a-waitlist-priority-setting /api-reference/openapi.json patch /api/v1/waitlist_priority_settings/{id} Updates the priority value for a waitlist priority setting. Enforces tenant isolation. Requires HR_TENANT permission. # Contact created Source: https://orgo.space/docs/api-reference/webhooks/contact-created /api-reference/openapi.json webhook contact.created Fires when a new Contact is created — manually entered, imported from CSV, generated from a public form submission, or auto-created from an event invitation. # Contact deleted Source: https://orgo.space/docs/api-reference/webhooks/contact-deleted /api-reference/openapi.json webhook contact.deleted Fires when a Contact is permanently deleted. Contacts with successful product payments cannot be deleted — this event only fires for contacts free of financial history. # Contact updated Source: https://orgo.space/docs/api-reference/webhooks/contact-updated /api-reference/openapi.json webhook contact.updated Fires when a Contact's profile changes — newsletter opt-in/out, tag added/removed, custom field update. Use `previous_attributes` to detect specific transitions (unsubscribes, status changes). # Contract assigned to a user Source: https://orgo.space/docs/api-reference/webhooks/contract-assigned-to-a-user /api-reference/openapi.json webhook contract_user.created Fires when a Contract template is assigned to a User or Contact via `POST /api/v1/contract_users`. Useful for triggering signature-chase reminders, or projecting the assignment into your compliance system. # Contract assignment deleted Source: https://orgo.space/docs/api-reference/webhooks/contract-assignment-deleted /api-reference/openapi.json webhook contract_user.deleted Fires when an unsigned contract-user record is removed (e.g., via `ask-resign` which cancels all unsigned instances of a contract). # Contract signed or status changed Source: https://orgo.space/docs/api-reference/webhooks/contract-signed-or-status-changed /api-reference/openapi.json webhook contract_user.updated Fires when a contract-user record's signature state changes — typically `UNSIGNED → SIGNED → COMPLETE`. `previous_attributes.status` is the reliable signal that a signature just happened. # Event registration created Source: https://orgo.space/docs/api-reference/webhooks/event-registration-created /api-reference/openapi.json webhook event_attend.created Fires when someone registers for an event — Member self-registers, admin registers them, external invite is accepted. Use to send your own confirmation emails or sync to a third-party event-mgmt tool. # Event registration deleted Source: https://orgo.space/docs/api-reference/webhooks/event-registration-deleted /api-reference/openapi.json webhook event_attend.deleted Fires when a registration is canceled. Capacity is returned to the pool. Refunds (if any) are handled separately as `product_payment.updated`. # Event registration updated Source: https://orgo.space/docs/api-reference/webhooks/event-registration-updated /api-reference/openapi.json webhook event_attend.updated Fires when the registration's status changes — confirmed by admin, checked in at the door, marked no-show. Also fires when guest tickets are added or removed. # Payment created Source: https://orgo.space/docs/api-reference/webhooks/payment-created /api-reference/openapi.json webhook product_payment.created Fires the moment a payment is initiated — Stripe checkout started, bank-transfer invoice issued, manual entry by treasurer. Status will typically be `PENDING` at this point. # Payment deleted Source: https://orgo.space/docs/api-reference/webhooks/payment-deleted /api-reference/openapi.json webhook product_payment.deleted Fires when a payment record is hard-deleted. Rare — refunds and cancellations update status rather than delete. Mostly emitted from admin cleanup of erroneous duplicate entries. # Payment updated Source: https://orgo.space/docs/api-reference/webhooks/payment-updated /api-reference/openapi.json webhook product_payment.updated Fires when a payment's status, amount, or metadata changes — payment captured, refunded, marked-as-paid for bank transfers, etc. Use `previous_attributes.status` to detect the transition. # Role assigned to a user Source: https://orgo.space/docs/api-reference/webhooks/role-assigned-to-a-user /api-reference/openapi.json webhook user_role.created Fires when a User is granted a role on a Unit — promotion to chapter lead, treasurer assignment, etc. Useful for sync to external permission systems (Slack channels, GitHub teams). # Role assignment revoked Source: https://orgo.space/docs/api-reference/webhooks/role-assignment-revoked /api-reference/openapi.json webhook user_role.deleted Fires when a role assignment is removed. Permission re-evaluation happens immediately on the next API call; cached JWT roles take effect on the next refresh. # Role assignment updated Source: https://orgo.space/docs/api-reference/webhooks/role-assignment-updated /api-reference/openapi.json webhook user_role.updated Fires when a role assignment's properties change (scope adjustment, validity dates, custom attributes). The role itself is immutable — to "change a role", delete the old assignment and create a new one. # User created Source: https://orgo.space/docs/api-reference/webhooks/user-created /api-reference/openapi.json webhook user.created Fires when a new User is created — through self-registration, admin creation, OAuth signup, or successful adhesion. The `object` is the full user with read-group fields. # User deleted Source: https://orgo.space/docs/api-reference/webhooks/user-deleted /api-reference/openapi.json webhook user.deleted Fires when a User is permanently deleted (irreversible — distinct from soft-deletion via status `INACTIVE`). The `object` is the last-known state of the user before deletion. # User updated Source: https://orgo.space/docs/api-reference/webhooks/user-updated /api-reference/openapi.json webhook user.updated Fires when a User's profile, status, or relationships change. The `object` is the full user post-change; `previous_attributes` carries only the fields that changed. # Create a webhook subscription Source: https://orgo.space/docs/api-reference/webhooksubscription/create-a-webhook-subscription /api-reference/openapi.json post /api/v1/webhook_subscriptions Creates a new webhook subscription or updates an existing one if a subscription with the same URL already exists for the tenant. Accepts url (required), eventTypes, name, secret, isActive, maxRetries, timeoutSeconds, description, headers, and metadata. Validates all fields before persisting. Requires ADMIN_TENANT permission. # Delete a webhook subscription Source: https://orgo.space/docs/api-reference/webhooksubscription/delete-a-webhook-subscription /api-reference/openapi.json delete /api/v1/webhook_subscriptions/{id} Permanently deletes a webhook subscription and its delivery logs. Requires ADMIN_TENANT permission. # Get a webhook subscription Source: https://orgo.space/docs/api-reference/webhooksubscription/get-a-webhook-subscription /api-reference/openapi.json get /api/v1/webhook_subscriptions/{id} Retrieves a single webhook subscription with full detail including event types, headers, metadata, and configuration. Requires ADMIN_TENANT permission. # Get webhook delivery logs Source: https://orgo.space/docs/api-reference/webhooksubscription/get-webhook-delivery-logs /api-reference/openapi.json get /api/v1/webhook_subscriptions/{id}/delivery_logs Returns recent delivery attempt logs for a webhook subscription, including request/response details and status codes. Accepts an optional limit query parameter (default 100, max 500). Requires ADMIN_TENANT permission. # List webhook subscriptions Source: https://orgo.space/docs/api-reference/webhooksubscription/list-webhook-subscriptions /api-reference/openapi.json get /api/v1/webhook_subscriptions Returns a paginated list of webhook subscriptions for the current tenant, 25 items per page. # Test a webhook subscription Source: https://orgo.space/docs/api-reference/webhooksubscription/test-a-webhook-subscription /api-reference/openapi.json post /api/v1/webhook_subscriptions/{id}/test Sends a test payload to the webhook URL and returns the delivery result including HTTP status code, response body, and timing. Useful for verifying the endpoint is reachable and correctly configured. Requires ADMIN_TENANT permission. # Update a webhook subscription Source: https://orgo.space/docs/api-reference/webhooksubscription/update-a-webhook-subscription /api-reference/openapi.json patch /api/v1/webhook_subscriptions/{id} Updates an existing webhook subscription properties such as event types, URL, secret, retry settings, and active status. Requires ADMIN_TENANT permission. # Create a newsletter widget Source: https://orgo.space/docs/api-reference/widget/create-a-newsletter-widget /api-reference/openapi.json post /api/v1/newsletter_widgets Creates a new newsletter subscription widget. Applies default newsletter settings if none provided. If this is the first newsletter widget for the tenant, it is automatically set as the default in tenant settings. Requires COMMUNICATION_TENANT or EVENT_TENANT permission. # Create a widget Source: https://orgo.space/docs/api-reference/widget/create-a-widget /api-reference/openapi.json post /api/v1/widgets Creates a new payment widget linked to a product. The product is required and must belong to the same tenant. Automatically sets the tenant from the authenticated user. Requires FINANCIAL_TENANT permission. # Delete a newsletter widget Source: https://orgo.space/docs/api-reference/widget/delete-a-newsletter-widget /api-reference/openapi.json delete /api/v1/newsletter_widgets/{uuid} Deletes a newsletter widget. Cannot delete the last remaining newsletter widget for the tenant. If deleting the default widget, another widget is automatically promoted as the new default. Requires COMMUNICATION_TENANT or EVENT_TENANT permission. # Delete a widget Source: https://orgo.space/docs/api-reference/widget/delete-a-widget /api-reference/openapi.json delete /api/v1/widgets/{uuid} Deletes a payment widget. Enforces tenant isolation. Requires FINANCIAL_TENANT permission. # Get a newsletter widget by UUID Source: https://orgo.space/docs/api-reference/widget/get-a-newsletter-widget-by-uuid /api-reference/openapi.json get /api/v1/get-newsletter-widget/{uuid} Retrieves a newsletter widget by its UUID for rendering on external or public pages. No authentication required. # Get a public widget Source: https://orgo.space/docs/api-reference/widget/get-a-public-widget /api-reference/openapi.json get /api/v1/widgets/public/{uuid} Retrieves a widget by its public UUID for embedding on external websites. Only active widgets are accessible. No authentication required. # Get a widget Source: https://orgo.space/docs/api-reference/widget/get-a-widget /api-reference/openapi.json get /api/v1/widgets/{uuid} Retrieves a single payment widget by its identifier. Requires FINANCIAL_TENANT permission. # List newsletter widget subscribers Source: https://orgo.space/docs/api-reference/widget/list-newsletter-widget-subscribers /api-reference/openapi.json get /api/v1/newsletter_widgets/{uuid}/subscribers Returns a paginated list of subscribers for a newsletter widget, including linked user or contact information. Supports page and itemsPerPage query parameters (max 100 per page). Only available for widgets with type "newsletter". Requires COMMUNICATION_TENANT or EVENT_TENANT permission. # List newsletter widgets Source: https://orgo.space/docs/api-reference/widget/list-newsletter-widgets /api-reference/openapi.json get /api/v1/newsletter_widgets Returns all newsletter widgets for the current tenant with subscriber counts pre-computed in a single query. Ordered by creation date descending. Requires COMMUNICATION_TENANT or EVENT_TENANT permission. # List widgets Source: https://orgo.space/docs/api-reference/widget/list-widgets /api-reference/openapi.json get /api/v1/widgets Returns a paginated list of payment widgets for the current tenant, 30 items per page. Requires FINANCIAL_TENANT permission. # Update a newsletter widget Source: https://orgo.space/docs/api-reference/widget/update-a-newsletter-widget /api-reference/openapi.json patch /api/v1/newsletter_widgets/{uuid} Updates a newsletter widget configuration such as name, settings, and styling. The widget must belong to a tenant. Requires COMMUNICATION_TENANT or EVENT_TENANT permission. # Update a widget Source: https://orgo.space/docs/api-reference/widget/update-a-widget /api-reference/openapi.json patch /api/v1/widgets/{uuid} Updates a payment widget configuration. Validates tenant isolation and that any referenced product belongs to the same tenant. Requires FINANCIAL_TENANT permission. # Activate a workflow Source: https://orgo.space/docs/api-reference/workflow/activate-a-workflow /api-reference/openapi.json post /api/v1/workflows/{uuid}/activate Activates a workflow so it will be triggered by matching events. The workflow must have at least one trigger and one action configured. Requires tenant admin permission. # Create a workflow Source: https://orgo.space/docs/api-reference/workflow/create-a-workflow /api-reference/openapi.json post /api/v1/workflows Creates a new automation workflow with triggers, condition groups, and actions in a single request. The workflow starts in inactive state. Triggers define which events activate the workflow, conditions filter eligibility, and actions define what happens (e.g., send email). Requires tenant admin permission. # Deactivate a workflow Source: https://orgo.space/docs/api-reference/workflow/deactivate-a-workflow /api-reference/openapi.json post /api/v1/workflows/{uuid}/deactivate Deactivates a workflow so it will no longer be triggered by events. The workflow configuration is preserved and can be reactivated later. Requires tenant admin permission. # Delete a workflow Source: https://orgo.space/docs/api-reference/workflow/delete-a-workflow /api-reference/openapi.json delete /api/v1/workflows/{uuid} Permanently deletes a workflow and all its associated triggers, conditions, and actions. Requires tenant admin permission and same-tenant access. # Duplicate a workflow Source: https://orgo.space/docs/api-reference/workflow/duplicate-a-workflow /api-reference/openapi.json post /api/v1/workflows/{uuid}/duplicate Creates a complete copy of the workflow including all triggers, condition groups, conditions, and actions. The copy is created in inactive state with " (Copy)" appended to the name. Requires tenant admin permission. # Get a workflow Source: https://orgo.space/docs/api-reference/workflow/get-a-workflow /api-reference/openapi.json get /api/v1/workflows/{uuid} Retrieves a single workflow with its triggers, condition groups, and actions. Requires tenant admin permission and same-tenant access. # List workflows Source: https://orgo.space/docs/api-reference/workflow/list-workflows /api-reference/openapi.json get /api/v1/workflows Returns a paginated list of automation workflows for the current tenant. Requires tenant admin permission. Returns up to 50 items per page. # Test a workflow Source: https://orgo.space/docs/api-reference/workflow/test-a-workflow /api-reference/openapi.json post /api/v1/workflows/{uuid}/test Performs a dry-run execution of the workflow against a test user without persisting any changes. Returns the evaluation result for each trigger, condition, and action. Optionally specify a userId and test payload in the request body. Requires tenant admin permission. # Update a workflow Source: https://orgo.space/docs/api-reference/workflow/update-a-workflow /api-reference/openapi.json patch /api/v1/workflows/{uuid} Updates a workflow including its triggers, condition groups, and actions. Nested entities (triggers, conditions, actions) are cleared and recreated on each update. Supports updating name, description, active status, priority, and canvas layout data. Requires tenant admin permission. # Get a workflow execution Source: https://orgo.space/docs/api-reference/workflowexecution/get-a-workflow-execution /api-reference/openapi.json get /api/v1/workflow_executions/{id} Retrieves details of a single workflow execution including trigger event, conditions evaluated, actions performed, and execution status. Requires tenant admin permission and same-tenant access. # List workflow executions Source: https://orgo.space/docs/api-reference/workflowexecution/list-workflow-executions /api-reference/openapi.json get /api/v1/workflow_executions Returns a paginated list of workflow execution logs for the current tenant, showing when workflows were triggered and their results. Requires tenant admin permission. Returns up to 50 items per page. # Changelog Source: https://orgo.space/docs/changelog/index What's new in ORGO platform **New Features** **Payments & Fees** * **VAT on Fees and Products**: Membership, registration fee and VAT are now itemised separately on the payment breakdown, the invoice and the invoice email, with the rate set per membership level: [VAT & Registration Fees](/docs/platform/fees/vat). * **Advance Payment Window**: Choose how far ahead of expiry a fee may be paid — a number of months for yearly fees, a number of days for monthly ones. A member whose membership is not currently covered can still pay for the next period outside that window. * **Fee Tier per Year**: The tier you pick on a chapter's member fees table is now dated, so a member can move to a different tier next year without repricing the periods they have already paid: [Member Fees Table](/docs/platform/local-group-fees/member-fees). * **Record a Payment Taken Outside Orgo**: A **Record payment** button on a member's payments tab logs a bank transfer, cash or cheque against a product, with the date it was actually taken. Fixed-price products lock the amount to the price: [Recording a Payment Made Outside Orgo](/docs/platform/fees/record-payment). * **Invoice for a Fee Already Paid**: Generate an invoice for a membership fee payment that was recorded earlier, instead of only at the moment of payment: [Invoices](/docs/platform/fees/invoices). * **Donations at Checkout**: Add an optional gift to the membership checkout, with suggested amounts, an optional custom amount within limits you set, and your own prompt. Each option chosen is recorded as its own payment and itemised on the charge: [Membership Fees](/docs/platform/fees/fees). * **One-Time and Recurring on the Same Price**: A price can be offered as both a single payment and a subscription rather than one or the other. * **Unit Admins from the Member List**: Make or dismiss a unit admin straight from the member list. They get the fee payments list scoped to their own units: [Units](/docs/platform/groups/units). * **Fee Tier as Role Group Criteria**: A role group can fill itself from the membership fee prices members are on: [Role Groups](/docs/platform/groups/role-groups). **Invoices** * **Invoices in the Recipient's Language**: The invoice PDF is generated in the member's own language across all 14 platform languages, and Stripe receipts follow the same language. * **Renewal Invoice Attached to Company Reminders**: Company fee renewal reminders now carry the renewal invoice as an attachment. **Companies** * **Voting Representative**: Mark one member of a company as its voting representative, from the members list or when inviting them. Only one person holds it at a time, and assigning it moves it off the previous holder: [Companies](/docs/platform/users/companies). * **Renewal Reminder Emails**: The seven company fee renewal reminders are now editable per organization, and a company can pay its renewal from the moment its renewal window opens. * **One Primary Contact**: Naming a new primary contact demotes the previous one instead of leaving two. **Voting** * **Non-Anonymous Votes**: Run a vote where administrators can see how each person voted. Voters are told before they cast a ballot, results open into an individual view, and a per-voter CSV export replaces the anonymous one. Anonymity is frozen once ballots exist, so a vote advertised as anonymous can never be turned: [E-Voting](/docs/platform/e-voting). **Newsletter** * **Per-Recipient Statistics Export**: **Export CSV** on a campaign's Report tab gives one row per recipient per recorded action — delivered, opened, clicked, bounced, complained, unsubscribed, rejected and failed: [Newsletter](/docs/platform/newsletter). * **One-Click Unsubscribe**: Campaign emails now carry one-click unsubscribe headers, so the Unsubscribe button mail clients show beside the sender works without opening the message. **Chapters** * **Newsletters, Courses and Contacts for Chapters**: Communication and HR roles at chapter level can now build and send their own campaigns, create and edit courses, and manage contacts, all scoped to their chapter. * **Parent Chapter Member Counts**: A parent chapter now counts the members of the chapters beneath it. * **Chapter Admins Manage Member Content**: Chapter admins can remove files and discussion content belonging to members of their own chapter. * **Chapter Products for Financial Roles**: Financial roles at chapter level reach the products and prices of their own chapter. **Discussions** * **Moderation for Chapter Discussions**: The blocked-words filter and moderation queue now cover chapter discussions, and the moderators of that chapter are alerted once per held post: [Discussion Moderation](/docs/platform/discussion/moderation). **Workflows** * **Four New Triggers**: Tag Added, Tag Removed, Donation Payment Success and Event Attendance can now start a workflow, with an optional filter on a specific tag, donation product or event: [Workflows](/docs/platform/workflows). **API & Integrations** * **Scoped API Tokens**: Narrow a token area by area with a read and write matrix, change the scope of a token after it was created without reissuing it, and get an internal record of every create, scope change and revoke: [API Access](/docs/platform/api). * **OAuth Consent and App Permissions**: The consent screen was rebuilt, members who belong to more than one organization pick which one they are granting access to, apps are registered as confidential clients bound to your organization, and each app declares whether it may act on the member's behalf or only read: [OAuth](/docs/platform/oauth). **Members** * **Identity Validation on the Join Flow**: The membership application can require an ID document check before it is submitted: [Identity Validation](/docs/platform/identity-validation). * **Encrypted Personal Identifiers**: National identifiers live in encrypted custom fields, numeric ones included, rather than a plain profile column: [Custom Fields](/docs/platform/users/custom-fields). * **Switch Off Individual System Emails**: Each system email can now be turned off on its own: [System Emails](/docs/platform/emails/system-emails). **Lists & Segments** * **Donation Dropout**: Build a list of contacts who started a donation but never completed one: [Lists & Segments](/docs/platform/users/lists). **Events** * **Speakers and Ticket Details**: Speakers open in a full list from the event page, tickets show their description, and agenda sessions with no stage get a readable default colour. * **Who Can Post Public Events**: The setting now governs both the create button and the event itself, and the public option is no longer offered inside private groups. **Languages** * **Czech and Estonian**: Both are available as interface languages, and all 14 languages are now complete against English: [Languages](/docs/platform/customization/languages). **Improvements** **Payments & Fees** * **Amounts Read Correctly**: Prices show at most two decimals across fee cards, the pay modal and the invoice preview, and the membership pay buttons quote the amount that will actually be charged. * **Payments List**: Filter the payments list by product, and rows stay visible when a filter is applied. * **Membership Out of the Offline Recorder**: The offline payment recorder covers products and one-off charges; membership periods are recorded on the fees table instead. **Members & Profiles** * **Long Date Format**: Dates on profiles, task lists and the project and voting pickers now read as "July 15th 2026", and US organizations get month/day/year ordering throughout. * **Dates Stop Shifting**: Join dates, role dates and task dates no longer move a day back when saved. * **Merge Search**: The record picker when merging duplicates no longer hides candidates by age. * **User Type Filter**: The member list's user type filter sits beside the list rather than under More filters, and a setting controls who can use it. **Imports** * **Smarter Town Matching**: Imports resolve towns more reliably, with an extended search and case-insensitive names. * **Chapters by Name**: Member and role imports can reference a chapter by name instead of an ID. * **Refreshed Example Files**: Every example CSV was rebuilt with all importable fields and valid sample values. * **Cleaner Rollbacks**: Rolling back an import unwinds more of what it created: [Import](/docs/platform/customization/import). **Projects & Tasks** * **Task Links Land on the Task**: Notification emails and push alerts open the task itself rather than the project. * **Quieter Archived Projects**: Archived projects stop sending task notifications. * **Task Board Details**: Tasks sort by name, the due date column is back, assignee dropdowns flip upward near the bottom of the screen, and descriptions keep their line breaks. **Geography** * **Empty Regions Are Clickable**: Clicking a region on the membership geography map opens the filtered member list even when nobody lives there yet. **New Features** **Files & Drive** * **Public Folder Sharing**: Share an entire Drive folder with a public link. Visitors get a clean, branded gallery or table view of the folder without needing an account. * **Embed External Media**: Paste YouTube or Spotify links into Drive with the new "Embed media" button. Embeds appear alongside your files with provider icons and play directly in the gallery and lightbox. **Discussions** * **AI Content Moderation**: Discussion posts and comments are automatically screened. Flagged content lands in a new moderation queue where admins can approve or reject it, with a configurable blocked-words list. **Website** * **Public Organization Website**: Organizations now get a public landing page with hero, about, chapters, events, donation, and newsletter signup sections. Each chapter also gets its own public page. **Payments & Fees** * **Membership Registration Fee**: Add a one-time registration fee to membership prices. It is collected together with the membership payment and shown on member fee cards. * **Unit-Level Fee Management**: Chapter fee member lists can now be filtered by unit, and fee amounts can be edited for individual members within your scope. **Voting** * **Export Voters**: Download the list of voters for organization-wide votes directly from the vote page. **Contacts** * **Multiple Contact Notes**: Contacts now support a full notes timeline. Add, edit, and delete multiple timestamped notes instead of a single notes field. **Dashboard** * **Chapter Analytics**: Chapters get a dedicated analytics page with membership, finance, and engagement statistics scoped to that chapter. * **US Maps in Geography Stats**: The membership geography view now includes US state and county-level maps with member filters. **Billing** * **Invoices and Usage Pages**: Organization admins can view their platform invoices and usage details from the new pages in the Billing settings. **Events** * **Event App Networking**: Attendees can browse other participants, book meetings, and keep a saved contacts list, with improved attendee profiles and QR ticket scanning. **Groups** * **Restrict Event Creation**: Groups can now be configured so that only group admins can create events in them. **Forms** * **Default Price per User Type**: Registration forms can assign a default membership price to each user type, so new members are set up with the right fee automatically. **Improvements** **Files & Drive** * **Thumbnails and Upload Progress**: Photos and videos now display thumbnails in Drive, and uploads run through a new progress panel with a visible queue. * **Gallery and Video Player Redesign**: The Drive gallery received a cleaner photo-grid layout and the video player was redesigned. * **Folder Actions Menu**: Rename, move, or remove the current folder straight from a new menu in the folder header. * **Richer Share Previews**: Shared video links now display a preview image when posted in chat and social apps. **Projects** * **Project Settings Screen**: Project settings were consolidated into a redesigned, easier-to-navigate screen. **Groups** * **Unit Hierarchy in Chapters List**: The chapters list now displays each chapter's unit structure as a browsable hierarchy. **Members** * **Organizational Chart Filters**: The organizational chart can now be filtered by chapter. * **Bulk Operations and Imports**: Saved member lists support bulk actions, payment records can be imported by matching member names, and the data import guide was expanded. **Sign-in** * **Password Login Default**: Organizations can make password login the default sign-in method for their members. **Membership** * **Adhesion Video Step**: The introduction video step in the membership adhesion workflow can now be turned on or off in module settings. **New Features** **Events** * **Event Companion App**: A brand-new in-event experience for attendees: browse the agenda and session details, register for individual sessions, view the event calendar, and see who else is attending, all optimized for mobile. Attendees can sign in with a simple one-time email code. * **Event Feed**: Post updates and photos during your event, comment, reply, and react. Organizers can pin important posts and organize the feed by category. * **Networking & Meeting Booking**: Attendees can browse participants, request 1:1 meetings, and manage their meeting schedule. Organizers can set up networking spaces and available time slots. * **QR Check-In**: Organizers can scan attendee QR codes to check people in and verify registrations on the spot. * **Push Notifications**: Attendees receive push notifications for replies, reactions, and meeting requests during events. * **Event Analytics**: New analytics view giving organizers insight into registrations and attendee engagement per event. * **One-Hour Event Reminder**: Attendees now automatically receive a reminder email one hour before an event starts. * **Participant List Visibility**: Organizers can make the participant list public or private per event, and attendees control whether their own profile appears in it. * **Add-On Quantities at Checkout**: Attendees can now choose quantities for ticket add-ons when registering for an event. **Voting** * **Redesigned Voting**: Completely rebuilt voting experience with clearer ballot cards, live participation stats, results views, and a "my selection" summary, on desktop and mobile. * **Vote Sharing**: Share a vote via link so members can jump straight into voting, including from the event app. * **Duplicate Votes**: Clone an existing vote to reuse it as a starting point for a new one. * **Reorder Questions & Options**: Arrange vote questions and answer options in exactly the order you want. * **Vote Search & Filters**: Find votes faster with keyword search, status filters, and an archived view. **Files & Drive** * **Public File Sharing**: Share Drive files via a public link that anyone can open, and revoke access at any time. * **Built-In Video Player**: Videos in Drive now play in a proper in-app player with full playback controls. **Newsletter** * **Resend to Non-Openers**: Duplicate a sent newsletter targeted only at recipients who didn't open it. * **Duplicate Newsletters**: Clone any newsletter to reuse its content and settings. * **Bounced Recipients**: See exactly which recipients bounced for each newsletter send. * **Shareable Web Version**: Publish a newsletter to a short public web link you can share anywhere. **Payments & Fees** * **Invoice Refunds**: Refund paid invoices directly from the invoice page, with related registrations updated automatically. * **Chapter Payment Setup**: Chapters and local centers can now connect their own Stripe account and set their own currency. **Dashboard & Reports** * **Ask Orgo**: Ask questions about your organization's data in plain language and get instant answers with tables and charts. Save your favorite queries and ask follow-up questions in a conversation. **Courses** * **Lesson Attachments**: Attach files to course lessons and let learners preview them directly in the course. **Forms** * **New Custom Field Types**: More field type options for profile and registration forms. **Organization Settings** * **Custom Domains**: Connect your own domain to your Orgo workspace with a guided setup and automatic SSL. * **Deletion Audit Log**: Deletions of important records are now recorded in the audit log, showing who deleted what and when. * **Lithuanian Language**: Orgo is now fully available in Lithuanian, including all email notifications. **Improvements** **Events** * **Refreshed Event Pages**: Redesigned event list, detail page, and agenda with clearer date, location, and host sections, a map preview, and color-coded stages in agendas and embeds. * **Speaker Showcase**: Improved speakers section on event pages with richer speaker cards. * **Participant Management**: Admins can now manage the participant list comfortably from mobile, with separate admin and attendee views. **Discussions** * **Reaction Details**: See who reacted to discussion posts and comments, and refreshed discussion cards with a cleaner look. **Contacts** * **Smarter Data Import**: Imports now support contacts without an email address, detect duplicate event attendees, carry over membership fee prices (including lifetime prices), and handle migrations from other platforms more reliably. * **More Complete Member Merge**: Merging duplicate members now transfers far more related data, including badges and fees. **Profiles** * **Fee Overview Redesign**: Membership fee information on member profiles is now presented in clearer summary and detail cards. **Forms** * **Registration Forms Overview**: Redesigned list for managing registration forms. **New Features** **Navigation** * **Redesigned Sidebar**: New sidebar split into Community and Administration modes with a mobile toggle, sticky footer with Administration link and user profile, and hover side panels for quick access. * **User Menu in Sidebar**: User menu moved from the header into the sidebar footer on desktop, with a new bottom-sheet design on mobile. Includes language switcher, downloads, and membership fee shortcut. * **Communication Category**: Added a dedicated Communication section in the sidebar for messages, newsletters, and discussions. * **Custom Menu Editor**: Admins can now reorder and customize community menu categories, with Home and Groups locked to preserve core navigation. * **Impersonation Shortcut**: Restored the impersonation button in the user menu for admins managing other accounts. **Dashboard** * **New Dashboard Experience**: Rebuilt dashboard with separate desktop and mobile layouts, redesigned welcome template, and improved discussion creation bar directly from the dashboard. **Files & Drive** * **Public Share Links**: You can now create public share links for Drive files and folders, with the ability to revoke access at any time. **Groups** * **Redesigned Group Browse**: New Group Browse experience with improved cards, header, and list rows for faster discovery and joining. * **Mute Groups**: You can now mute individual groups to silence their notifications without leaving them. **Contacts & Membership** * **New Adhesion Flow**: Redesigned membership application form with optional video recording for personal introductions, plus a refreshed admin list view for reviewing applications. **Discussions** * **Link Previews**: Discussion posts now display rich Open Graph previews when you share a link, showing the title, description, and thumbnail. **Improvements** **Email Templates** * **Refactored Admin Editor**: Cleaner email templates management screen in admin with a redesigned editor layout. **Projects** * **Redesigned Project Pages**: Updated Project create, show, and update screens with a clearer layout and tab structure. **Events** * **Event List Enhancements**: Added new filtering and display options on the Event List page. **Admin Lists** * **Improved Tables**: User lists, certifications, regions, professions, roles, and other admin tables now render more reliably with consistent loading behavior. **New Features** **Events** * **Event Agenda Builder**: Create detailed event agendas with sub-events, time slots, and speaker assignments. Agendas appear on both the event page and the public event page. * **Event Templates**: Save and reuse event configurations as templates, including registration forms, ticket types, and settings. Manage templates from the Events module settings. * **Guest Tickets & Passes**: Attendees can now invite guests to events. Guests receive confirmation emails with QR codes for check-in. * **QR Code Tickets for Free Events**: Free events now generate QR code tickets for attendees, matching the paid event experience. * **QR Codes on Confirmation Emails**: Event ticket confirmation emails now include a scannable QR code for easy check-in at the door. * **Dedicated Registration Form Page**: The event registration form builder has been moved to its own page for a cleaner editing experience. * **Restrict Events by User Type**: You can now limit event visibility and registration to specific member roles. * **Invoice Generation Toggle**: Added an option to disable automatic invoice generation during event checkout. **Newsletter** * **Redesigned Newsletter Management**: The newsletter list, creation, and detail pages have been completely redesigned with a cleaner interface and improved workflow. * **Newsletter Analytics**: View open rates, click rates, and delivery statistics directly on the newsletter list and detail pages. * **Newsletter Builder**: New visual newsletter builder with a modern editing experience. * **Default Newsletter Templates**: Choose from pre-built templates when creating a new newsletter. **Subscriber Lists** * **Redesigned Subscriber List Management**: Subscriber lists now feature paginated member views, subscription status filtering, and improved dynamic/static list management. **Donations & Payments** * **Donation Pages**: New public-facing donation pages with customizable colors, preset amounts, and organization branding. * **Embeddable Donation Widget**: Place a donation widget on external websites to accept contributions directly. * **Generate Invoice from Payment**: Admins can now generate invoices directly from event payment records. **Projects & Tasks** * **Project Member Management**: Add and remove project members with role-based access control. * **Drag & Drop Tasks**: Reorder tasks via drag and drop on the project task list. * **Task Grouping by Assignee**: Group tasks by assignee for a clearer project overview. * **Project Icons**: Assign custom icons to projects for better visual identification. * **Optional Objectives**: Project objectives are now optional, giving you more flexibility in project setup. * **Task Type & Checklist in Create Modal**: Set task type and add checklist items directly when creating a task. **Discussions** * **Comment & Reply Deletion**: Discussion comments and replies can now be deleted while preserving thread structure. **Profiles** * **Merge Duplicate Profiles**: Admins can now merge duplicate member profiles with a side-by-side comparison view and full merge history log. **Courses** * **CSV Export**: Export course enrollments and quiz results to CSV. **Companies** * **Search & Status Filters**: Added a search bar and status count filters to the company list page. * **Persistent Filters**: Filter selections on the company list now persist across navigation. **Members** * **Grace Period Filter**: Filter the member list by fee grace period status. * **CSV Export with Custom Fields**: Member CSV exports now include custom field data. * **Improved Manual Registration**: Assign permissions and roles directly during manual member registration. **E-Documents** * **Redesigned E-Documents List**: The e-documents management page has been completely redesigned with better organization and a new configuration panel in settings. * **Download per Entry**: Download individual e-documents directly from user entries. **Invoices** * **Town & Country on Company Invoices**: Company invoices now display town and country information. **Improvements** **Events** * **Redesigned Event List**: Events now display in a card-based layout with cover photos and better visual hierarchy. * **Better Upload Error Messages**: Event form now shows clear, specific messages for upload timeouts, network failures, and file size limits. * **Improved Mobile Checkout**: Enhanced mobile experience for event ticket purchases. **Dashboard** * **Redesigned Welcome Message**: The dashboard welcome message has a cleaner, refreshed design. * **Custom Homepage Redirects**: Organizations with custom homepages now redirect correctly. **Products** * **Redesigned Product Management**: Product list, detail, and form pages have been redesigned with better navigation, statistics, and subscriber management views. * **Product Color Customization**: Products support custom brand colors that carry through to payment and thank you pages. * **Product Archive & Remove**: You can now archive or remove products directly from the product detail page. **Newsletter** * **Updated Unsubscribe Page**: The email unsubscribe page has been refreshed with a cleaner design. **Groups & Units** * **Improved Group Browse Page**: Better layout and responsiveness when browsing groups. * **Improved Unit & Patrol Management**: Reorganized unit type creation and editing for better usability. **Maps** * **Improved Local Center Map**: Enhanced local center map with better interactivity and English-language display. **Referrals** * **Redesigned Referral Tab**: The referral tab on member profiles features an improved layout with better sharing options. **Members** * **Improved Invitation Emails**: Member invitation emails have been updated with better formatting and reliability. **Files & Drive** * **Improved Drive File List**: Enhanced file listing with better navigation in the Drive module. **New Features** **Projects & Tasks** * **Project Management Module**: Full project management with objectives, tasks, kanban board, and list views for organizing work within your organization * **Task Assignments & Notifications**: Assign tasks to members and receive email notifications for new assignments and updates * **Project Goals**: Set and track project goals with progress indicators **User Profiles** * **Merge Duplicate Profiles**: Admins can now merge duplicate user profiles with a side-by-side comparison view and full audit trail * **Privacy Default Settings**: Configure default privacy preferences at the organization level that apply to all new registrations **Contacts** * **Custom Fields for Contacts**: Add custom fields to contacts, just like user profiles, for more detailed contact management * **Bulk Delete Contacts**: Select and delete multiple contacts at once from the contact list * **Contact Source Tracking**: Track where each contact came from with automatic source field **Events** * **Event User Type Restrictions**: Restrict event visibility and registration to specific member types with permission enforcement **Companies** * **Company Member Join Date**: Track and edit when members joined a company with a new editable date field * **Company Invoice Mark as Paid**: Manually mark company invoices as paid for bank transfer payments * **Company Member Deletion**: Proper cleanup when a company is deleted, removing all associated member records **Payments & Fees** * **Default Invoice Template**: Set a default invoice template that automatically applies to new invoices * **Payment Refunds for Events**: Process refunds for event payments directly from the admin panel **Dashboard** * **Customizable Welcome Messages**: Create and customize welcome messages displayed on the member dashboard **Media & Files** * **New Image Cropper**: Redesigned image cropper component with better controls for badge uploads and profile photos **AI & Provisioning** * **AI-Powered Demo Generation**: Automatically generate demo content for new tenants by crawling an organization's website and creating realistic events, newsletters, and discussions **Discussions** * **Discussion Filter Bar**: New filter bar on the discussion list for easier browsing and searching * **Discussion Categories in Main List**: View discussion categories directly in the main discussion list **Statistics** * **Statistics Dashboard Redesign**: Split statistics into dedicated sub-pages for Membership, Finance, Geography, Leaderboards, and Platform usage * **US State-Level Geography**: Support for US state-level geographic data in statistics and member locations **Improvements** **Events** * **Event Registration Flow**: Simplified event registration and checkout experience * **Event Attendance Export**: Enhanced attendance export with more data fields * **Event Registration Data**: Improved handling of custom field values during event registration **Newsletter** * **Newsletter Batch Dispatch**: Improved newsletter sending with better batch processing * **Newsletter Builder Embeds**: Better handling of embedded content in the newsletter builder **Registration** * **Registration Form Updates**: Improved registration form layout and user experience * **Registration Footer**: New footer component on registration pages **User Management** * **User List Loading**: Improved loading state when browsing the user list * **CSV Export Pagination**: Better handling of large CSV exports with pagination **SEO** * **Subdomain No-Index**: Subdomain pages now properly set noindex to prevent search engine indexing of tenant subdomains **New Features** **Workflows** * **Workflow Automation Engine**: Create automated workflows with triggers, conditions, and actions. Set up rules like "when a member joins, send a welcome email" or "when a payment is received, update their status" * **Workflow Triggers**: Trigger workflows on membership changes, contract updates, identity verification, payments, course completions, and user inactivity * **Scheduled Workflow Actions**: Schedule workflow actions to execute at a future time (e.g., send a reminder 7 days after joining) * **Workflow Editor**: Visual editor to build and test workflows with drag-and-drop conditions and actions **Authentication** * **One-Time Password (OTP) Login**: Members can now log in with a one-time code sent to their email instead of remembering a password * **OTP for Email Changes**: Verify email address changes with a one-time code for added security * **OTP for Password Changes**: Confirm password changes with email verification * **Multi-Factor Authentication**: Added MFA support with OTP verification for admin accounts **Permission Impersonation** * **View As Another Role**: Admins can now preview the platform as if they were a different role or group member, making it easier to verify permissions and troubleshoot access issues * **Impersonation Audit Log**: All impersonation sessions are logged for security and compliance **Companies** * **Companies Module**: Full company management with create, edit, search, and member management * **Company Invitations**: Invite companies to join your organization with accept/decline/revoke/resend workflows * **Company Payments**: Company-level payment processing with Stripe connected payments and bank transfer invoicing * **Company Fee Management**: Assign and manage fees at the company level with mark-as-paid support **Donations** * **Embeddable Donation Widget**: Create donation widgets that can be embedded on external websites * **Donation Statistics**: View donation performance with built-in analytics on each widget * **Donation Payment Flow**: Streamlined donation checkout with identity validation **Discussions** * **@Mentions in Discussions**: Tag other members in discussion posts and comments with @mention autocomplete * **Real-Time Comments**: Discussion comments now update in real-time without refreshing the page **Newsletter** * **Schedule Newsletters**: Schedule newsletters to be sent at a specific date and time in the future * **Newsletter Subscriber Widgets**: New widget management page for newsletter subscription widgets **Profiles** * **Member Recommendations**: Get recommended connections based on shared interests and activities * **Referral Tab on Profile**: View and manage referrals directly from user profiles **Voting** * **Vote Collection CSV Export**: Export vote collection results as CSV for external analysis * **Real-Time Voting Updates**: Vote results now update in real-time via Mercure **Events** * **Event Attendee CSV Export**: Download a CSV file with all event attendee details * **Event User Type Permissions**: Restrict event visibility to specific member types **Email** * **Editable Email Templates**: Admins can now customize all system email templates directly from the settings panel **Import** * **Event Attendee RSVP Import**: Import event attendance with RSVP status from CSV files **Payments** * **Payment Page Redesign**: Redesigned payment landing pages with clearer pricing and donation options * **Mark Multiple Periods as Paid**: Mark multiple fee periods as paid at once for faster admin workflows * **Fee Interval Enforcement**: Fee payment intervals are now properly enforced as mandatory **Predefined Lists** * **Predefined User Lists**: Create and manage predefined user lists for quick access to common member groups **Improvements** **Newsletter** * **Newsletter Metrics**: View detailed newsletter performance metrics including open rates, click rates, and bounced recipients * **Newsletter Link Click Tracking**: Track which links in your newsletters are being clicked * **Newsletter Preview**: Improved newsletter preview before sending **Login & Registration** * **Animated Login Page**: New animated background on login, registration, and start pages * **Newsletter Registration Flow**: Improved newsletter subscription during member registration **Events** * **Event List Performance**: Faster loading of event lists with optimized API calls * **Event Status Handling**: Improved event status display and management **User Management** * **User List Performance**: Optimized user list loading with new collection serialization groups * **Social Media Icons**: Larger, more visible social media icons on user profiles **Payments** * **Invoice Bank Transfer Flow**: Improved bank transfer invoice creation and management * **Fee History Display**: Expanded fee history view with more details **Voting** * **Voting Module Overhaul**: Redesigned voting interface with improved data tables and form builder integration * **Vote Editing**: Improved vote option editing capabilities **Platform** * **UTM Parameter Tracking**: Standardized UTM tracking across all public pages (events, forms, newsletters, donations) * **Real-Time Updates**: Improved Mercure real-time update infrastructure across discussions, issues, and votes **New Features** **Events** * **Event Attendee CSV Export**: You can now download a CSV file with all event attendees, including their registration details * **Event Status Filter**: Added a new filter to view events by status (upcoming, ongoing, past) * **User Type Restrictions for Events**: Admins can now restrict event visibility and registration to specific member types * **Event Attendee Gallery View**: Switch between table and gallery views when viewing event attendees * **Send Attendance Reminders**: New option to enable/disable automatic attendance reminder emails for events **Files & Drive** * **Drive Search**: You can now search for files directly in the Drive/Files section with a new search bar **Contacts** * **Contact Import**: Import contacts from CSV files with support for name, email, phone, and social profiles * **Contact Sorting**: Contacts list can now be sorted by different columns * **Contacts in Unified Search**: Searching from the main search bar now includes contacts in results **Dashboard** * **User Type Welcome Messages**: Configure different welcome messages for different member types on the dashboard * **Sticky Welcome Message Option**: Choose whether welcome messages stay visible or can be dismissed * **Photo Upload for Dashboard**: Click to upload photos directly in dashboard organizer widgets **Payments & Fees** * **Age-Based Fee Pricing**: Set different membership fee prices based on member age ranges * **Fee Selection Improvements**: Redesigned fee selector with clearer pricing display **Groups** * **View Archived Groups**: Members can now view groups they belonged to that have been archived * **Archived Groups Hidden from Browse**: Archived groups no longer appear in the public group browser **API & Integrations** * **Multiple API Tokens**: Admins can now create and manage multiple API tokens with different permissions * **Read-Only API Tokens**: Create API tokens with read-only access for safer integrations **Email Templates** * **Event Registration Email Template**: Customize the email sent when someone registers for an event * **Event Reminder Email Template**: Customize the automatic event reminder emails **Import** * **CSV Import Examples**: Download example CSV files for all import types (users, contacts, events, badges, etc.) **Improvements** **Mobile Experience** * **Redesigned Mobile Navigation**: New transparent header and footer with improved navigation * **Mobile Profile Menu**: Redesigned profile menu for easier access on mobile devices * **Mobile Dropdown Positioning**: Dropdowns now appear at the bottom of the screen on mobile for easier tapping * **Mobile Event View**: Improved event display and editing on mobile devices * **Mobile User List**: Better user list layout with filters accessible via bottom sheet * **Mobile Tabs**: New tab design that prevents horizontal scrolling issues **Events** * **Event List Redesign**: Cleaner event list with improved search and filter controls * **Event Show Page**: Reorganized event details page with better information hierarchy * **Faster Event Loading**: Reduced duplicate API calls when loading events **User Management** * **Organizational Chart Heading**: Fixed heading display in the organizational chart view * **User Map Clustering**: Improved map pin sizes and cluster colors based on member count * **Map Filters**: Interest field filters now work correctly with the user map view **Contacts** * **Contact Modal View**: View and edit contacts in a modal without leaving the list * **Contact Form Improvements**: Social profile fields are now better organized **Newsletter** * **Newsletter Gallery Previews**: Better styled HTML previews in the newsletter gallery **Groups** * **Group Card Display**: Improved group card layout with better badge and type display * **Group Header Actions**: Reorganized action buttons in group headers **Voting** * **Vote List Improvements**: Better voting list display with clearer status indicators * **Vote Form Mobile**: Improved voting form layout on mobile devices **Dashboard** * **Dashboard Widget Corners**: Fixed issue where widget corners became square unexpectedly * **User Types Widget Colors**: Fixed color display for user type statistics on dashboard **Issue Tracking** * **Issue List Filters**: Status filter now works correctly and filters persist when navigating * **Issue Form Modal**: Text no longer overlaps with the emoji button **Other Improvements** * **Phone Country Prefix**: New phone number input with country code selector * **Birthday Selector Mobile**: Improved date picker for birthdays on mobile * **Donation Page**: Fixed display of donation amounts when product is archived * **Stripe Country Check**: Payment setup now validates your organization's country for Stripe compatibility **New Features** **Events** * **Event Status Management**: You can now define custom event statuses and track events through their lifecycle (planning, in progress, completed) * **Attendance Reminder Emails**: Configure custom email reminders to be sent before events to remind participants about attendance * **Event Propagation to Local Centers**: Events can now be propagated to all local center groups, making it easier to share organization-wide events **Members Map** * **Interactive Map with Zoom Filtering**: The member map now updates the member list as you zoom in/out, showing only members within the visible area * **Map/List View Toggle**: New button to easily switch between map view and list view when browsing members **Organization Chart** * **Revamped Organization Chart**: Improved visual design with better alignment, permissions display as tags, and the ability to add levels at any position * **Empty Groups Persist While Editing**: Empty groups now stay visible until you finish editing, making it easier to build your organization structure **Newsletter** * **Newsletter Gallery Previews**: Preview newsletter images in a gallery view before sending * **Hero Image Placement**: Better control over hero image positioning in newsletters **Groups** * **View Archived Groups**: You can now view and unarchive previously archived groups from the Groups browse page * **Filter by Archived Status**: New filter to show or hide archived groups **Drive** * **Breadcrumb Navigation**: Navigate through folders using breadcrumbs on desktop; on mobile, use the back arrow to return to parent folders * **Double-Click to Edit**: Double-click on discussion titles and descriptions to quickly edit them **User Management** * **Inline Tag Creation**: Create new tags directly while assigning them to users - no need to go to settings first * **Approve/Waitlist Buttons**: Quick action buttons to approve users or add them to waitlist directly from the user list and profile views * **Multi-Local Center Access**: Users can now have access to multiple local centers with different permission levels * **Private Profile Setting**: Users can choose to make their profile private, hiding it from members outside their local center **Donations** * **Cover Processing Fee Option**: Donors can now choose to cover the Stripe processing fee so organizations receive the full donation amount * **Floating Hearts Animation**: A delightful animation plays when donations are made **Authentication** * **Register with SSO**: New users can now register using social login (Google, Apple, LinkedIn, etc.) in addition to email/password **Profile** * **Signal & Bluesky Fields**: Added new social profile fields for Signal and Bluesky **Improvements** **Members Map** * **Improved Performance**: Member map loads significantly faster with optimized clustering and reduced API calls * **Better Cluster Zoom**: Clicking on a cluster now smoothly zooms to show individual members * **Skeleton Loading**: Loading states now show skeleton placeholders for a smoother experience **Sidebar** * **Collapsible Sidebar**: The sidebar can now be collapsed to show only icons, giving you more screen space * **Improved Animations**: Smoother transitions when expanding/collapsing sidebar sections **Local Centers** * **Improved Ordering**: Local centers are now ordered with parent-child relationships clearly visible (orphan → parents → children) * **Parent Center Access**: Parent local center now only appears if you are a member of it **User Lists (Segments)** * **Member Count Display**: User lists now show the count of members matching the criteria * **Newsletter Subscriber Count**: See how many members in a list are subscribed to newsletters * **Improved Criteria Filters**: Enhanced filtering options for creating dynamic member lists **Discussions** * **Fixed Long Title Display**: Discussion titles now properly truncate when too long **Voting** * **Improved Voting List Design**: Redesigned voting list with cards showing status badges, live indicators, and better mobile layout **Payments** * **BGN Currency Support**: Added Bulgarian Lev (BGN) conversion rate for payments **Stats Dashboard** * **Fixed Paying Users Metric**: The "paying users" statistic now correctly shows users with active memberships * **Fixed Daily/Monthly Percentages**: Corrected percentage calculations for platform usage statistics **New Features** **Members & Profiles** * **Interactive Member Map**: View members on a map with clustering and profile photos * **Map Location Field**: New location field in profiles and registration for map positioning * **Personal Drive**: Each member now has their own personal file storage space * **Gallery View for Members**: Switch to gallery view when browsing members * **Multiple Adhesions Support**: Users can now have multiple membership adhesions **Events** * **Event Type Colors**: Customize event types with colors using a color picker **Newsletter** * **Newsletter Gallery**: Browse past newsletters in a paginated gallery view **Gamification** * **Points Leaderboard**: View top members by points with time-based filters * **Points for Activities**: Earn points for event attendance, referrals, and posts **Drive & Documents** * **ORGO Docs**: Create and edit documents directly in the platform * **Floating Add Button**: Quick access floating button for creating files and folders * **Breadcrumb Navigation**: Navigate folders with clickable breadcrumbs **Authentication** * **Microsoft SSO**: Sign in with your Microsoft account * **Email Verification Code**: New 6-digit code verification for email confirmation **Statistics** * **Enhanced Statistics Dashboard**: Visual cards showing platform metrics * **Financial Statistics**: View financial data and disk usage **Administration** * **Custom Profession Types**: Manage custom profession types in settings * **Redesigned Module Settings**: Auto-save settings with improved layout * **Languages Settings Page**: Configure available languages for your organization * **Donate Button in Sidebar**: Option to show donation button in navigation **Improvements** * **Mobile Drive**: Better file management experience on mobile devices * **Dark Theme Tables**: Fixed table styling in dark mode * **Filter Icons**: Visual filter indicators in list views * **Advanced Member Filtering**: More powerful member search filters * **Under-18 Privacy on Maps**: Enhanced privacy protection for minors on member maps * **Video Thumbnails**: Preview video content in discussions * **Auto-Login After Registration**: Automatically logged in after completing registration **New Features** **Dashboard** * **Customizable Dashboard Widgets**: Administrators can now configure dashboard layouts with custom widgets including weather forecasts, discussion feeds, and quick link cards * **Widget Color Themes**: Dashboard widgets now support custom background colors with light/dark theme adaptation * **Welcome Message on Dashboard**: The sticky welcome message is now visible on both standard and custom dashboards **Local Center Map** * **Interactive Map Search**: New map view to search and explore local centers by location, with distance radius filtering * **Language Filtering**: Filter local centers by the languages they support * **Age Group & Day Filters**: Filter local centers by age groups served and meeting days * **Favorite Local Centers**: Save your preferred local centers for quick access (requires login) * **Social Media Links**: Local centers can now display their social media profiles on the map **Learning Management (LMS)** * **Course Management**: New course creation and editing interface for administrators * **Lesson Navigation**: Browse through course lessons with progress tracking * **Quiz System**: Take quizzes within courses with multiple choice and multi-select questions * **Enforced Courses**: Administrators can require users to complete specific courses before accessing other features * **Course Badges**: Automatically award badges upon course completion **Waitlist Management** * **Waitlist Status Page**: Users can now check their waitlist position and estimated wait time * **Priority Management**: Administrators can set priority levels for waitlist entries * **Bulk Actions**: Approve, reject, or notify multiple waitlist entries at once * **Volunteer Priority**: Children of volunteers receive higher priority on waitlists **Family Management** * **Family Member Management**: Add and manage family members from your profile * **Child Registration**: Parents can register children directly through the platform * **Family Name Editing**: Customize your family group name **Organizational Chart** * **Visual Org Chart**: New interactive organizational chart showing roles and hierarchy * **Drag-and-Drop Roles**: Administrators can reorganize roles by dragging them between groups * **Role Color Coding**: Roles display with color-coded tags for easy identification * **Empty Group Placeholders**: Visual indicators for organizational levels without assigned roles **Profile & Activity Logs** * **Profile Update Logs**: View who last updated a profile and when * **Activity Log Filtering**: Filter profile activity logs by type and date * **Email Logs**: View email communication history for contacts and users **Improvements** **Sidebar Navigation** * **Custom Menu System**: Administrators can fully customize the sidebar menu structure * **Icon Selection**: Choose from hundreds of icons for menu items * **Permission-Based Visibility**: Menu items can be shown/hidden based on user permissions * **Collapsible Categories**: Menu categories can be expanded or collapsed **Events** * **Calendar View Enhancements**: Improved calendar navigation with a "Today" button * **Event Date/Time Display**: Fixed event date and time display issues **Discussions** * **Reaction Buttons**: Colorful reaction buttons for discussion posts and comments * **Mobile Comment Input**: Sticky comment input on mobile for easier typing * **Discussion Images**: Discussion category widgets now display cover images **Drive/Files** * **Drag-and-Drop**: Move files and folders by dragging them to new locations * **Improved File Preview**: Better preview support for images, videos, and PDFs * **Breadcrumb Navigation**: Enhanced folder navigation with clickable breadcrumbs * **Gallery View**: Improved image gallery with navigation controls **Payments** * **Payment Link Copy**: Easily copy payment links for fees to share with members * **Product Options Sorting**: Drag-and-drop reordering for product options * **Donation Page Improvements**: Cleaner layout for donation pages with better option display **Notifications** * **Notification Sidebar**: New slide-out panel for viewing notifications * **Simplified Email Settings**: Streamlined notification preferences **Theming** * **Improved Dark Mode**: Better color contrast and consistency in dark theme * **Grey Tinting**: Interface greys now adapt to match each theme's primary color * **Sidebar Colors**: Updated sidebar styling for better visibility **New Features** **Sidebar Menu Customization** * **Menu Organizer**: Administrators can now customize the sidebar menu structure with a drag-and-drop interface. Add, remove, and reorder menu categories and items to match your organization's workflow. * **Hotlinks per Category**: Create custom quick-access links within specific menu categories for faster navigation to frequently used pages. * **Permission-Based Menu Items**: Menu items now automatically show or hide based on user permissions and enabled modules. **Webhooks Integration** * **Webhook Subscriptions**: Connect your ORGO platform to external services like n8n. Configure webhooks to automatically notify external systems when members are created, updated, contracts are signed, payments are processed, and more. * **Webhook Delivery Logs**: View detailed logs of all webhook deliveries including success/failure status and retry attempts. * **Webhook Secret**: Set a secret on a subscription and every delivery carries an `X-Webhook-Signature` header derived from it. (This first version was a plain checksum. Cryptographic signing arrived in the August 2026 entry at the top of this page.) **Email Template Editor** * **New TipTap Editor**: Redesigned email template editor with improved formatting capabilities and placeholder insertion. * **Live Preview**: Preview emails with placeholder values replaced before sending. * **Send Test Email**: Test your email templates by sending them to yourself before activating. * **Module-Based Templates**: Email templates now only appear for modules that are enabled in your organization. **Professional Network** * **Interest Filtering**: Filter members in the professional network by their interests using the configured custom field. * **Adult-Only Listings**: Professional network now automatically excludes minors for privacy protection. * **Profession Industry Display**: Improved display of profession and industry information in member listings. **Contacts & Search** * **Unified Search**: Search across both members and contacts from a single search bar with tabs to filter results. * **Contact Tags**: Add tags to contacts for better organization and filtering, similar to member profiles. **Improvements** **User Interface** * **Bulma 1.0 & Buefy 3.0 Migration**: Updated to the latest UI framework versions for improved performance and modern styling. * **Dark Mode Improvements**: Enhanced dark theme with better color consistency and contrast across all components. * **Theme Persistence**: Your light/dark theme preference is now saved and persists across sessions. * **Mobile Responsiveness**: Improved layouts for discussions, events, fees, payments, and group management on mobile devices. * **Rounded Buttons**: All buttons now use consistent rounded styling throughout the platform. **Discussions** * **Required Titles**: Discussion posts now require a title to improve organization and searchability. * **Category Management**: Inline category management with drag-and-drop reordering directly from the discussions page. * **Reactions Popup Fix**: Fixed display issues with the reactions popup on discussion posts. **E-Documents & Contracts** * **Pre-Signed Contract Flow**: Improved workflow for contracts that require administrator signature before member signing. * **Contract Number Generation**: Automatic sequential contract numbering for better tracking and compliance. * **Expiry Notifications**: Updated Romanian language texts for contract expiration reminder emails. * **Go to Platform Button**: Contract completion emails now include a direct link to access the platform. **Events** * **Copy Event Link**: Easily copy event page links with a single click for sharing. **Payments & Invoices** * **Invoice Validation**: Backend validation to prevent invoice creation errors. * **Stripe Price Updates**: Product price names now sync correctly with Stripe. **Groups** * **Group Visibility Icon**: Groups now display visibility icons in the browse view. * **Private Group Mobile Fixes**: Improved editing experience for private groups on mobile devices. **Image Uploads** * **Improved Cropper**: Enhanced image cropping interface with better selection controls. **Custom Fields** * **Drag-and-Drop Options**: Reorder dropdown, checkbox, and radio button options with drag-and-drop. **Member Lists** * **UI Refresh**: Redesigned member list creation and viewing interface. * **Tag Filtering**: Filter member lists by tags with duplicate prevention. **Issue Tracking** * **Drag-and-Drop Priority**: Reorder issues by dragging to automatically update priority. * **Mobile List View**: Improved issue list display on mobile devices. **New Features** **User Tags** * **Profile Tags Management**: Administrators can now create and manage user tags from Settings. Tags can be assigned to user profiles for better organization and categorization * **Tags Display on Profiles**: User tags are now visible on profile pages with responsive mobile support **Contact Statuses** * **Custom Status Labels for Contacts**: New profile status feature allows organizations to define custom status labels with colors for contacts, helping track contact lifecycle stages **Issues & Tasks** * **Drag-and-Drop Issue Ordering**: You can now reorder issues by dragging and dropping them when sorted by priority * **Close with Comment**: New ability to close an issue and add a closing comment in one action * **Issue Assignees Display**: Issue assignees are now visible directly in the issue list view **Image Cropping** * **Image Cropper for Uploads**: New image cropping tool when uploading logos and profile images, allowing you to crop and adjust images before saving **Finance Statistics** * **Financial Analytics Dashboard**: New dedicated finance statistics page accessible from the sidebar, showing payment analytics with customizable date ranges **Newsletter** * **Send Emails to Event Participants**: You can now create newsletters directly targeting event participants from the event page **Improvements** **Mobile Experience** * **Improved Mobile Navigation**: Bottom tab navigation bar for quick access to Dashboard, Groups, and Events on mobile devices * **Responsive Profile Pages**: User profile pages are now optimized for mobile with better layout and touch-friendly buttons * **Mobile-Optimized Modals**: Add issue and discussion modals now display fullscreen on mobile for easier input * **Better Mobile Tables**: Contact lists, payment lists, and user lists now display properly on mobile screens * **Voting Page Mobile Support**: Voting pages are now fully responsive with improved mobile layout **Dashboard** * **Sticky Message Expansion**: Long sticky messages on dashboard now have "See more/Less" toggle * **Public Groups Section**: Dashboard now shows public groups section for easier discovery * **Improved Card Shadows**: Better visual distinction for dashboard cards **Discussions & Issues** * **Drag-and-Drop File Upload**: You can now drag and drop files directly into posts and comments * **Inline Category Management**: Discussion categories can now be managed inline without leaving the page * **Issue Status Reordering**: Group administrators can reorder issue statuses and types via drag-and-drop * **Reactions Display**: Improved reactions display on discussions with better mobile layout **Events** * **Event Date Language**: Event dates now display in your selected language * **Hide Share for Drafts**: Share button is now hidden for draft events * **Increased Upload Limit**: Event media upload limit increased to 150MB per batch * **Admin Media Deletion**: Administrators can now delete any event media **Voting** * **Redesigned Voting Interface**: Voting list and detail pages have been refreshed with improved layout * **Mobile Voting**: Better mobile experience when casting votes and viewing results **Custom Fields** * **Inline Custom Field Management**: Custom fields now update dynamically and can be managed inline * **Visual Options Editor**: Custom field options now use a visual editor instead of JSON input * **Responsive Custom Fields Page**: Custom fields settings page is now mobile-friendly **Documents & Contracts** * **Improved Document Signing**: Better scrolling and layout for DocuSign document preview * **Contract Expiry Notifications**: Updated email templates for contract expiry reminders **User Interface** * **Rounded Buttons**: Consistent rounded button styling throughout the platform * **Improved Search Bar**: Top search bar has been redesigned for better usability * **Group Header Tabs**: Navigation tabs in group headers now display as pills on mobile * **Header Image Updates**: Header images now update immediately after upload without page refresh * **Dark Mode Logo Support**: Organizations can now upload separate logos for dark mode **Payments** * **Pay Modal in User Profile**: Direct payment modal accessible from user fee tab * **Better Error Messages**: Improved error display during checkout process **Newsletter** * **Default Public Setting**: New newsletters are now set to public by default * **Redesigned Newsletter List**: Newsletter management page has been refreshed with better layout **Registration** * **Terms Agreement Required**: Registration now properly enforces agreement to terms and GDPR before proceeding * **Improved Registration Messages**: Better feedback messages during user registration **New Features** **Products & Donations** * **Multi-Language Product Descriptions**: Products and donation pages now support German (DE) and English descriptions alongside the default language, automatically displaying the right language based on visitor preferences. * **Custom Thank You Message**: Add a personalized thank you message that displays after successful payments on donation/product pages. * **Hero Video Support**: Add a video URL to display as the hero media on product/donation pages instead of a static image. * **CHF Bank Account Support**: Organizations can now add a separate CHF IBAN for Swiss Franc payments at both tenant and local center levels. **External Contacts** * **Newsletter Subscription Status**: View whether external contacts are subscribed, unsubscribed, or not yet subscribed to newsletters. Includes ability to unsubscribe contacts directly from their profile. * **Delete Button for HR**: Local center HR administrators can now delete external contact profiles when needed. **Mobile App Integration** * **Native SSO Login**: New OAuth flow supporting single sign-on for native mobile applications. **Improvements** **Mobile Experience** * **Events Page**: Improved layout and scrolling on mobile devices with better tag wrapping and spacing. * **Groups List**: Fixed horizontal scrolling issues and improved card layouts on mobile. * **Local Chapters List**: Better responsive design for browsing local chapters on smaller screens. * **Files/Drive**: Tables now scroll properly on mobile with file actions available in a dropdown menu. Some columns are hidden on mobile for better usability. * **Issues List**: Filter controls now work better on mobile devices. * **Modals**: Login, MFA, and reactivation modals now display correctly on mobile without transparency issues. * **Dashboard**: Fixed sticky padding issues on mobile dashboard. **Newsletter** * **Metrics Placement**: Newsletter statistics (opens, clicks) now display in a better position on the newsletter detail and preview pages. * **Clone Fix**: Fixed an issue where cloning a newsletter could fail in certain conditions. * **Builder Session**: Extended the newsletter builder session duration to 3 hours to prevent timeout during long editing sessions. **Events** * **Attendance View**: Improved layout for the attendance/check-in interface with clearer controls and better mobile support. * **Public Event Page**: Better caching for faster loading of public event pages. **User Interface** * **Dark/Light Mode Toggle**: Theme toggle icons now display correctly in the header and sidebar menus. * **Password Field Icons**: Fixed visibility toggle icon display in password fields across login, registration, and password reset pages. * **Sidebar Navigation**: Added visual tree lines connecting submenu items for clearer navigation hierarchy. * **Text Editor**: Improved paragraph spacing in the TipTap rich text editor content. * **Workspace Switcher**: Added workspace switcher to mobile header for easier navigation between organizations. **Ticketing & Pricing** * **Ticket Management Table**: Improved ticket/pricing table layout with clearer action buttons and better information display including subscription and restriction badges. **E-Documents** * **Document Preview**: Improved document preview experience with better placeholder handling. * **Custom Fields**: Fixed display sizing issues with custom field widgets. **Payments** * **Multi-Currency Progress**: Donation progress bars now correctly calculate totals when payments are made in different currencies using conversion rates. * **Product Save**: Fixed an issue where saving product settings could fail in certain conditions. **Groups** * **Browse Groups**: Improved group card design and list layout with better visual hierarchy. **Login** * **Autocomplete Support**: Login form now properly supports browser password autocomplete/autofill. **New Features** **Newsletter** * **User Lists for Recipients**: Create static or dynamic user lists to target specific groups when sending newsletters. Dynamic lists automatically update based on criteria like membership status, local center, or custom filters. Access lists from the new "Lists" menu item in the Newsletter section. * **List Member Management**: View, add, and remove members from user lists. See member count and list type (static/dynamic) at a glance. **Files & Gallery** * **Gallery View Mode**: New gallery view for browsing images in the Drive with lightbox preview, keyboard navigation, and download button directly from the gallery modal. * **Folder Download**: Download entire folders as a single archive with the new download folder button. * **Improved File Icons**: Files now display type-specific icons (PDF, image, document) for easier identification. **Membership Fees** * **Price Versioning**: Create new versions of membership fee prices with effective dates. Track price history and see which version is currently active. Useful for managing annual fee changes. * **Lifetime Membership Support**: Enhanced handling for lifetime memberships with zero-amount fee processing. * **Pro-Rated Fees**: System now calculates pro-rated amounts when members join mid-cycle. **Dashboard** * **Welcome Message with Image**: Administrators can now add an avatar/photo next to the welcome message (e.g., CEO photo) for a more personal touch. * **Sticky Welcome Message**: Option to keep the welcome message visible even after users dismiss it. * **Horizontal Scroll Buttons**: Quick action buttons on the dashboard now have horizontal scroll controls on mobile. **Payments** * **Product Statistics Page**: View detailed payment statistics for donation/product pages including total collected, number of payments, and conversion metrics. **Improvements** **User Interface** * **Unified Sort & Filter Controls**: Consistent filter and sort controls across Members, Events, Discussions, and Files pages for a more cohesive experience. * **Event Ticket Display**: Ticket names now display in bold on event pages for better readability. Location now links to Google Maps when coordinates are available. * **Registration Page Title**: Custom title text can now be configured for the registration page. **Identity Verification** * **Improved Admin Validation Interface**: Enhanced layout for administrators validating member identity documents with better scrolling after validation and clearer status messages. * **Payment Identity Messages**: Clearer messaging during identity verification in payment flows. **Payments** * **Donation Page Description**: Increased character limit for donation page descriptions to accommodate longer text. * **Payment Proof PDFs**: PDF receipts now use the organization's configured timezone for accurate date/time display. **E-Documents** * **Profile Documents Tab**: Users now see a clear message when no documents are available instead of an empty space. **Roles** * **Role Position Updates**: Fixed issue when updating role positions in the organization structure. **Newsletter Builder** * **Improved Editor Embedding**: Newsletter builder now works more reliably across different browser configurations with better error handling. **Multi-Language** * **Text Management Fix**: Fixed a bug affecting multi-language text management for organizations using multiple languages. **New Features** **Analytics Dashboard** * **Organization Statistics Page**: New comprehensive analytics dashboard for administrators showing email metrics, user activity, discussion engagement, and newsletter subscriber statistics. View daily/monthly active users (DAU/MAU), login trends, and detailed breakdowns of platform usage. * **Kudos Leaderboard**: New leaderboard showing top members who give and receive kudos (reactions), with filtering by status and local center. Track community engagement and recognize active members. * **Product Analytics**: Enhanced product pages now display detailed conversion analytics including page views, UTM source/campaign tracking, device breakdown, and widget performance charts. * **Payment Charts on Dashboard**: Administrators can now see payment trends for the last 60 days directly on their dashboard. **Alliance/Aggregator Administration** * **Multi-Tenant Admin Login**: New secure admin portal for managing multiple organizations (alliances). Administrators can now log in to a central dashboard to view aggregated statistics across all member organizations with MFA protection. * **Cross-Organization Statistics**: View combined metrics across alliance member organizations including total users, emails sent, discussions, and newsletter subscribers. **Authentication & Registration** * **Redesigned Login Page**: Fresh, modern login experience with animated backgrounds and improved layout for both desktop and mobile. * **Improved Registration Flow**: Updated registration page with better visual design and clearer organization branding. * **New Tenant Signup Experience**: Redesigned "Start your trial" page with animated backgrounds, country-based defaults for currency/timezone/language, and a streamlined 3-month trial setup. **E-Documents** * **Appendix PDF Templates**: New appendix templates (Anexa 14, Anexa 21) available for generating payment proof documents. * **Mark Contract as Signed**: Administrators can now manually mark contracts as signed on behalf of users, with tracking of who performed the action. **Improvements** **User Interface** * **Refreshed Sidebar Design**: Updated sidebar with new blue theme and improved border styling for better visual hierarchy. * **Improved File Browser**: Enhanced drive/files view with better icon display for files and folders, and clearer owner information. * **Onboarding Improvements**: Get Started page now shows completion checkmarks for completed steps and clearer progress indicators. **Payments** * **Donation Fee Transparency**: Payment pages now show donors exactly how much of their donation goes to the cause after processing fees. * **Product Form Updates**: Improved product creation form with better widget configuration options. **Badges** * **Badge List Visibility**: Improved badge display logic to show relevant badges based on user permissions. **Groups & Roles** * **Sync Button Tooltip**: Added helpful tooltip explaining the role sync functionality in group headers. **Discussions** * **XSS Protection**: Enhanced security for discussion posts and comments to prevent cross-site scripting attacks. **Charts & Visualization** * **Migrated to ECharts**: Analytics charts now use ECharts library for better performance and more interactive visualizations with smooth animations and improved tooltips. **Localization** * **Bulgarian & Ukrainian Translations**: Updated translations for Bulgarian, Ukrainian, and Portuguese languages. **New Features** **Payments & Fees** * **Local Center Stripe Integration**: Local centers can now connect their own Stripe accounts to collect membership fees directly. Admins can view which local centers have Stripe accounts connected in the local centers list. * **Organization Fee Column**: Added a new column in the local centers list showing organization fee status for better oversight. * **Subscription Identity Verification**: Members with recurring subscriptions now receive email reminders to verify their identity before the next billing cycle. A dedicated confirmation page guides users through the identity verification process. **E-Documents** * **Default Signature per Contract**: Administrators can now set a default signature for each contract template, streamlining the document signing process. * **External Document Access**: Non-members can now access and sign documents by providing their name and email, with a simplified public preview form. * **Generate External Links**: Added ability to generate and copy shareable links for documents directly from the document list. **Reports** * **Annual Report Printing**: Improved the annual report view with better print support through an embedded iframe layout. * **Public UTM Statistics**: Added a public statistics page for tracking UTM campaign performance. **Localization** * **Bulgarian Language Support**: Added Bulgarian translations across the platform. **Improvements** **Membership Management** * **Archived Fee Visibility**: Archived membership fee options are now hidden from registration and membership forms, showing only active fee options to users. * **Product Options Archiving**: Administrators can now archive product options instead of deleting them, preserving historical data while hiding them from active selections. **Organizational Chart** * **Enhanced Role Display**: The organizational chart now shows role member counts with a cleaner layout. Roles with many members display a count badge instead of listing all names. * **Improved Loading**: Fixed flickering issues when loading the organizational chart. **Newsletter** * **Subscriber Count Display**: Newsletter forms now show the accurate count of subscribers who will receive the newsletter. * **Email Search for Subscribers**: Added email search functionality in the product subscribers list for easier subscriber management. **Payments** * **Payment Thank You Page**: Improved the payment confirmation page with clearer messaging and better layout for donation pages. * **Product Tabs Memory**: The platform now remembers which tab you were viewing on product pages when navigating back. **User Interface** * **Discussion Comments**: Improved the visual layout of comment attachments in discussions with better image gallery display. * **Embedded Payment Pages**: Fixed scrolling issues on embedded payment pages for smoother user experience. **New Features** **Payments & Donations** * **Multi-Factor Authentication (MFA)**: Added email-based two-factor authentication for enhanced account security when logging in from new devices. MFA codes are valid for 48 hours per trusted device. * **UTM Tracking for Campaigns**: You can now configure UTM Source, Campaign, and Medium parameters in product settings to track the effectiveness of your marketing campaigns. * **Product Analytics Dashboard**: View detailed statistics for your donation and payment pages including total views, conversion metrics, and traffic sources with visual charts. * **Payment Filtering by Email**: Search and filter payments by donor/payer email address in the payments list. * **Share Modal on Thank You Page**: After completing a donation, users can easily share the campaign on social media (Facebook, Twitter, WhatsApp, Email) with one click. **Identity Verification** * **Automated Identity Validation**: The system now automatically validates Romanian ID cards (including the new card format) and passports using OCR, reducing manual verification workload. * **Identity Upload Required Per Donation**: For compliance, each donation now requires identity document upload (configurable per tenant). **Events** * **Event Ticket Descriptions**: Event ticket types now display their descriptions on the public event page, helping attendees understand what each ticket includes. **Integrations** * **HubSpot Integration**: Connect your ORGO account with HubSpot CRM to automatically sync contacts and donation amounts. Configure your HubSpot API key in Tenant Settings > Integrations. * **Facebook Pixel Support**: Add your Facebook Pixel ID to track conversions and optimize your advertising campaigns. **Documents (E-Contracts)** * **Document Signature Tracking**: E-documents now track signature dates and upload times for better audit trails. * **Improved Document Filtering**: Filter signed documents by contract, user, status, and unit. **Improvements** **Payments & Donations** * **Redesigned Donation Page**: The public donation page has been completely redesigned with better mobile responsiveness, clearer price selection, and animated interactions. * **Real-time Donation Counter**: See recently donated amounts with a "just donated" counter showing activity from the last few hours. * **Top Donors Display**: View top and most recent donors on the donation page with an option to toggle between views. * **Progress Bar Fix**: Donation goal progress bars now display correctly. * **Subscription Activation Flow**: Subscriptions for political donations now activate only after identity verification is validated (compliance requirement). * **Price Sorting in A/B Testing**: Product prices in A/B testing mode are now sorted in ascending order for better user experience. **Comments & Social** * **Comment Pagination**: Comments on donation pages now paginate at 30 items for better performance. * **Admin Comment Management**: Admins can now view, approve, and reject donation comments from the product management area. * **Words of Support Design**: Refreshed visual design for the "words of support" section on donation pages. **Identity & Profiles** * **Romanian CNP Validation**: The system now validates Romanian personal identification numbers (CNP) when updating identity information. * **Better Passport OCR**: Improved text extraction from passport documents for more accurate data capture. * **New Romanian ID Card Support**: Added support for the newer Romanian identity card format (backside processing). **User Interface** * **Floating Mobile Buttons**: Action buttons on mobile now float at the bottom of the screen for easier access. * **Group Images**: Group logos now display properly contained and centered in listings and creation forms. * **Privacy Tooltip**: Added helpful tooltip explaining privacy options on donation forms. * **Dashboard Statistics**: Dashboard statistics are now shown only for organizations with HR features enabled. **Email & Notifications** * **Improved Email Templates**: Updated donation confirmation and identity reminder email templates with better formatting. * **Newsletter Bounce Rate Fix**: Fixed calculation of newsletter bounce rates for more accurate delivery statistics. * **Drive Notifications Removed from Digest**: File storage notifications no longer clutter the daily digest email. **Membership** * **Membership Renewal Fix**: Fixed issue where users with canceled subscriptions couldn't renew their membership. * **Fee Status Display**: Membership fee status now correctly shows based on active fee rather than expiration date. **New Features** **E-Documents** * **Public Document Editing**: External users can now edit documents shared via public access links without needing to log in. This makes it easier for non-members to complete and sign documents sent to them. **Improvements** **E-Documents** * **Town Selection**: Improved the town/locality selection when filling out document fields for more accurate address information. **Newsletter** * **Widget Improvements**: Enhanced the newsletter subscription widget with better styling and clearer action buttons. **New Features** **Newsletter** * **Embeddable Newsletter Widget**: You can now embed a newsletter subscription widget on external websites, allowing visitors to subscribe to your organization's newsletter directly from your website **E-Documents** * **Admin Co-Signature Support**: Documents can now require an administrator signature after the member signs, enabling two-party contract workflows * **Create Documents for External Profiles**: You can now create and assign e-documents directly to external profiles (non-members) * **Unit Assignment for Documents**: Assign documents to specific organizational units for better organization and filtering * **Clone Documents**: Quickly duplicate existing document templates using the new clone button * **Automatic Email on Completion**: When all required signatures are collected, the signed document is automatically emailed to the signer **Events** * **Public Event Sharing**: Share events via a public link that anyone can view, with an improved share button design * **Download Event Tickets**: Attendees can now download their event tickets directly from the event page * **Free Event Label**: Events without a fee now clearly display a "Free" label **Editor** * **Image Resize and Alignment**: You can now resize and align images directly in the rich text editor when creating newsletters, documents, or event descriptions **Improvements** **E-Documents** * **Filter Documents by Unit**: Filter the document list by organizational unit to find documents faster * **Display in Profile Option**: Choose which signed documents appear on member profiles * **Contract Status Tracking**: Documents now show clear status indicators (unsigned, signed by user, complete, expired) * **Improved Document Preview**: Better layout when viewing and signing documents **Events** * **Enhanced Public Event Page**: Public event pages now display more event details and a cleaner layout * **Event Description Display**: Event descriptions now render with proper formatting including images **Products** * **Widget Display Options**: Configure how payment widgets appear (popup or vertical layout) with customizable title and description visibility **Navigation** * **Simplified Finance Menu**: Removed redundant links from the finance sidebar for a cleaner navigation experience **New Features** **Events** * **Public Events Page**: Browse public events without logging in - view event details, dates, locations, and register directly from a public-facing events list * **Add to Calendar**: Easily add events to your Google, Outlook, or Yahoo calendar directly from the event page * **Interactive Location Maps**: Events now display location on an interactive map with address autocomplete when creating events * **Rich Text Event Descriptions**: Event organizers can now use rich text formatting (bold, italic, lists) in event descriptions using the new TipTap editor **Groups** * **Group Categories**: Administrators can now organize groups into color-coded categories for better organization * **Group Info Pages**: Groups now have dedicated info pages with rich text content * **Admin-Only Posting**: Group admins can restrict discussions, events, and file uploads to administrators only * **Auto-Include All Members**: Option to automatically include all organization members in a group **E-Documents** * **Public Document Signing**: Share documents with external users via secure temporary links for signing without requiring login * **Company Details Placeholders**: Add company information (name, identifier, address) as placeholders in e-Documents that auto-fill from user profiles * **Required Documents**: Mark specific documents as required during user onboarding **Referral System** * **Member Referrals**: New referral system allows existing members to refer new users before they can complete registration * **Referral Tracking**: View who referred you and track your own referrals from your profile **Profiles** * **Company Details**: Users can now add company information (company name, tax ID, address) to their profile with autocomplete search * **Company Details on Event Registration**: Company information can now be collected during event registration **Payments** * **Payment Links in Emails**: Membership renewal reminder emails now include direct payment links for easier fee payment **Localization** * **Ukrainian Language Support**: The platform now supports Ukrainian language **Improvements** **Events** * **Timezone Display**: Event times now clearly show timezone information * **Pre-filled Registration**: When logged in, event registration forms are pre-filled with your profile information * **Online Event Links**: Email notifications for online events now properly display meeting links even when no physical location is set **Groups** * **Improved Group Cards**: Redesigned group cards with category colors and better visual organization * **Follow Groups**: Improved group following functionality for non-members **User Experience** * **Dark Mode Improvements**: Fixed theme preference display for users who haven't set a preference * **Safari Icon Fixes**: Resolved icon display issues on Safari browser * **Improved Onboarding**: Enhanced user onboarding flow with group selection **E-Documents** * **Document Preview**: Improved document preview with signature placement visualization * **Custom Field Support**: Better handling of custom fields in document templates **Registration** * **Customizable Form Text**: Administrators can add custom text before and after registration forms * **Checkbox Handling**: Fixed checkbox behavior on registration pages **Voting** * **Email Notifications**: Members now receive email notifications when a new vote is published **New Features** **Invoices** * **Manual Invoice Creation**: Administrators can now create manual invoices for members and external contacts directly from the platform * **Invoice Email Sending**: Send invoices via email to recipients with a single click * **Invoice PDF Download**: Download invoices as PDF documents for record-keeping * **Online Payment for Invoices**: Recipients can pay invoices online via Stripe payment links * **Bank Transfer Support**: Generate invoice series for bank transfer payments with payment details displayed to users * **Invoice Status Management**: Mark invoices as paid or void them as needed **Email Logs** * **Email Log Viewer**: New section in the admin menu to view all sent emails (transactional and newsletter) * **Email Search**: Filter email logs by recipient name * **Email Type Indicators**: Visual tags distinguish between transactional emails and newsletters **Newsletter** * **Recipient Count Preview**: See the estimated number of recipients before sending a newsletter * **Bounced Email List**: View which email addresses have bounced from newsletter sends * **Click Tracking**: Track total link clicks on sent newsletters **Subscriptions** * **Cancel/Resume Subscriptions**: Administrators can cancel or resume user subscriptions from the payment management screens * **Subscription Notifications**: Users receive email notifications when subscriptions are created, paid, or deleted **E-Documents (Contracts)** * **Membership Contract Requirement**: Configure contracts that must be signed before purchasing membership * **Signature Cancellation**: Enable option to allow users to cancel their signatures on contracts * **Contract Duration Settings**: Set contract validity duration in months * **Contract Visibility in Profile**: Membership contracts now displayed in user profile pages **Events** * **Share Event Button**: New share button on event pages to easily copy event links * **Invited Attendee Tag**: Visual indicator showing which attendees were invited to an event **Local Centers** * **Map Description**: Add descriptions to local centers that display on the public map view **Locations** * **International Town Search**: Search and add towns from any country using Geonames integration - no longer limited to pre-loaded locations **Improvements** **User Interface** * **Improved Filter Organization**: Better ordering and display of filters on user list page * **Better Birthday Input**: Improved date picker with placeholders for birthday selection during registration * **Notification Settings Table**: Cleaner table layout for configuring notification preferences during onboarding **Payments** * **Fee Permission Update**: Local center admins can now modify fees (previously required tenant financial admin) * **Payment Settings Display**: Stripe account information now properly displayed in payment settings **Profiles** * **Password Change Without Logout**: Users can change their password without being logged out * **External Profile Deletion**: Improved handling when deleting external profiles with invalid payments **Membership** * **Fee Members View**: Improved layout and display of member fees by local center with better mobile support **New Features** **Payments & Donations** * **Donation Page Improvements**: Redesigned payment page with better layout for donations, including a "Show more/less" toggle for long product descriptions * **Top Donors Display**: New modal showing top and most recent donors on donation pages * **A/B Testing for Pricing**: Added ability to create price variations for products to test different pricing strategies with analytics * **Refund Payments**: Admins can now refund payments directly from the payments list * **Currency Support**: Products now support multiple currencies with proper display **Newsletter** * **New Email Editor**: Completely rebuilt newsletter editor with drag-and-drop functionality and image uploads * **Template Management**: Save and reuse newsletter templates for faster campaign creation * **Unsubscribe Link**: Newsletters now automatically include an unsubscribe link for compliance * **Placeholder Support**: Use dynamic placeholders in newsletters (member name, organization name, etc.) **Profiles & Members** * **Address Fields**: New address and postal code fields added to member profiles * **Contacts Search**: Improved search functionality for external contacts with newsletter subscription toggle * **Profile Details Facelift**: Updated user profile display showing profession, location details, and membership information **Email Notifications** * **Customizable Email Templates**: Admins can now customize transactional email templates (welcome messages, membership renewal reminders) * **Membership Renewal Reminders**: Automatic email reminders sent 1 month before, 7 days before, and on membership expiration day * **Renewal Success/Failure Notifications**: Members now receive confirmation emails when their membership auto-renews or fails **Badges & Achievements** * **Volunteer Hours Tracking**: Track and manage volunteer hours for members with automatic badge assignment based on hours completed * **Badge Statistics**: View badge completion statistics and progress **Products & Subscriptions** * **Bundle Memberships**: Create family or group membership bundles where a coordinator can add members * **Share Links**: Easily share product/donation page links with a copy button * **Lifetime Membership Display**: User list now shows "Lifetime" status for lifetime memberships **Improvements** **User Interface** * **Rounded Buttons**: Consistent rounded button styling across the platform * **Payment Page Layout**: Improved mobile responsiveness and card-based layout for payment pages * **Product Management**: Tabbed interface for product details, pricing options, and analytics * **Stats Page**: Better display of tag statistics with rounded tag badges **Payments** * **Mark as Paid**: Improved interface for manually marking payments as paid with date selection * **Payments List**: Better filtering and display of payment information including Stripe links * **Invoice Frontend**: New invoice management interface (work in progress) **Newsletter** * **Sent Status**: Newsletter list now shows "Sent" instead of "Send" for completed campaigns * **Email Validation**: Stricter email validation for newsletter recipients to reduce bounces **Administration** * **Admin Notifications**: Increased limit for new user notifications from 5 to 10 admins * **Dashboard Contacts**: Fixed total contacts count on dashboard **New Features** **Voting System** * **Vote Collections**: You can now organize multiple related votes into collections, making it easier to manage elections with multiple positions or questions * **Clone Votes**: Quickly duplicate existing vote configurations to create similar elections without starting from scratch * **Real-time Vote Updates**: Vote results and voter status now update in real-time without needing to refresh the page * **Vote Integrity Page**: New integrity verification page with digital seal to ensure vote authenticity and transparency * **Preliminary Results**: Option to show preliminary results during active voting periods * **Poll Mode**: New poll type for quick informal surveys alongside formal elections **Payments** * **Mark Membership as Paid**: Administrators can now manually mark member fees as paid for cash, check, or bank transfer payments directly from the member profile **Navigation** * **Hot Links**: New customizable quick-access links in the sidebar for frequently used pages, discussion categories, or events **Improvements** **Voting System** * **Voter Management**: Improved interface for adding, removing, and editing voter aliases * **Vote Status Display**: Clearer visualization of vote status (draft, published, closed) * **Eligible Voters Count**: Vote details now show the total number of eligible voters **User Interface** * **Link Colors**: Updated link color to a more accessible blue shade throughout the platform * **Breadcrumb Navigation**: Improved breadcrumb design in the Drive/Files section * **Lifetime Membership Badge**: Member listings now clearly indicate lifetime membership status **Official Gazette** * **Improved Layout**: Better presentation of gazette entries with enhanced link previews **New Features** **Payments & Donations** * **Donation Comments & Support Messages**: Donors can now leave public messages of support when making donations. These messages are displayed on the payment page along with top donations and recent contributions. * **Comment Management for Admins**: Administrators can approve or reject donor comments before they appear publicly on donation pages. * **Separate Event Payment Page**: Event ticket purchases now have a dedicated payment page, separate from product/donation payments, with improved event information display including dates and countdown. * **Subscription Cancellation Link**: After completing a subscription payment, users now receive an email with a link to manage or cancel their subscription. **Tenant Onboarding** * **New Onboarding Checklist**: Organization administrators now see a guided setup wizard when first configuring their tenant. The checklist includes steps for setting up modules, configuring online payments, setting organization type, configuring languages, creating the first group, creating the first event, inviting the first user, and branding setup. **Discussions** * **Reactions Popup**: You can now click on reaction counts to see who reacted to a post or comment, with a detailed list showing user profiles and their reactions. * **Manage Discussion Categories**: Administrators can now manage discussion categories directly from the discussions page with a quick-access link. **Admin Tools** * **Hotlinks Management**: New admin interface to create, edit, and delete navigation hotlinks that appear in the sidebar. Supports linking to events, discussions, and other platform areas. * **Local Center Filter for Membership**: HR administrators with parent local center access can now filter the membership applications list by specific local centers. **Issues & Tasks** * **Assignee Selection in Issue Modal**: When creating issues from a group, you can now assign them directly to team members using an autocomplete selector. **Improvements** **Payments** * **Two-Step Payment Flow**: External profiles now see a cleaner two-step payment process with fade transitions between steps. * **Payment Page Enhancements**: Product descriptions are now displayed on payment pages, and the "create account" toggle visibility is now smarter based on context. * **Better Payment Redirect**: When canceling a payment initiated from a profile, users are now correctly redirected back to their profile. **Events** * **Improved Event Cards**: Event list cards now display cover images with better scaling (shrink-to-fit) for a more polished appearance. * **Event Type Display**: Event type names are now visible on event cards and detail pages. **Discussions** * **Improved Comment UI**: Comment replies now load more efficiently, and the expand button only appears when there are actual replies to show. * **Redirect on Missing Post**: Users are now redirected to the dashboard instead of seeing an error when trying to view a deleted or non-existent post. **User Interface** * **Updated Sidebar Icons**: The groups sidebar now features improved icons and better visual organization with clear section separators. * **Dashboard Event Display**: Events on the dashboard now display with improved background image scaling. * **Newsletter Statistics Display**: Newsletter open, click, complaint, and bounce rates are now displayed as percentages for easier understanding. **User Management** * **Profile External Updates**: External profiles now include town and country fields, with improved display of creation and last update dates. * **User Profile Improvements**: User profile editing now shows organization/company and role fields more prominently. **New Features** **Events** * **Event Tickets with QR Codes**: Generate tickets with QR codes for attendance verification at events * **Send Newsletters to Event Attendees**: Create and send newsletters directly to event participants **Members** * **Filter Members by Country**: New filter option to find members by their country **Statistics** * **Geographic Statistics**: View member distribution on an interactive map **Newsletter** * **Newsletter Targeting for Events**: Target newsletters specifically to event attendees **Products** * **Display Products on Profiles**: Show purchased products on user profiles * **Archive Products**: Archive products that are no longer active **Improvements** **Newsletter** * **Better Template Selection UI**: Improved interface for selecting newsletter templates * **Newsletter List Pagination**: Added pagination and sorting to newsletter list * **Enhanced Email Builder**: Improved email builder experience **Events** * **Improved Event Configuration**: Better event configuration page layout * **Timezone Fixes**: Fixed timezone handling for events **Products** * **Better Charts**: Improved product charts with decimal precision * **Faster Loading**: Optimized product list loading speed **Identity Verification** * **Expired Document Flow**: Better handling of expired identity documents **User Interface** * **Improved Logo Upload**: Better logo upload experience * **Reorganized Group Navigation**: Cleaner group navigation structure **New Features** **Payments** * **Financial Charts**: You can now view payment analytics charts on product pages with customizable date ranges, showing payment trends and totals over time **Identity Verification** * **New Romanian ID Card Support**: The platform now recognizes and processes the new format Romanian identity cards during membership applications and identity verification * **Resend Confirmation Email**: If your account email is not confirmed, you can now request a new confirmation email directly from the login page **Groups** * **Search Groups**: Added a search bar in the sidebar to quickly find groups by name * **Alphabetical Sorting**: Groups in the sidebar are now sorted alphabetically for easier navigation **Improvements** **Events** * **Upcoming Events Sorting**: Upcoming events are now displayed in chronological order (earliest first) for better planning **Profiles** * **Contacts List Sorting**: Fixed and improved sorting of the contacts list for easier navigation **Identity Verification** * **Admin Review Interface**: Improved the admin identity verification page with sticky image display and better layout for reviewing identity documents * **User Verification Flow**: Enhanced the identity verification process for users with clearer instructions and better feedback **New Features** **Payments & Donations** * **A/B Testing for Payment Pages**: Admins can now create multiple price variations for donation campaigns to test which pricing options perform better. View statistics for each variation directly on the product page. * **Progress Bar on Donation Pages**: Public payment pages now display a visual progress bar showing campaign goals and current donation totals. * **Filter Payments by Date Range**: Filter the payments list by date intervals to analyze donations within specific time periods. * **Filter Payments by Identity Status**: New filters to view payments based on identity verification reminder status. * **Stripe Payment Links**: Direct links to Stripe dashboard now appear in payment and subscriber lists for quick access to payment details. **Events** * **Upcoming Event Reminders**: Attendees now receive email reminders before events they're registered for, with event details and timezone information. * **Public Events by Organization**: Events marked as public can now be discovered by external visitors on your organization's public page. * **Improved Event Attendance Details**: Event attendance lists now show additional participant information including location details. **Identity Verification** * **Back of ID Document Upload**: Users can now upload the back side of their identity documents for more complete verification. * **Multiple Identity Reminders**: System now sends up to 3 reminder emails to users who haven't completed identity verification after making a payment. * **Identity Verification from Payments**: Admins can now navigate directly to identity verification from the payments list. * **Hide Address Details Option**: Organizations can configure whether to show or hide detailed address information during identity verification. **Units & Teams** * **Unit Member Management**: New interface for viewing and managing members organized by units and unit types. Admins can add or remove members directly from this view. * **Unit Type Filtering**: Filter member lists by specific unit types to quickly find team members. * **Improved Unit Navigation**: Added back buttons and cleaner navigation when managing units and teams. **Membership** * **Resignation Notifications to Local HR**: When a member submits a resignation request, the local HR representative now receives an email notification. * **HR Access to Privacy Settings**: Local HR roles can now access member privacy and resignation settings. **Products & Campaigns** * **Product Hero Images**: Add featured images to payment/donation products that display prominently on public payment pages. * **Local Center Assignment**: Products can now be assigned to specific local centers for better organization and reporting. * **Custom URL Slugs**: Create custom, shareable URLs for payment pages. * **Default Price Option**: Mark a specific price as the default selection on payment pages. **Analytics** * **Google Analytics per Organization**: Each organization can now configure their own Google Analytics tracking ID for detailed visitor analytics. **Improvements** **Payments** * **Improved Payment Dashboard**: Product list now shows comprehensive statistics including total donations, active subscriptions, and subscriber counts. * **Better Payment Page Mobile Experience**: Payment pages now display properly on mobile devices with improved spacing and button sizes. * **Thank You Page Updates**: Improved post-payment confirmation pages with clearer messaging. **Events** * **Event Form Simplification**: Ticketing and public access options are now available only to HR roles for cleaner event creation. * **Event Media Deletion**: Fixed and improved the ability to delete media files attached to events. **User Interface** * **Local Center Sorting**: Added ability to reset sorting on local center lists. * **Member List Improvements**: Better formatting and horizontal scrolling on mobile for member lists. * **Consistent Button Styling**: Rounded buttons applied consistently across the platform. **Notifications** * **Timezone in Email Notifications**: Event notifications and reminders now include timezone information for clarity. * **Admin Notification for New Users**: Organization admins now receive email notifications when new users register. **Forms** * **Adhesion Form Improvements**: Added social media field placeholders and improved validation in membership application forms. **New Features** **Events** * **Public Event Registration**: External guests can now register for public events without an account and receive confirmation emails * **AI-Powered SDG Suggestions**: Get automatic Sustainable Development Goal suggestions for your events * **Event Type Colors**: Customize event types with specific colors for better visual organization **Newsletter** * **Organization-Specific Templates**: Create and save newsletter templates specific to your organization **Voting** * **Timezone Support**: Votes now properly handle timezones for accurate scheduling **Profiles** * **Website Field**: Users can now add their personal or professional website to their profile **Authentication** * **Email Change Verification**: Email changes now require verification for security **Membership** * **Lifetime Subscriptions**: Support for lifetime membership subscriptions * **Force Password Reset**: Admins can force users to reset their password on next login **Contacts** * **Enhanced External Profiles**: Improved external contact profiles with more fields **Improvements** **Events** * **Timezone Display**: Event times now clearly show timezone information **Discussions** * **Category Filters**: Better filtering by discussion categories * **Assignee Selection**: Improved assignee selection in discussions **Payments** * **Hidden Price Options**: Admins can hide certain price options from public view **Membership** * **Resignation Form Privacy**: Improved privacy handling in resignation forms **Statistics** * **Chart Improvements**: Better statistics charts with improved visualization **User Interface** * **Mobile Layout**: Various mobile layout improvements across the platform **New Features** **Events** * **Draft Mode for Events**: Event organizers can now save events as drafts before publishing. Draft events are only visible to the creator until they choose to publish them publicly. * **Event Photo Gallery**: Added a gallery component to event pages for viewing uploaded event photos. **Voting** * **Vote Publication Notifications**: Eligible voters now receive notifications when a new vote is published. Updated email templates for vote announcements. * **Unit Selection for Votes**: Improved the voting interface to allow selecting which organizational unit a vote applies to. **Membership** * **Resignation Request System**: Members can now submit resignation requests through their profile. Administrators can review, approve, or reject these requests. * **Account Reactivation**: Inactive users can now reactivate their accounts during login. * **Adhesion Signature Workflow**: Updated the membership application process with clearer step-by-step instructions and signature functionality. **User Management** * **Filter Users by Town**: Added the ability to filter user lists by town/city location. * **Filter Users by Permission**: User lists can now be filtered by specific permissions. **Local Centers** * **Map View for Local Centers**: Local centers can now be displayed on an interactive map. * **Donation Links**: Local centers can now display donation links on their profile pages. **Improvements** **Analytics** * **Updated Charts**: Analytics dashboard charts have been modernized for better performance and visual clarity. **Discussions** * **Text Search**: Added text search functionality in the discussions list and support ticket views. * **Improved Comment Replies**: Fixed display of nested comment replies in discussions. **Support/Issues** * **Kanban Board**: Improved the Kanban board for issue tracking with better drag-and-drop functionality. * **Issue Status Colors**: Fixed the color dropdown for issue types and statuses. **User Interface** * **Theme Selector**: Theme switching now works correctly from the menu. * **Language Selector**: Language switching is now functional and properly updates the interface. * **Dark Mode Support**: Improved display of various elements in dark theme mode. * **Mobile Menu**: Better navigation on mobile devices. **External Contacts** * **Sorting Options**: Added sorting options for external contact profiles, including by newsletter subscription and creation date. **New Features** **Local Center Transfers** * **Request Local Center Transfer**: Members can now request to transfer to a different local center directly from their profile. HR administrators can review, approve, or decline these requests. * **Transfer Request Management**: HR administrators have a new dedicated page to view and manage all pending local center transfer requests. **Newsletter System** * **Embeddable Newsletter Registration**: Organizations can now embed a newsletter registration form on external websites. * **Send to Contacts**: Newsletters can now be sent to external contacts, not just registered members. * **Email Preview**: You can now send a preview email to yourself before sending a newsletter to all recipients. * **Personalization Tags**: Use dynamic placeholders in newsletter subjects and content for personalized emails. * **Unsubscribe Link**: Add unsubscribe tags in your newsletter templates. * **Visual Email Builder**: New drag-and-drop email builder with image upload support for creating beautiful newsletters. **Contacts Import** * **CSV Import for Contacts**: Import external contacts via CSV file with rollback capability if needed. **Cookie Consent** * **GDPR Cookie Consent**: New cookie consent banner with options to accept, reject, or postpone the decision. **Member Onboarding** * **Guided Onboarding Flow**: New step-by-step onboarding wizard for new members to complete their profile, set privacy preferences, configure notifications, and select timezone. **Profile Activity Logs** * **Profile Change History**: Administrators can now view a log of changes made to user profiles. **Improvements** **Events** * **Event List Tabs**: Events are now organized with tabs for easier navigation between upcoming and past events. * **Timezone Display**: Events now show a globe icon to view/select timezone for event times. * **Past Events Indicator**: Events now display whether they are in the past. * **Trainer Events on Profile**: Users can see events where they participated as a trainer on their profile. **Discussions & Issues** * **Multi-Status Filtering**: Filter issues by multiple statuses simultaneously using checkboxes. * **User Mentions**: You can now mention users in discussion posts, and they will be notified. * **Emoji Picker**: Added emoji picker for discussions. * **Search Autocomplete**: Long items in search autocomplete are now properly trimmed. **Groups** * **Public Join Link**: Groups can now have a public join link that allows members to join directly. * **New Group Button**: Improved visibility of the "Create Group" button in the sidebar. **User Experience** * **Mandatory Membership Redirect**: If membership fees are mandatory, users without valid membership are redirected to purchase a membership tier. * **Automatic Timezone Detection**: User timezone is automatically detected and set on first login. * **Discussion Edit Modal**: Improved modal interface when editing discussions. * **Link Preview**: Better handling of link previews in posts. **Newsletter List** * **Enhanced Statistics Display**: Newsletter list now shows cleaner statistics with rounded tags for engagement metrics. **Permissions** * **Permissions Documentation Page**: New page explaining available permissions and roles for administrators. # API Access Source: https://orgo.space/docs/platform/api Create API tokens, scope them to part of your data, and connect external systems to Orgo An API token lets a script, an automation platform or an internal tool talk to Orgo without a browser session. Every REST endpoint the app itself uses is available, and each token can be narrowed to only the part of your data an integration actually needs. **Built for** operations teams wiring Orgo into the rest of their stack. **Replaces** CSV exports and manual re-keying between systems. API Tokens page with the create form, the Full access and Restricted scope selector, and a table of existing tokens showing last used, expiry and status *** ## Where it lives **Settings → Developers → API Tokens** Creating, editing, revoking and deleting a token all require **ADMIN\_TENANT**. The menu entry appears only when API access is switched on for your organization. The full endpoint catalogue, request and response shapes, and error formats are in the [API Reference](/docs/api-reference/concepts/authentication). *** ## Creating a token Use the integration's name, not a person's. The name is the only thing you will recognise it by later. Any date from tomorrow onwards. Leave it empty for a token that never expires. **Full access** (optionally **Read-only**), or **Restricted** with a per-area level. See below. It is shown once, in a yellow banner. Orgo stores only a hash of it, so a lost token cannot be recovered: create a new one and revoke the old. Send it on every request as a header: ``` Api-Token: YOUR_TOKEN ``` *** ## Limiting what a token can reach A token does not have to carry everything you can do. The **Access** control has two modes. **Full access** behaves like your own account. The **Read-only** switch then restricts it to `GET`, `HEAD` and `OPTIONS`; anything else is rejected with `403`. **Restricted** gives you a matrix: four areas, each set to **None**, **Read** or **Write**. | Area | Covers | | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Financial** | Products, prices, payments, fees, invoices and invoice templates, subscriptions, billing profile | | **Events** | Events and event types, tickets, addons, vouchers, attendance, speakers, networking spaces and sessions | | **Members** | Members and their roles, units, local centers, groups, families, companies, contacts, badges, courses, contracts, adhesions, identities, votes, waitlist, referrals | | **Communications** | Newsletters and templates, recipient lists, discussions, topics and posts | A few resources belong to more than one area: a contact is reachable with either **Financial** or **Members**, a newsletter with either **Communications** or **Events**. This is the answer to "can we let a developer or an external tool work with our member data without exposing payments?" Yes. Grant **Members** and leave **Financial** on None. Three rules make a restricted token safe to hand out: * **Default deny.** Anything not covered by a granted area is refused, not merely filtered. Reference data (countries, towns, tags, custom-field definitions, the token owner's own notifications) stays readable, but not writable. * **Never administrative.** Tenant settings, OAuth apps, webhooks, email templates and the email log, imports, workflows, projects and tasks are out of reach for a restricted token whatever you grant it. * **No escalation.** A restricted token cannot assign a member a role carrying a permission the token does not itself hold at Write, and cannot rewrite role-group structures at all. A token can never exceed the permissions of the admin who created it. The scope narrows that person's access; it does not widen it. *** ## Managing tokens The table shows each token's name, creation date, last use, expiry, access and status. | Action | What it does | | ---------- | ------------------------------------------------------------------------------------------------------------------------------------ | | **Edit** | Change the name, expiry or scope of an active token. The token value never changes, and the new scope applies from the next request. | | **Revoke** | Stops the token working immediately. Integrations using it start failing. | | **Delete** | Available only after a token is revoked or expired. Removes it from the list permanently. | You see and manage the tokens you created, not other admins'. Every create, scope change and revoke is recorded internally with the actor and the before and after scope, so support can reconstruct who changed what. A token also stops working if the account that owns it is no longer active, so revoke tokens as part of offboarding rather than relying on the account alone. *** ## Volume and limits Requests are counted per token per day. **Settings → Usage & Billing** shows API requests over the last 30 days against your plan's allowance. There is no per-minute quota tied to your plan. A handful of expensive or abuse-sensitive endpoints have their own limits and answer `429` with a `Retry-After` header: see [Rate limits](/docs/api-reference/concepts/rate-limits) for the list and a retry pattern. *** ## Keeping tokens safe A token carries the permissions of the admin who created it. Anything in a browser, a mobile app or a public repository is compromised the moment it ships. For user-facing sign-in, use [OAuth](/docs/platform/oauth) instead. Separate tokens mean you can revoke one integration without breaking the others, and the Last Used column tells you which ones are actually in use. Read-only where the integration only reads, and a restricted scope where it touches one area. The blast radius of a leaked token then stops at data it could already see. Contractor access, a one-off migration, a proof of concept: give it a date and let it lapse on its own. *** ## Related * [API Reference](/docs/api-reference/concepts/authentication) - every endpoint, parameter and response * [Webhooks](/docs/platform/webhooks) - get pushed events instead of polling * [OAuth Server](/docs/platform/oauth) - let members sign in to your own app with their Orgo account * [Orgo MCP](/docs/platform/mcp) - connect AI assistants to your Orgo data * [Integrations](/docs/platform/integrations) - HubSpot, n8n, analytics and SSO # Badges Source: https://orgo.space/docs/platform/badges Named awards on a member profile, given by hand or awarded automatically from hours, events, and courses A badge is a named, illustrated award attached to a member's profile. You define the catalogue once, then badges reach members either because someone gives them out or because Orgo awards them from something the member did: hours logged, an event attended, a course finished. **Built for** organizations that already recognise members informally (training passed, hours volunteered, levels reached) and want that recognition on the member record instead of in a spreadsheet. **Replaces** the certificates spreadsheet and the "who is first aid certified?" email thread. It is not a qualifications register: a badge has no expiry date and no renewal. Badges need the Gamification module. Turn it on at **Settings** → **Modules** → **Gamification & Courses** → **Gamification** with **Enable Gamification Module**. That settings area needs `ADMIN_TENANT`. *** ## Categories and badges Badges can be grouped into categories, which is optional and controlled by the **Enable badge categories** switch. A category has only an image and a title. Its job is to keep the award picker usable once you have more badges than fit on a screen. **Settings** → **Modules** → **Gamification & Courses** → **Badge Categories** Badge Categories list showing the category images and names with an Add badge category button Badges themselves live one level down, at **Settings** → **Modules** → **Gamification & Courses** → **Badges**. | Field | What it does | | ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | | Image | Circular badge artwork, cropped on upload | | **Title** | The badge name. Required, saving without one is blocked | | **Badge type** | The category. Shown only when **Enable badge categories** is on | | **Hours number** | Volunteering-hours threshold, see [by volunteering hours](#by-volunteering-hours). Shown only when **Enable hours tracking** is on | | **Points required** | Tier threshold, see [Gamification](/docs/platform/gamification). Shown only when **Enable tiers/levels by points** is on | | **Default note explanation** | Pre-fills the note when someone awards this badge, so the same wording is used every time | Badges list inside the Gamification and Courses module, each row showing the badge artwork, its name, its Type and the hours threshold that awards it, with an Add badge button Creating, editing, and deleting badges and categories all need `ADMIN_TENANT`. Deleting a badge also deletes every award of it from every member. Deleting a category deletes the badges filed under it, and their awards with them. Courses and events that pointed at a deleted badge simply lose the link. *** ## Awarding a badge ### By hand Open the member, go to the **Badges** tab, and click **Add badge**. The picker lists categories on the left and their badges on the right, both searchable. Pick one, then fill in: | Field | Notes | | ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Date completed** | Pre-filled with today, and editable by hand. Back-dating is allowed. Leaving it empty is fine: a new award is stamped with the moment you save it, and clearing it on an existing award keeps the date already stored | | **Notes** | Pre-filled from the badge's default note when it has one | | **Status** | **Completed** or **Pending**, defaulting to Completed | A save that fails leaves the modal open and reports the error, so an award that does not appear in the table was not quietly dropped. Pending is for work in progress: the member holds the record, and it is counted and filtered separately from completed awards everywhere it appears. The **Add badge** button appears for `HR_TENANT` and for `HR_LOCAL` on the member's local center. Awarding is checked again when you save: it needs `HR_ASSISTANT_LOCAL` over that member's local center, which `HR_LOCAL`, `FINANCIAL_LOCAL` and `ADMIN_LOCAL` all satisfy, or one of the tenant-wide equivalents. Editing or removing an existing award needs the same permission, or that you are the person who gave it. Every award stores who gave it, shown as **Offered by** on the profile and **Given by** in the centralizer. Nobody is notified when a badge is awarded or removed, so announce the ones that matter yourself. ### By volunteering hours With **Enable hours tracking** on, the Badges tab gains **Add volunteering hours**, which needs `HR_ASSISTANT_LOCAL` on the member. Each entry has a period (start and end date), a number of hours, a title, and notes. Saving or editing an entry re-totals every hour logged for that member and awards, as Completed, each badge whose **Hours number** is above zero and at or below that total. Deleting an hours entry does not take a badge back, so revoke it by hand if the total no longer holds. ### From an event With both **Enable tiers/levels by points** and **Enable badge per event** on, the event form gains a **Gamification** section containing **Award badge on event attendance**, visible to `EVENT_TENANT`. Participants receive the badge when their attendance is set to Attended. If the attendance is deleted or moved away from attending, the badge is removed again. ### From a course With the Gamification module on, a saved course gains **Award badge on completion**. Students receive it when their enrollment is marked complete, and the course page then shows the badge as earned. Deleting a completed enrollment removes the badge. A member can hold a given badge only once. Every automatic path checks first and skips if the badge is already on the profile, so re-marking attendance or re-running an import will not create duplicates. *** ## Where badges show up On a member profile, the overview card lists badge artwork and names, and the **Badges** tab holds the full table: badge, category, status, who offered it, and the date. Volunteering hours get their own table below it when hours tracking is on. **Badges** in the sidebar (`/badge-users`) is the tenant-wide view, shown to `HR_ASSISTANT_LOCAL` and above once the module is on. Filter by category, badge, Completed or Pending, and local center, then read across three tabs. | Tab | What it shows | | ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Local centers** | Completed and pending counts per local center. The tab is labelled with whatever your organisation calls its local centers, so it reads **Chapters** where that is the word in use. Only when the Local Centers module is on | | **Badges stats** | Completed and pending counts per badge, sortable, 30 rows a page | | **Badges** | Individual awards: badge, member, who gave it, and when. 100 rows a page | Someone whose HR permission is local-only sees just the awards for members of their own local center. Badges centralizer with local centers, badge stats, and individual award tabs plus Completed and Pending filters *** ## Common questions There is no request flow and no self-service button. Badges come from an admin with HR permission, or from one of the automatic paths above. Yes. Open the member's Badges tab and delete the award. Nobody is notified, so explain it directly if the reason matters. Yes. The import tool has three badge entities: Badge Types, Badges, and Badge Assignments, each with a downloadable example file. Import categories and badges first, then the assignments. The Gamification module is off. Turn it on under Settings, Modules, Gamification & Courses. They hold a local-level HR permission, so the list and the local center filter are limited to their own local center. Tenant-level HR sees everything. *** ## Related * [Gamification](/docs/platform/gamification) - Points, tiers, and the leaderboard * [Courses](/docs/platform/courses) - Award a badge when a course is completed * [Event attendance](/docs/platform/events/attendance) - Award a badge to everyone marked as attended * [Members](/docs/platform/users) - The profile where badges appear * [Permissions](/docs/platform/permissions) - What HR\_LOCAL and HR\_ASSISTANT\_LOCAL cover # Contacts Source: https://orgo.space/docs/platform/contacts Track people who are not members: donors, newsletter subscribers, ticket buyers, and partners **Built for** organisations whose audience is wider than their membership. **Replaces** a separate CRM or a spreadsheet of donors and subscribers. A contact is a person record without a login. Orgo creates one automatically whenever someone interacts with you without an account (buys a ticket, donates, subscribes to the newsletter), and you can add them by hand. Everything a contact does (payments, tickets, signed documents, emails received) stays attached to that record. Contacts directory with newsletter, status and tag columns and a search bar *** ## Turning it on **Settings → Modules → Contacts → Enable Contacts Module** (needs `ADMIN_TENANT`). Two extra switches live on the same page: | Setting | What it does | | ------------------------------- | --------------------------------------------------------------------------------------------------------------- | | **Enable Contact Statuses** | Adds a status field to contacts and the **Contact Statuses** sub-page where you define the list | | **Enable Per-Chapter Contacts** | Lets a contact belong to a local center, adds the Chapter filter and column. Requires the Local Centers feature | *** ## Who can see contacts `HR_TENANT` and `FINANCIAL_TENANT` always see the full contact list. Local-level managers (`HR_LOCAL`, `FINANCIAL_LOCAL`) only reach contacts when **Enable Per-Chapter Contacts** is on, and then only within the local centers they belong to. When they create a contact without picking a chapter, it is filed under their own. Exporting the list to CSV requires `HR_TENANT`. Contacts have no account and cannot log in to the member area. The one exception is the event app: a ticket holder who is a contact signs in with a one-time code scoped to that event only. *** ## Where contacts come from Every contact records how it arrived, shown as **Source** on the record and as a column in the list: | Source | Created when | | -------------- | ---------------------------------------------------------------------- | | **Manual** | Someone clicks **Add Contact** | | **Import** | A CSV import of contacts runs | | **Form** | A standalone form or a public website form is submitted | | **Newsletter** | Someone subscribes from a signup widget or public page | | **Event** | A non-member registers for, buys, or is invited to an event | | **Donation** | A donor fills in their details on a donation page | | **Stripe** | A payer record arrives from Stripe | | **Contract** | An e-document is shared with someone outside the membership | | **System** | Orgo creates the record while checking whether an email already exists | To load contacts in bulk, use **Settings → Import** and pick the contact import type. There is no import button on the Contacts screen itself. *** ## What a contact record holds Adding or editing a contact gives you these fields: | Section | Fields | | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------ | | **Basics** | Photo, name (required), email, phone, town (country is derived from it), Chapter, gender, birthday, bio | | **Professional Info** | Current Organisation/Company, Current role | | **Billing Details** | Company identifier (with a lookup button that fills the rest), company name, company address, company commerce registry number | | **Additional information** | The custom fields you selected for the profile form | | **Social profiles** | LinkedIn URL, Twitter URL, Instagram URL, Bluesky handle | Saving a contact with an email that already belongs to another contact, or to a member, is rejected. Orgo tells you which of the two it clashed with. Contact record with Tags, Notes and Activity as stacked cards, the Notes card holding an Add a note about this contact box with an Action select, and the Activity card listing three Note added entries and a Donated 50 usd entry The record page adds panels that are filled in as the contact interacts with you: **Status**, **Newsletter**, **Tags**, **Notes**, **Activity**, **Events**, **Payments & Subscriptions**, **Company Membership**, **e-Documents** (when that module is on), **Email logs**, and an **Identity** link when they uploaded an ID document. ### Notes and Activity The **Notes** card writes a note; the **Activity** card below it is where notes are read, along with the contact's donations, form submissions and tag changes on one feed. Both cards need **Enable Profile Notes & Activity** switched on and `HR_LOCAL` or `FINANCIAL_LOCAL` over that contact, or `ADMIN_TENANT`. Each note records its author and time, is capped at 512 characters, and carries an optional **Called** or **Emailed** action. Click a note in the Activity feed to read it in full, and to edit or delete it, which the person who wrote it or an `ADMIN_TENANT` may do. Older single-blob notes from before this change appear as notes without an author, so only an `ADMIN_TENANT` can edit those. Full detail: [Profile Activity & Notes](/docs/platform/users/profile-activity). ### Statuses and tags Statuses are a single-choice list you define under **Settings → Modules → Contacts → Contact Statuses**: name, colour, and drag-to-reorder. Tags are multi-choice and come from the shared tag catalogue used for members too, so you can filter the same tag across both. *** ## Working with the list **Search** matches name and email. The filter row adds **Chapter**, **Status**, **Tags** and **Newsletter**. Columns are Name, Country, Town, Chapter, Email, Phone, Newsletter, Source, Status, Tags, Date created and Stripe; most are sortable. * **Select** switches the list into selection mode for bulk delete. * **Download CSV** exports the filtered list 500 rows at a time. If the result is larger, Orgo asks which page you want. Every export is written to the audit log. * Per-row actions: **Create user account**, **Open in Stripe**, **Delete contact**. A contact with a successful payment against it cannot be deleted, individually or in bulk. Bulk delete skips those rows and reports how many were skipped. *** ## Newsletter subscription The newsletter field on a contact has three states, and the list filter mirrors them: | State | Meaning | | ------------------ | ------------------------------------------------------------------------------------------------------ | | **Subscribed** | Opted in, receives newsletters | | **Not subscribed** | Never made a choice | | **Unsubscribed** | Opted out, either by clicking the link in an email or through the **Unsubscribe** button on the record | The **Unsubscribe** button shows only while the contact is subscribed, and using it requires `HR_TENANT`. Unsubscribing takes effect immediately and the button disappears afterwards, so there is no one-click undo. Confirm the request before you use it. *** ## Turning a contact into a member **Create user account** on the contact record creates a member account from that email and sends the welcome email with a login link. The new member is asked to set a password on first login, and Orgo takes you straight to their member profile. The contact record is kept as-is. It is not deleted, and its payments, tickets and documents stay attached to the contact rather than moving to the new member account. If you need the two records combined into one history, ask Orgo support to merge them. *** ## Common questions Donors without an account are contacts, not members. Search the Contacts list and filter by source **Donation**. Yes. Newsletter audiences are built from both, and only contacts marked **Subscribed** are included. Contacts are tenant-level unless **Enable Per-Chapter Contacts** is on and the Local Centers feature is enabled. Without both, only `HR_TENANT` and `FINANCIAL_TENANT` reach the list. That is deliberate: deleting the contact would orphan the payment records. Keep the contact, or ask support if the payment itself needs to be removed first. Creating a contact with an email that already exists is blocked, so duplicates usually differ by email. Fix the email on the record you want to keep, then delete the other. *** ## Related * [Donations](/docs/platform/fees/donations) - donation pages and donor records * [Newsletter](/docs/platform/newsletter) - campaigns to contacts and members * [Import](/docs/platform/customization/import) - bulk-loading contacts from a file * [Custom Fields](/docs/platform/users/custom-fields) - extra fields on contact records * [Profile Activity & Notes](/docs/platform/users/profile-activity) - the Notes and Activity cards in full * [Members](/docs/platform/users) - the member directory contacts convert into # E-Document Templates and Signing Source: https://orgo.space/docs/platform/contracts Build document templates, assign them to members and contacts, and collect signatures in the browser E-Documents lets you write a document once as a template, fill it with member data automatically, send it to a member or a contact, and have them sign it on screen. Orgo renders the signed result as a PDF and keeps it against the member's profile. **Built for** membership organizations that need the same agreement from every member: membership contracts, volunteer agreements, codes of conduct, photo and media releases, parental consents. **Replaces** printing, scanning, and chasing paper forms, and replaces a general e-signature tool for the routine documents your own members sign. *** ## Turning it on **Settings → Modules → Files & eDocuments → eDocuments**, then **Enable eDocuments Module**. Module settings require `ADMIN_TENANT`. | Setting | What it does | | ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | | **Enable eDocuments Module** | Shows the eDocuments screens and the E-Documents tab on member profiles | | **Enable Groups** | Ties each template to one group, which changes who sees it and who may assign it | | **Membership Card Contract** | Marks one template as the membership card document, adding a **Print status** column and a **Mark as printed** action on that template's list | Day-to-day work lives at **eDocuments** in the admin menu (`HR_TENANT`), with **Documents** and **Templates** tabs. `ADMIN_TENANT` satisfies every `HR_TENANT` check. *** ## Templates Templates tab showing template cards with group tag, signing method, duration and document count, plus a Create new template card Each card shows the name, group, signing method (on screen or file upload), duration in months and document count; selecting one opens the editor. The same cards under **Settings → Files & eDocuments → eDocuments Templates** also get **Clone**, which copies the template with the name prefixed `Copy `. Creating a template requires `ADMIN_TENANT`; editing, cloning and deleting require `HR_TENANT`. ### Settings tab Template Settings tab with General information, Signature and Duration cards including the signing method radio buttons | Setting | What it does | | ----------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Template name** | Internal name, shown in lists and filters | | **Associated group** | Ties the template to one group (needs **Enable Groups**) | | **Show in member profile** | Members see the template on their own E-Documents tab before it is assigned to them. With **Enable Groups** on, only members of the associated group see it | | **Mandatory document** | The member is pushed through onboarding until it is signed (see below) | | **Enable signature** | Off makes it a read-and-download document with no signing step | | **Signing method** | **Sign by finger on screen** or **Sign by file upload** | | **Requires administrator signature** | Not finished until an admin countersigns | | **Use default signature** | Stores one reusable admin signature on the template | | **Pre-sign with default signature** | Stamps the stored admin signature on every new document at assignment, so it completes the moment the member signs | | **Enable signature cancellation** | A signed document can be revoked afterwards | | **Infinite contract duration** | The document never expires | | **Contract duration in number of months** | 1 to 60 months from the signing date | **Delete template** refuses once any document from it has been signed. **Cancel all signed** (`ADMIN_TENANT`) instead cancels every outstanding document from that template and asks everyone to sign again. ### Document content tab Template content editor with rich text on the left and the Placeholders sidebar grouped into Member data, Document, Organization and Company A rich text editor with a **Placeholders** sidebar. Click any tag to insert it at the cursor. | Group | Placeholders | | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | Member data | `{firstName}` `{lastName}` `{email}` `{phone}` `{address}` `{postalCode}` `{currentTown}` `{dateBirth}` `{dateJoined}` `{profession}` `{userId}` `{cardProfileLink}` `{cardProfileQrCode}` | | Document | `{dateSignature}` `{expirationDate}` `{dateValidityEnd}` `{signature}` `{signatureAdmin}` `{autoContractNumber}` | | Organization | `{organizationName}` `{organizationShortName}` `{organizationLogo}` | | Company | `{companyName}` `{userCompanyName}` `{userCompanyAddress}` `{userCompanyIdentifier}` `{userCompanyRegNo}` `{professionOrganisationRole}` `{membershipFeeAmount}` | Two more forms work but are not listed as tags: `{custom_field_ID}` for a [custom field](/docs/platform/users/custom-fields) (text input and text area insert their value directly; yes/no, dropdown, checkbox and file render their label or a download link), and `{drive|filename.ext}` to link a file from [Drive](/docs/platform/files). `{signature}` and `{signatureAdmin}` mark where the signature images land; a missing signature prints a blank line instead. The two end dates are not the same tag. `{dateValidityEnd}` prints the validity end held on that person's own document, the date set when it was sent, and prints nothing when the document has none. `{expirationDate}` is worked out while the document renders, as today plus the template's duration, and prints "undetermined" on a template with no expiry. `{cardProfileLink}` and `{cardProfileQrCode}` are meant for templates with **Enable signature** off, such as membership cards, which are rendered fresh from live member data every time. They are not filled in on a signed document. *** ## Sending a document In the **Documents** tab, **Start document** opens a panel with three fields: the template (shown only when more than one exists), a **Search member** autocomplete across members and [contacts](/docs/platform/contacts), and validity. **Contract validity date start** defaults to today, and the end date comes from the template duration unless you switch on **Custom contract validity date end**. Assigning to someone else requires `HR_TENANT`, or `HR_LOCAL` when the template's associated group belongs to a local center. Members can always start their own document from their profile. ### Public links Two buttons produce a link that works without an Orgo login: **Generate public link** on a template creates a blank invitation (the visitor gives a name and email, which creates a contact, then signs), and **Share** on a pending row links to that one document. Both live at `/public/document/` and **expire 72 hours** after creation. Creating one requires `HR_TENANT` unless it is for yourself. Every link for a document is deleted as soon as that document is signed. *** ## Statuses | Status | Shown as | Meaning | | ------------- | ---------------------------------------- | ------------------------------------------------------------------- | | `unsigned` | **Pending** | Assigned, waiting for the signer | | `signed-user` | **Pending** (filter: **Signed by user**) | The member has signed, an administrator signature is still required | | `complete` | **Signed** | Fully signed | | `expired` | **Expired** | The validity end date has passed | A nightly job moves signed documents to **Expired** the day after their validity ends. *** ## Tracking Documents tab with name search, template and group filters, status pills, and a table of documents showing member, signature date, validity and status Filter by member name, template, group and status. The table shows document ID, member, template, group, signature date, validity and status. Every row carries **View** and **Open document**; **Share** appears on pending rows, **Download PDF** once a signed PDF exists, and **Delete** for `HR_TENANT`. Document side panel showing status, member, created and signing dates, validity, and a history timeline with Revoke and Open document actions **View** opens a side panel with the member, the dates, the validity and a **History** timeline. **Revoke** appears there for signed documents when the template has **Enable signature cancellation** on, and **Download PDF** once the signed PDF has been generated. Three more admin actions on a single document, all `HR_TENANT`: **Modify document text** (edits this copy before it is completed), **Mark as signed** (records an offline signature with your own start and end dates), and countersigning, by drawing a signature or with **Sign with default signature**. *** ## What the member sees Members find their documents under **E-Documents** on their own profile: a card per template with **Sign**, **Upload file** or **Download PDF**, a running count of required documents signed, and previous versions with their validity ranges. On a signing template, the screen shows the document beside a short form for whatever placeholders it uses (first name, phone, town, company details, custom fields), then the member draws a signature. What they enter is written back to their profile where that field was empty. *** ## Mandatory documents **Mandatory document** shows the member an onboarding step listing everything they still have to sign, and holds them there until they do. A document is outstanding when it has never been signed, is waiting for the administrator signature, or its validity has ended. Tenant HR admins are exempt. Separately, **Settings → Modules → Payments & Fees → Membership Fees → Require Contract for Membership** blocks paying the membership fee until the template named in **Membership Contract Document ID** has been validly signed. *** ## Related * [E-Document Records and Legal Weight](/docs/platform/e-documents) - what a signature captures, storage, validity and renewal * [Files](/docs/platform/files) - general document storage and sharing * [Custom Fields](/docs/platform/users/custom-fields) - the fields you can pull into a template * [Adhesion](/docs/platform/users/adhesion) - the separate membership application document * [Permissions](/docs/platform/permissions) - what `HR_TENANT` and `ADMIN_TENANT` unlock # Courses Source: https://orgo.space/docs/platform/courses Build self-paced courses with lessons and quizzes, enrol members, and track progress Courses lets you publish structured learning inside Orgo. A course holds sections; each section holds lessons (rich text plus optional video, audio, embed and file attachments) and quizzes. Members work through it at their own pace, and their progress is stored against their membership record. **Built for** organisations that train their own members: onboarding for new joiners, role-specific training, and refresher material tied to a user type or a local group. **Replaces** a shared folder of PDFs and videos for internal member training. It is not a public course marketplace: only signed-in members of your organisation can open a course. Courses list showing course cards with lesson, quiz and student counts, an All Courses and My Courses tab, and a Create a course button An organisation with nothing published yet sees an empty list inviting a first course. If the list cannot be loaded at all, the page says **Courses could not be loaded** and offers **Try again**, so a failed request does not read as a catalogue with nothing in it. *** ## Turning it on Courses is a module, on by default. **Settings** → **Gamification & Courses** → **Courses** has two switches: | Setting | What it does | | ------------------------------ | -------------------------------------------------------------------------------------------------------- | | **Enable Courses** | Shows the Courses entry in the sidebar and enables every course screen. | | **Enforce onboarding courses** | Blocks members from the rest of the platform until they finish their onboarding courses. Off by default. | Toggling the module requires `ADMIN_TENANT`. *** ## Who can do what | Action | Permission | | ------------------------------------------------------ | ------------------------------------------------------ | | Browse and take courses | Any signed-in member | | Create, edit, delete a course, add lessons and quizzes | `HR_TENANT`, or `HR_LOCAL` on the course's local group | | Enrol other members, view the Students tab, export | `HR_TENANT`, or `HR_LOCAL` on the course's local group | A local manager (`HR_LOCAL`) must keep the course inside a local group they belong to. If they do not pick one when creating, their own group is filled in automatically, and they cannot later move the course to a group they have no rights over or make it organisation-wide. *** ## Building a course **Courses** → **Create a course**. The Course tab holds the settings; the Lessons and Students tabs unlock once the course is saved. | Field | What it does | | ----------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Course Title** | Name shown on the card and course page. | | **Course availability** | **Available for all users**, or **Available for specific user types**. Members whose user type is not selected never see the course, not in the list and not by direct link. | | **Local center** | Appears when the local groups module is active. Members see organisation-wide courses plus courses of the groups they belong to. | | **description** | Shown on the course page and truncated on the card. | | **Award badge on completion** | Appears when the Gamification module is active and the course is saved. | | **Image thumbnail** | Card image, 16:9. | Two dropdowns sit in the header: * **Status**: **Draft** or **Published**. Draft courses are visible only to `HR_TENANT` and to a local manager of that course's group. Everyone else gets a not-found. * **Course type**: **Self-paced** or **User onboarding**. See [Onboarding courses](#onboarding-courses). ### Sections, lessons and quizzes On the **Lessons** tab, add a section, then use **Add new** on that section for a **Lesson** or a **Quiz**. Sections and items are reordered by dragging. Each item has its own Draft or Published state and a menu with View, Edit, Duplicate, Rename and Delete. Course builder Lessons tab showing sections with nested lessons and quizzes, drag handles, per-item Draft and Published tags, and an Add new menu **Lesson editor** | Field | What it does | | --------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Status** | Draft or Published. | | **Require completion to proceed** | Locks every later item until this lesson is completed. | | **Enable featured media** | Shows the media block at the top of the lesson. | | **Featured Media** | Upload a video (.MP4, .MOV, .WEBM, .AVI) or audio file (.MP3, .M4A, .WAV) up to 200MB, or paste an embed URL. YouTube, Vimeo, Loom and Wistia links are rendered; other hosts render nothing. | | **Lesson Content** | Rich text editor. | | **Attachments** | PDF, Word, Excel, PowerPoint, TXT, CSV, PNG, JPEG, WEBP, GIF and ZIP, up to 50MB per file. | **Quiz editor** | Field | What it does | | ------------------------- | ----------------------------------------------------------------------------------------------------- | | **Status** | Draft or Published. | | **Enforce passing grade** | When on, the member must reach the score below before later items unlock. They may retake the quiz. | | Passing grade | Percentage, defaults to 80. Only shown when Enforce passing grade is on. | | **Question type** | **Single answer** or **Multiple answers**. These are the only two types. | | **Responses** | At least two options per question, with the correct one or ones marked. Questions can carry an image. | Scoring is done on the server: each question is worth its points value (1 by default) and the score is the percentage of points earned. Nothing is graded by hand. *** ## Enrolling members Members enrol themselves with **Enroll in course** on the course page. They can leave a self-paced course they have not finished with **Drop Course**. Managers enrol people from the **Students** tab: **Add member**, pick one or more members, then **Add**. Enrolling somebody who is already on the course is rejected rather than duplicated. The **Notify member** checkbox in the Add member dialog does not currently send anything. The enrolment itself is created normally, but the notification email fails silently. Tell newly enrolled members yourself, or announce the course through a [newsletter](/docs/platform/newsletter). There is no approval queue, no invite-only mode and no prerequisites between courses. Access is controlled by the course's user types and local group. *** ## Progress and completion Progress is the share of published lessons and quizzes the member has completed. An enrolment moves from **Enrolled** to **In progress** on the first completed item, and to **Completed** at 100 percent. When an enrolment reaches Completed and the course has a badge (and Gamification is on), the badge is awarded automatically. Deleting a completed enrolment takes the badge back. Course completion does not produce a certificate: nothing is generated, and there is no certificate download. ### Tracking members The **Students** tab lists everyone enrolled, filterable by All, Enrolled, In progress and Completed, and searchable by name. The table shows Member, Enrolled, Last update, Progress and Status. Row actions are View Profile, View Progress (opens the course in read-only mode as that member sees it) and Remove. Students tab of a course showing the status filter, student count, Export menu and a table with member, enrolled date, last update, progress bar and status Two exports sit behind the **Export** button: * **Export Students (CSV)**: Name, Email, Enrolled Date, Last Accessed, Progress (%), Status, Completed Date. * **Export Quiz Results**, one file per quiz: Student Name, Email, Attempt #, Score (%), Passed, Time Spent (s), Started, Submitted. There is no completion-rate dashboard or drop-off chart. Use the exports for reporting. *** ## Onboarding courses Set **Course type** to **User onboarding** to make a course part of the joining flow. Saving any course as **User onboarding** switches the tenant setting **Enforce onboarding courses** on for you if it was off. From that point, members with an unfinished onboarding course are redirected away from the rest of the platform. Once enforcement is on, a member who opens Orgo is sent to a mandatory-course screen listing every published onboarding course that matches their user type and that they have not completed. The gate does not apply to `HR_TENANT` users, to the Event App, or to a member who owes a mandatory fee (the fee gate takes priority and runs first). *** ## Deleting a course A course with even one enrolment cannot be deleted. Remove the enrolments first, or set the course back to Draft to take it out of circulation. *** ## Automating around courses If you use Workflows, three course triggers are available: **Course Enrolled**, **Course Completed** and **All Onboarding Courses Completed**. Use them to send a message, apply a tag or move a member forward once training is done. *** ## Related * [Badges & Gamification](/docs/platform/badges) - award a badge on course completion * [User types](/docs/platform/users/user-types) - the audience filter on every course * [Permissions](/docs/platform/permissions) - what `HR_TENANT` and `HR_LOCAL` unlock * [Local groups](/docs/platform/local-group-fees/create-local-fees) - scoping a course to one group * [Events](/docs/platform/events) - for training that happens in person # Custom Domain Source: https://orgo.space/docs/platform/custom-domain Serve your community from your own address, with TLS and email sender identity set up in the same flow By default your community lives at `yourorg.orgo.space`. A custom domain moves it to an address you own, such as `members.yourorg.org`. The same setup also requests the TLS certificate and prepares your domain as an email sender, so you do this once rather than three times. **Built for** organizations whose members should never see a vendor address, including federations, associations, and unions with an established public domain. **Replaces** running a redirect or a reverse proxy of your own in front of the members' area. **Settings → Customization → Custom Domain** Requires **ADMIN\_TENANT**. Every endpoint behind this page enforces it server side, not just the menu. Custom Domain setup page showing the before-you-start checklist and the App host field *** ## Before you start The page states four things up front, and all four matter: * You need DNS access at your domain's **apex** (for example `acme.com`), not just at the subdomain. * Setup takes about 10 minutes of your time. Validation afterwards is not instant. * Your old URL keeps working: once the new domain goes live, `yourorg.orgo.space` redirects to it automatically. * TLS is free and renewed for you. Two rules are enforced when you submit. **It must be a subdomain**: `members.acme.com` is accepted, `acme.com` is rejected, and Orgo resolves the registrable apex using the public suffix list, so `community.acme.co.uk` correctly resolves to `acme.co.uk`. **One setup at a time**: cancel a running setup before starting another. *** ## The setup sequence Type the address, for example `community.acme.com`; the page previews the final URL. **Start setup** immediately requests a wildcard TLS certificate for `*.`, creates a sender identity for the same apex, and points that identity's bounce address at `bounce.`. Once both requests come back, the status becomes **Awaiting DNS** and two record groups appear. Add every record exactly as shown at your DNS provider. Use **Copy all as text** or **Download as CSV** rather than retyping. Orgo checks for the records on its own. The page refreshes every 10 seconds while setup is running, and **Check now** forces an immediate check. When the certificate is issued and your CNAME actually resolves to the Orgo target, the domain starts serving and the old address begins redirecting. *** ## The two record groups ### Domain Validation Proves you own the domain so the certificate can be issued, and points traffic at Orgo. | Record | What it is | | ------------------ | ---------------------------------------------------------------------------------------------------- | | CNAME (validation) | A one-off ownership proof under your apex. Marked **Verified** once the certificate is issued. | | CNAME (your host) | Points `community.acme.com` at the Orgo endpoint. Marked **Verified** once the domain has gone live. | ### Email Setup Authorises Orgo to send mail signed as your domain, and makes that mail authenticate as yours rather than as Amazon's. | Type | Name | Value | What it is | | -------------------- | --------------------------- | ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------ | | CNAME, three of them | `._domainkey.` | `.dkim.amazonses.com` | DKIM signing keys. Required, and all three must be present | | MX | `bounce.` | `10 feedback-smtp..amazonses.com` | Required. Moves the envelope sender onto your own domain | | TXT | `bounce.` | `"v=spf1 include:amazonses.com -all"` | Required. The SPF record authorising Amazon SES for that subdomain | | TXT | `_dmarc.` | `"v=DMARC1; p=none;"` | Badged **Recommended**, not required. It tells receiving servers what to do with messages that fail authentication | Five required records, so the verified counter next to **Email Setup** now counts to 5. It can read 5/5 while the DMARC row still shows as Recommended, because recommended records are not counted. `` is the AWS region your sender identity lives in, today `eu-central-1`. Copy every name and value from the page rather than from this table: the DKIM tokens are unique to your domain, and the region is stored per setup so it cannot change under you. Some DNS providers append your domain to any value you paste, silently turning a correct record into a wrong one. After saving, read the stored record back and compare it character for character with what Orgo shows. Three things to check against the form your provider gives you: * **The zone.** All of these belong in your apex zone. A provider that asks for a host name relative to the zone wants `bounce`, not `bounce.acme.com`. * **The MX priority.** The leading `10` in the MX value is the priority. If your provider has a separate priority field, put `10` there and only `feedback-smtp..amazonses.com` in the value. * **The quotes.** Orgo shows TXT values wrapped in double quotes, which is how they look in a zone file. Most provider forms want the value without the surrounding quotes; the few that take raw zone-file syntax want them. Match how the TXT records already in your zone are stored. ### What the bounce records do Every email carries two sender addresses: the `From:` header your recipients read, and the envelope sender (the `Return-Path`) that only the receiving server sees. Without these two records, the envelope sender on Orgo's mail for you sits on a subdomain of `amazonses.com`. That matters because SPF is checked against the envelope domain. SPF passes, but it passes for Amazon's domain rather than yours, so it is not *aligned* with your `From:` header, and DMARC only counts a check that passes **and** aligns. Your DMARC result then rests entirely on DKIM, and filters that score the `From:` domain's SPF on their own mark the message down. The MX record moves the envelope onto `bounce.`, a subdomain of your own domain, and the TXT record on that subdomain authorises Amazon SES to send for it. SPF then both passes and aligns, so DMARC has two independent passing checks instead of one. What it does not do: * It does not change the address recipients see. That is the contact email verification described under [Going live](#going-live-and-what-changes). * It does not replace DKIM. Both stay required, and DKIM is still what carries alignment if a message is forwarded. * It does not change the SPF record on your apex, and does not need to. For Orgo's mail, the SPF record receivers consult is the one on `bounce.`. * It relies on DMARC's default relaxed alignment, under which `bounce.acme.com` counts as aligned with `acme.com`. If your DMARC record asks for strict SPF alignment with `aspf=s`, a subdomain does not align and DKIM remains your only aligned check. * It does not improve a domain's existing reputation, and it does not gate anything in this setup. Status, going live, and sender verification all ignore it. If the MX record is missing, wrong, or removed later, Amazon SES silently falls back to its own envelope domain and your mail keeps flowing exactly as it did before. That fallback is deliberate: a DNS typo here costs you alignment, never delivery. Verification watches the MX record only. When Amazon SES finds it, both bounce rows flip to **Verified** together, so a Verified badge on the TXT row means the MX was found, not that the SPF value was read and approved. Check that one back yourself. ### Your existing SPF record Below the records table you may see a panel titled **Optional: your existing SPF record**. It is advice about the SPF record on your **apex**, and it is deliberately not a copy-paste row in the table above. It appears in one of two forms: * **A merged value.** Orgo reads the SPF record currently published on your apex and offers the same record with `include:amazonses.com` inserted before the trailing `all`, keeping every sender you already authorise. If your apex has no SPF record at all, the suggestion is a bare `v=spf1 include:amazonses.com ~all`. * **A warning with no value**, when your record is already close to SPF's ceiling of 10 DNS lookups. One more lookup could cross it, which fails SPF for your whole domain, so the fix is to consolidate the record first rather than add to it. Nothing appears when your apex already lists Amazon SES, or while the lookup has not returned an answer yet. Publish only the merged value Orgo shows, never a bare `v=spf1 include:amazonses.com` record. A domain may hold exactly one SPF record, so pasting a bare one over an apex record that authorises your real mail (Google Workspace, your CRM, your ticketing tool) stops all of it authenticating. This panel is optional in the real sense: your mail authenticates correctly without it, because the record that matters for Orgo is on `bounce.`. It exists for the filters that also glance at the apex. ### Records on a domain that was already verified Orgo never repoints a sender identity that already has a bounce domain of its own. If your domain was configured by hand before this existed, that bounce domain is kept and the wizard shows its records rather than `bounce.`. Otherwise, the next automatic check adds the bounce configuration to your existing setup. Two new rows appear in **Email Setup** marked Pending and the counter that used to read 3/3 now reads 3/5. Nothing else changes: your domain stays **Active**, mail keeps sending, and DKIM keeps signing. Publish the two records when it suits you and the badge flips on the next check. *** ## Status reference | Status | Meaning | What you do | | ------------------ | ------------------------------------------------------------------------------------- | ------------------------------------------ | | **Provisioning** | The certificate and sender identity are being requested. Records appear here shortly. | Wait | | **Awaiting DNS** | Records are ready to be added at your provider. | **Add the records** | | **Validating DNS** | Your records are being checked. Usually minutes once they exist. | Wait | | **Active** | The domain serves your community and email is signed by your domain. | Nothing | | **Failed** | Setup hit an error. | **Retry**, or contact support if it recurs | Awaiting DNS is the only status that needs you. **The 7-day limit.** A setup that sits in Awaiting DNS or Validating for 7 days is cleaned up: the certificate and the sender identity are released and the setup record is deleted. There is no warning status for this. The page simply returns to the empty **Start setup** form, and you begin again from scratch. **How often Orgo re-checks.** Checks start once a minute and slow down the longer a setup waits: roughly every minute for the first half hour, then every five minutes for about six hours, then every half hour for about a day, then once a day until the 7-day cleanup. **Check now** bypasses that schedule, so use it after you have just saved your records rather than waiting for the next automatic pass. *** ## Going live, and what changes Two things have to finish, and they rarely finish together. **Traffic.** The certificate must be issued **and** your host's CNAME must actually resolve to the Orgo target. Only then does Orgo switch your app host over and set up the redirect from `yourorg.orgo.space`. **Email.** Both the domain verification and all three DKIM keys must succeed. When they do, and your organization's contact email is on the same domain (or a subdomain of it), Orgo marks that address as a verified sender. Until then, mail goes out from `no-reply@orgo.space` with your contact email as the reply address; after verification, from your contact email. The two bounce records are not part of this gate: a domain reaches **Active** with them still Pending, and they can be published afterwards. The status reads **Active** only once both halves are done, so a domain can be serving pages perfectly while the page still says Validating because DKIM has not propagated yet. Set your contact email **before** the DKIM records verify. Orgo checks the contact email once, on the first check where domain verification and all three DKIM keys are green, and never revisits it. If the address was on another domain at that moment, changing it afterwards in [Organization Info](/docs/platform/organisation/organisation-info) will not promote it on its own; ask support to re-run the promotion. Payment and donation short links (`/pay/`) use a separate payment host this setup does not change; ask support if you want those on your domain too. *** ## Cancelling and retrying **Retry** on a failed setup cancels the current attempt and starts a fresh one under the same host name. **Cancel setup**, and **Remove custom domain** on a live one, destroy the TLS certificate and the email sender identity, remove the routing, and drop the redirect from the old address. The DNS records you added stop doing anything, and starting again requests a brand-new certificate. If you have been in Awaiting DNS for more than an hour with records you have verified, contact support rather than cancelling. Starting over requests a new certificate and puts you back at the start of the same validation window. *** ## Troubleshooting Awaiting DNS and Validating both mean the domain is not serving yet. If the status is Active, your own machine may be holding an older DNS answer, so try a private window or another network. Usually the provider rewrote the record, so check for an added trailing dot. Otherwise the records went into the wrong zone: they belong at your apex, not at the subdomain. Almost always certificate validation not completing inside its window, meaning the validation record was not in place in time. Confirm it, then use **Retry**. All three DKIM records in the Email Setup group must read Verified, and your organization contact email must have been on the new domain at the moment they turned green. If it was not, support has to promote it for you. Those are the bounce records, added to every custom domain so that SPF authenticates as your domain rather than as Amazon's. Nothing broke and nothing is waiting on you: your domain stays Active and mail keeps sending while they read Pending. Publish them when convenient. The record belongs in your apex zone, where most provider forms want a host of just `bounce`, not `bounce.acme.com`, and never the subdomain your community runs on. Providers with a separate priority field also want `10` in that field rather than at the front of the value. Mail is unaffected either way: Amazon SES falls back to its own envelope domain while the record is missing. No. The SPF record receivers consult for Orgo's mail is the one on `bounce.`. The apex panel is advice for filters that also look at your main domain, and it only ever offers a value that keeps the senders you already authorise. If it shows a warning instead of a value, your record is near the 10-lookup limit and needs consolidating before anything is added. That line is the last error from the most recent check. It clears as soon as a check runs clean, so a message that stays means the condition is still present. A social sign-in that is refused always finishes on `app.orgo.space`, never on your domain, so the member sees an address that is not yours. That is the refusal itself, not a domain fault: the `auth_error` value in the address bar names the reason, usually an account status that social sign-in does not accept. A sign-in that succeeds stays on your domain. See [Troubleshooting access](/docs/platform/users/troubleshooting-access). *** ## Related * [Branding](/docs/platform/organisation/branding) - Logos, login background, and interface theme * [Organization Info](/docs/platform/organisation/organisation-info) - Contact email and sender identity * [Modules](/docs/platform/organisation/modules) - Turn platform features on and off * [Mobile Apps](/docs/platform/mobile-apps) - Shared app and branded apps * [Permissions](/docs/platform/permissions) - What ADMIN\_TENANT unlocks # Dashboard Organizer Source: https://orgo.space/docs/platform/customization/dashboard-organizer Build the member dashboard from content sections and widget grids, by drag and drop **Built for** organizations that want the dashboard to lead with their own priorities. **Replaces** a fixed home page everyone scrolls past. The Dashboard Organizer composes the member dashboard from categories. A category is either a **content section** Orgo fills automatically (latest discussions, upcoming events, groups, member suggestions) or a **widget grid** you fill with your own tiles. Dashboard organizer in edit mode with the Dashboard Elements palette on the right, holding Available Categories, Widget Grids and Available Widgets, and the placed dashboard sections on the left: Latest Discussions, a Member Shortcuts widget grid and Latest Events **Settings → Customization → Dashboard Organizer** Requires **ADMIN\_TENANT** and **Use Custom Dashboard**, a switch under **Settings → Modules → Users & Profiles → Advanced Settings**. Its own help text says it: *when enabled, the home page shows the configurable dashboard with widgets instead of the default feed*. While it is off, this page is hidden from Settings and redirects to the dashboard. *** ## Building the dashboard It opens in edit mode already, with the palette on the right and a grip handle and delete button on every category. After you press **Save Changes** it drops back to a plain preview, and an **Edit Dashboard Layout** button brings the palette back. Drop it between existing categories to control where it lands. A blue line shows the insertion point. A grid shows empty slots. Click one to open the widget picker, or drag a widget straight from the palette into a slot. Drag a placed widget onto another slot to swap them. Click a placed widget to open its settings: title, icon, background colour and its type-specific options. Click a category name to edit it inline. Drag the grip handle to move a category up or down. The first category is the top of the dashboard. The button stays disabled until something has actually changed. Nothing is applied to members until you press it. *** ## Content sections Orgo fills these; there is nothing to configure inside them. | Palette name | What members see | | ---------------------- | ------------------------------------------------------------- | | **Latest Discussions** | Recent discussion cards from the groups they belong to | | **Latest Events** | Upcoming events as a horizontal card strip | | **Community Groups** | The groups available to them, as a grid | | **Discover members** | Suggested members to connect with, each with a connect button | Each can be added once. Once it is on the dashboard it disappears from the palette. **Discover members** only appears in the palette when **User Recommendations** is on (**Settings → Modules → Users & Profiles → Advanced Settings**), and it is hidden from the dashboard again if that switch is later turned off. *** ## Widget grids The palette offers one grid category, **Widget Grid (3-16 widgets)**. It starts with three slots and grows a slot at a time as you fill it, up to sixteen. Add as many grid categories as you need. | Widget | What it does | Configuration | | ----------------------- | ------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------- | | **Link Widget** | A tile that opens an address | **Link URL**, plus an optional **Widget Image** you upload | | **Weather Widget** | Current weather for a place | **Location** (city search) and **Temperature Unit**: Celsius, Fahrenheit or Kelvin | | **Discussion Category** | A tile that jumps into discussions | **Discussion Category** to open, or **All Discussions**, plus an optional image | | **Photo Widget** | An image tile, rendered double width | A **Default Photo**, plus optional **User Type Specific Photos** so different member types see different images in the same slot | Every widget also takes a **Widget Title**, an **icon** picked from a searchable list (or none), and a **Background Color**. Deleting a widget removes any images it held. Organizations set up before the dynamic grid may still have fixed grids of 3, 4, 6, 8 or 16 slots. Those keep working exactly as before; only new grids use the flexible one. *** ## Where the configured dashboard appears With the Custom Dashboard feature on, the member dashboard at **/dashboard** renders your configured categories at the top, followed by the standard dashboard content. Without the feature, members get Orgo's default feed dashboard and this page is unavailable. The layout is responsive: grids sit side by side on desktop and stack into fewer columns on mobile. Category order is the same on both, so put the thing you most want seen first. Three to five categories is usually enough. A long dashboard is scrolled past as fast as an empty one. *** ## Troubleshooting Turn on **Use Custom Dashboard** under **Settings → Modules → Users & Profiles → Advanced Settings**. Until then the dashboard is Orgo's default feed and cannot be composed. Nothing has changed yet. The button enables on the first real edit. Renaming a category only counts once you confirm the inline edit. Each is single-use: if it is already on the dashboard it will not appear again. **Discover members** additionally requires member recommendations to be enabled. Content sections render each member's own data. Latest Discussions is empty for someone in no groups; Latest Events is empty when nothing upcoming is visible to them. Pair a content section with a widget grid so the dashboard is never blank. The layout is one for the whole organization. Only the **Photo Widget** varies by audience, through its user type specific photos. For role-specific messaging use [Dashboard Welcome](/docs/platform/customization/dashboard-welcome), which does target by user type. *** ## Related * [Dashboard Welcome](/docs/platform/customization/dashboard-welcome) - the greeting above the dashboard * [Menu Organizer](/docs/platform/customization/menu-organizer) - the sidebar equivalent * [Discussions](/docs/platform/discussion) - what the discussion sections and widgets point at * [Events](/docs/platform/events) - what the events section shows * [Customization](/docs/platform/customization) - everything under Settings → Customization # Dashboard Welcome Source: https://orgo.space/docs/platform/customization/dashboard-welcome A rich-text greeting at the top of the dashboard, optionally different per user type **Built for** the first thing a member reads after logging in. **Replaces** a launch email nobody reopens. The welcome message sits at the top of the dashboard. It is rich text with images and personalization placeholders. Every organization has one general message, and organizations that use user types can add more, each aimed at specific types. Welcome Messages by User Type page with the Create New Message button and the Hide welcome message toggle above three cards: the Default message tagged All other users, and two messages tagged Volunteer and Student Member, each with a Sticky switch, an edit button and, on the non-default ones, a delete button **Settings → Customization → Dashboard Welcome** Requires **ADMIN\_TENANT**. The page is headed **Welcome Messages by User Type**. *** ## Writing the message An organization with a single message opens it in edit mode automatically. The editor supports headings, bold, italic, links, lists and pasted or uploaded images. Images are uploaded when you save, not when you paste them. Type them inline in curly braces. They resolve per member when the dashboard renders. **Welcome message Image URL** takes the address of an image shown alongside the message. It must be a publicly reachable URL. On a non-default message, add user types from the dropdown. See targeting below. The message is live immediately. ### Placeholders | Placeholder | Resolves to | | -------------------- | ------------------------ | | `{firstName}` | The reader's first name | | `{lastName}` | The reader's last name | | `{organizationName}` | Your organization's name | Write them exactly as shown, with no spaces inside the braces. The editor's own hint lists only the two name placeholders, but `{organizationName}` works as well. Welcome message editor with the rich text area, the placeholder hint, the image URL field and the sticky switch *** ## Targeting by user type The **Create New Message** button appears only when your organization uses user types. Without them there is a single message for everyone and nothing to target. * The **Default** message is tagged as such and labelled **All other users**. It is the fallback for anyone whose user type has no message of its own. It cannot be deleted. * Any other message carries a list of user type tags. Assignment is exclusive: adding a user type to one message removes it from whichever message held it before, so a member is never matched by two. * A non-default message with no user types assigned shows **No user types assigned** and reaches nobody. ### Which message a member sees | Situation | Result | | ------------------------------------------------------------------- | ------------------------------------------------- | | **Hide welcome message** is on | No message, for anyone | | The member's user type has its own message | That message | | ...and **Show general and user type messages** is on | The general message first, then the user-type one | | The member's user type has no message, or user types are not in use | The general message | | No message exists at all | Nothing renders | Both switches sit at the top of the page. **Show general and user type messages** only appears once at least one user-type message exists. *** ## Sticky and dismissible Each saved message has a **Sticky** toggle, and the help text says it plainly: *if activated, the message is always visible and cannot be closed by users*. A non-sticky message has a close button. Once a member closes it, it stays hidden for them across sessions, on every message that is not sticky. That preference is per member and is not reset when you edit the text. Editing a non-sticky message does not bring it back for members who already dismissed it. For an announcement that must be read, make it sticky, or use a [notification](/docs/platform/notifications) or the [newsletter](/docs/platform/newsletter). *** ## What to put in it | Situation | Content | | --------------------- | ---------------------------------------------------------------- | | Launching Orgo | What the platform is for and the first two or three things to do | | Onboarding | Complete your profile, join a group, check upcoming events | | Seasonal | Registration opens, deadline dates, one clear link | | Nothing in particular | `Welcome back, {firstName}!` and a link. Timeless beats stale | A dated message is worse than none. Either keep it current or write something that does not expire. *** ## Troubleshooting Check **Hide welcome message** is off, that a message exists, and that its content is not empty (the card shows **No content yet** when it is). If you use user types, check the reader's type is either assigned to a message or covered by the default. Almost always a dismissal. Non-sticky messages stay closed once a member closes them. Turn on **Sticky** to make it unclosable. Use single braces with no spaces: `{firstName}`, not `{ firstName }`. Names are case-sensitive. Only `{firstName}`, `{lastName}` and `{organizationName}` are substituted; anything else is left as typed. That is intentional. A user type belongs to exactly one message, so adding it here removes it there. The image URL must be publicly reachable over HTTPS. Test it in a private browser window. Images pasted into the editor itself are uploaded when you save the message, so save before checking those. Not supported: targeting is by user type only. Either use `{organizationName}` and keep the message generic, or send local announcements through [notifications](/docs/platform/notifications) or a [newsletter](/docs/platform/newsletter) segmented by local center. You cannot. Blank its content, or turn on **Hide welcome message** to suppress all messages at once. *** ## Related * [Dashboard Organizer](/docs/platform/customization/dashboard-organizer) - the rest of the dashboard * [User Types](/docs/platform/users/user-types) - the types you target messages at * [Notifications](/docs/platform/notifications) - for time-sensitive messages * [Newsletter](/docs/platform/newsletter) - for anything that has to reach inboxes * [Customization](/docs/platform/customization) - everything under Settings → Customization # Data Import Source: https://orgo.space/docs/platform/customization/import Bulk-create and bulk-update members, contacts, events, badges, products and companies from CSV files Import turns CSV files into Orgo records. It is how you migrate from another system, load a historical archive, or push a bulk correction across thousands of profiles without touching them one at a time. **Built for** organisations arriving with years of data in another tool or in spreadsheets. **Replaces** the manual re-typing, and the "can you just run this SQL" request. The page is at **Settings** → **Customization** → **Import** (`/tenants/import`), titled **Data Import System**. Every import endpoint requires `ADMIN_TENANT`. Data Import System page showing the recommended import order as numbered steps, each with a Choose CSV button and an example file download *** ## How the page works The page is a numbered list, not a wizard: each entry is one import type. No column-mapping screen, no options dialog, no dry run. The file you upload is the instruction. The download icon on each step gives you a file with the exact column headers that step reads. `.csv` and `.txt`, up to 50 MB. Comma, semicolon and tab are detected automatically, and a UTF-8 byte order mark is stripped. A larger file is refused on the spot with "File is larger than the 50 MB import limit"; split it and run the parts one after another. Validation and processing run in the background, in batches, so a large file keeps going after you close the tab. A live percentage, refreshed every three seconds, with running counts of successful, failed and skipped rows. The counts move one batch at a time rather than one row at a time, so a file small enough to fit in a single batch stays at 0% until it finishes. Expand the row in **Import History** for per-row failures: row number, message and raw row data. The first 20 are listed, with the total count underneath. Orgo does not email you when an import finishes. Keep the page open, or come back to the history table. Validation runs before any row is written: Orgo looks for the header row in the first 10 lines and checks the required columns. If they are missing, the import fails naming the columns it wanted and the ones it found, and nothing is created. *** ## What you can import Run the steps in the order below: each one can reference records the earlier ones created. Steps whose module is switched off do not appear at all. | Step | Required columns | Needs module | | --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------- | | **Local Centers** | `name`, `local_center_legacy_id` | Local Centers | | **Units** | `name`, `unit_legacy_id` | Groups & Teams, **Enable Organizational Units** | | **Roles** | `name`, `role_legacy_id` | none | | **Badge Types** | `name`, `badge_type_legacy_id` | Gamification | | **Badges** | `name`, `badge_type_legacy_id`, `badge_legacy_id` | Gamification | | **Users** | `user_legacy_id` | none | | **Contacts** | `email` | none | | **User Roles** | `user_legacy_id`, `role_legacy_id`, `start_date` | none | | **Products** | `product_legacy_id`, `name` | Payments & Fees | | **Product Prices** | `product_price_legacy_id`, `product_legacy_id`, `price` | Payments & Fees | | **Product Payments** | one way of naming the payer (`user_legacy_id`, or `payer_email`, or `payer_name` + `payer_email` + `payer_organisation`), the product (`product_legacy_id`, or `product_name` + `product_type`) and the price (`product_price_legacy_id`, or `product_name` + `price_name` + `amount` + `currency`) | Payments & Fees | | **Events** | `name`, `datetime_begin` | Events | | **Event Attendance** | one way of naming the event (`event_legacy_id`, or `event_name` + `event_datetime`, optionally with `chapter`) and the attendee (`user_legacy_id`, or `attendee_email`, or `attendee_name` + `attendee_email` + `attendee_organisation`) | Events | | **Badge Assignments** | `user_legacy_id`, `badge_legacy_id`, `concluded_at` | Gamification | | **Companies** | `company_legacy_id`, `name` | Companies | | **Company Members** | `company_legacy_id`, `user_legacy_id` | Companies | | **Modify Users** | any of `email` / `user_legacy_id` / `phone_number` | none | | **Modify Contacts** | any of `email` / `phone` | none | The `*_legacy_id` columns are the glue: your old system's identifiers, stored on the Orgo record, are how a later file says which event an attendance belongs to. Keep them stable across all your files. Where a step accepts several column shapes, give it legacy ids if you have them, or human columns like `event_name` and `event_datetime`, and Orgo creates or links the event, product, price tier and attendee for you. Companies and Company Members check their required columns row by row rather than upfront, so a file with the wrong headers starts, then fails every row. *** ## Creating versus modifying The first sixteen steps only create: a row matching an existing record counts as **skipped** and the record is left alone. Users match on `user_legacy_id` first, then on email. Contacts whose email belongs to an existing member are skipped by design. The last two steps, under the **Modify existing records** heading, update in place: * **Modify Users** matches on `email`, then `user_legacy_id`, then `phone_number`, in that order. **Modify Contacts** matches on `email`, then `phone`. * An empty cell leaves that field unchanged. Only columns you fill in are written. * A row that matches nothing falls back to creating a contact, provided it carries at least an email or a name. * Usernames, passwords, permissions and API tokens can never be written by an import. Imported members get no email and no usable password: the import writes a placeholder nobody knows. Someone imported with their own address signs in with the email one-time code from the login page, or through a password reset. A row whose email already belongs to somebody else, and a row with no email at all, gets a generated placeholder address that cannot receive mail, so those members cannot sign in until you correct the address. *** ## Custom fields Any column that is not a recognised system column for that step becomes a **profile custom field**. If none with that name exists, Orgo creates one (text, visible on the profile) and stores the value, so custom fields need not exist before the import. A column named `custom_field_123` writes to the existing custom field with that id instead, which is useful when two of your fields share a label. *** ## Rolling back Every completed import has a **Rollback** button in **Import History**, until you use it once. For the create steps, rollback deletes the records that import made, in reverse dependency order, so nothing is left pointing at a missing parent. For **Modify Users** and **Modify Contacts**, Orgo stored a before-image of every row it touched: rollback replays those values, including custom fields, then deletes any contacts the fallback created. The whole rollback is one transaction, so it either completes or changes nothing. Rollback of a modify import restores the values as they were at import time. If another import or an admin changed those records afterwards, those later changes are reverted too. Import History table listing past imports by type and status, including a Processing import with its percentage, a Failed import, and Completed and Rolled Back imports, with results counts that show failed and skipped rows alongside the successful ones and a Rollback button on the completed imports Statuses you will see: **Pending**, **Validating**, **Processing**, **Completed**, **Failed**, **Rolled Back**. The history keeps the 50 most recent imports. *** ## Troubleshooting Header validation. The message lists the columns the step needs and the ones it found: check for a title row above the headers and for renamed headers, then upload the corrected file. Skipped means the record already exists, the expected result when you re-run the same file. To update those records instead, use **Modify Users** or **Modify Contacts**. Progress is written when a batch finishes, so a minute or two at 0% is normal on a file that fits in one batch. The slow case is a Local Centers, Units or Users file whose town column names places Orgo has not seen before: each new name is looked up against an external place-name service one row at a time. Leave it running and reload the history table. If it is still **Processing** after fifteen minutes with no counts, the batch did not finish and nothing was written: split the file into smaller parts and run them one after another. The header did not match a system column for that step. Built-in names are snake\_case (`first_name`, `phone_number`, `birth_date`, `town_residence`), not camel case. Compare against the example CSV, roll the import back, fix the header, run it again. Yes, but not from this page. Open the list and use the CSV import inside it. See [Lists & Segments](/docs/platform/users/lists). *** ## Related * [Adding Members](/docs/platform/users/adding-members) - the other three ways people get an account * [Users & Profiles](/docs/platform/users) - what the imported members look like afterwards * [Merging Duplicates](/docs/platform/users/merging-duplicates) - cleaning up records an import doubled * [Custom Fields](/docs/platform/users/custom-fields) - the fields an import can create * [Lists & Segments](/docs/platform/users/lists) - importing members straight into a list * [Contacts](/docs/platform/contacts) - the difference between a contact and a member # Customization Source: https://orgo.space/docs/platform/customization/index Make Orgo speak your language and show your structure: languages, wording, menu, dashboard and data import **Built for** organizations that are not generic and should not read as if they were. **Replaces** custom development to change wording, navigation or a home page. Orgo runs thousands of very different organizations. The Customization section is where you make it fit yours: which languages members can use, what things are called, what the sidebar contains, what the dashboard shows, and how your existing data gets in. Settings sidebar scrolled to the Customization section, listing Workflows, eDocuments templates, Custom Domain, Languages, Texts, Menu Organizer, Dashboard Organizer, Dashboard Welcome and Import, with the demo-only Demo Data and AI Provisioning entries below them and the Developers section underneath **Settings → Customization** Every page in this section requires **ADMIN\_TENANT**. Local, HR and financial admins do not see the Settings area. *** ## What is in the section | Page | What it does | | ------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------- | | [Workflows](/docs/platform/workflows) | Automate actions from events and triggers | | **eDocuments templates** | Document templates. Shown only when the eDocuments module is on. See [E-Document Templates and Signing](/docs/platform/contracts) | | [Custom Domain](/docs/platform/custom-domain) | Run Orgo on your own address | | [Languages](/docs/platform/customization/languages) | Choose the interface languages members can use, and the default | | [Texts](/docs/platform/customization/labels) | Replace Orgo's wording with your own, per language | | [Menu Organizer](/docs/platform/customization/menu-organizer) | Reorder, rename, hide and permission-scope the sidebar | | [Dashboard Organizer](/docs/platform/customization/dashboard-organizer) | Compose the dashboard. Needs **Use Custom Dashboard** | | [Dashboard Welcome](/docs/platform/customization/dashboard-welcome) | The greeting at the top of the dashboard | | [Import](/docs/platform/customization/import) | Bring members and other records in from a file | Demo organizations get two extra entries, **Demo Data** and **AI Provisioning**, for loading sample content. They disappear once the organization is no longer marked as a demo. The page called **Labels** in earlier documentation is **Texts** in the app. The doc page kept its address. *** ## A sensible order for a new organization Decide the default and which languages members may pick. Doing this first means every later step, including your wording, is written against the right set. Replace the handful of phrases that are wrong for your organization: Members to Scouts, Local Center to Troop. You fill in one column per enabled language, which is why languages come first. Bring in your existing records. Import structure before people so references resolve. Hide what you do not use, promote what you do, restrict admin sections to the right permissions. Write the greeting new members land on. This is the highest-read text you will write. If you turned on **Use Custom Dashboard**, compose the dashboard sections and widget tiles. All of it can be changed later. The reason to do languages and wording before inviting anyone is that early members otherwise learn the vocabulary you are about to replace. *** ## What Customization does not cover | You want to change | Go to | | ------------------------------------- | -------------------------------------------------------------------------------------------------------- | | Logos, login page, colours | [Branding](/docs/platform/organisation/branding) | | Which features exist at all | [Modules](/docs/platform/organisation/modules) | | Legal name, VAT, IBANs, timezone | [Organization Info](/docs/platform/organisation/organisation-info) | | Who can do what | [Permissions](/docs/platform/permissions) | | The wording of emails members receive | Email templates. Text replacements do not reach emails | | Registration and profile fields | [Registration form](/docs/platform/users/registration-form), [Profile fields](/docs/platform/users/profile-fields) | *** ## Troubleshooting The Settings area needs **ADMIN\_TENANT**. Local center admins, HR and financial roles do not have it, by design. It appears only when **Use Custom Dashboard** is on, under **Settings → Modules → Users & Profiles → Advanced Settings**. Wording and menu changes reach a member on their next page load or session start. A hard refresh clears anything stuck. Menu and dashboard edits are staged: neither applies until you press save. Only per tool, and only where the tool provides it. The Menu Organizer has **Reset to defaults**. Text replacements are removed row by row. Dashboard categories are deleted individually. There is deliberately no single reset for the whole section. *** ## Related * [Branding](/docs/platform/organisation/branding) - logos and login page * [Modules](/docs/platform/organisation/modules) - turn features on and off * [Organization Info](/docs/platform/organisation/organisation-info) - the organization's own details * [Permissions](/docs/platform/permissions) - the permissions the menu and dashboard scope against * [Workflows](/docs/platform/workflows) - automation, also under Customization # Texts (label replacements) Source: https://orgo.space/docs/platform/customization/labels Replace any wording in the Orgo interface with your own, per language **Built for** organizations whose vocabulary is not Orgo's: scouts, not members; patrols, not groups. **Replaces** explaining to every new member that "Local Center" means "troop". The **Texts** page holds a list of text replacements. Each row pairs a phrase Orgo ships with the phrase you want in its place, and you fill in one replacement per enabled language. Anything the interface displays can be replaced this way, not just a fixed vocabulary list. Text Replacements page with four saved rows, each pairing a System Expression EN value (Unit, Units, Local center, Local centers) with a Custom Expression EN field holding the replacement (Team, Teams, Chapter, Chapters), a remove cross on every row, and the Add Text Replacement and Save buttons above **Settings → Customization → Texts** Requires **ADMIN\_TENANT**. This page is called **Texts** in the app; the underlying setting is the tenant's label overrides. *** ## Adding a replacement A search panel opens over the page. Type part of the phrase. The search matches both the translated phrase you see in the app and the underlying English source phrase, so searching in either language works. Results are shown with the English source in brackets when it differs. The list is multi-select. Tick as many as you need in one pass; the button shows the count. Phrases already in your table are skipped with a warning instead of being duplicated. Add Text Replacement panel searching for local center, listing the matching interface phrases as checkboxes, with the capitalised and the lowercase form of the same phrase both ticked so the footer button reads Add (2) Back on the table, each new row shows **System Expression** (Orgo's wording, read-only, in your current interface language) and one **Custom Expression** column per enabled language. Type your replacement in each. Click **Save**. The new wording takes effect straight away for you, without a page reload. Other members pick it up the next time their session loads translations. Leave a Custom Expression blank and that language keeps Orgo's wording. You do not have to fill every column. *** ## What a replacement covers A replacement swaps one phrase everywhere that exact phrase is used in the interface. It changes display text only: no data, permission or route changes behind it. | Surface | Replaced? | | --------------------------------------------------------- | ----------------------------------------------------------------------------------- | | Sidebar, page titles, tabs, buttons | Yes | | Form labels, placeholders, help text, validation messages | Yes | | Empty states, confirmation dialogs, toasts | Yes | | The event app and mobile app interface | Yes, same catalogue | | **System and notification emails** | **No.** Emails render from server-side templates that do not read your replacements | | **Generated PDFs** (invoices, adhesions, contracts) | **No** | | Member-written content: posts, event names, group names | No, and there is nothing to replace | Because the same phrase is replaced everywhere it appears, a short common word is risky. Replacing "Group" changes it in the sidebar and also in every sentence that happens to use it. Prefer replacing the specific phrases you actually see wrong. *** ## Working with several languages The table shows one **Custom Expression** column per language you enabled under [Languages](/docs/platform/customization/languages). If multi-language support is off, there is a single column for the organization's default language. The search panel builds its list from the English source catalogue merged with your organization's default language, so a phrase stays findable even when it is only present in one of the two. Enabling a new language later adds an empty column to every existing row. Until you fill it, members using that language see Orgo's wording, not yours. *** ## Common replacements | Orgo's wording | Typical replacement | | --------------- | ---------------------------------------------------- | | Member, Members | Scout(s), Associate(s), Volunteer(s), Participant(s) | | Group, Groups | Patrol(s), Chapter(s), Team(s), Committee(s) | | Local Center | Troop, District, Branch, Section | | Event, Events | Activity/Activities, Meeting(s), Session(s) | | Fee, Fees | Dues, Contribution(s), Subscription(s) | Singular and plural are separate phrases. So are capitalised and lowercase variants. Search broadly and tick all the forms in one pass. *** ## Removing a replacement Click the **x** at the left of the row, then **Save**. The row disappears and Orgo's own wording returns. Clearing a single language's field and saving reverts just that language. *** ## Troubleshooting Those places use a different phrase. Orgo's catalogue holds separate entries for singular, plural and differently capitalised forms, and longer sentences are stored whole rather than assembled from words. Search for the exact text you see on screen and add that as its own row. Correct, and not fixable from this page. Emails are rendered server-side from templates that do not read text replacements. Adjust the wording in the email templates instead. Search a distinctive fragment rather than the whole sentence, and try the English wording as well as your own language. Phrases that come from your own data (a group name, an event type, a custom field label) are not in this catalogue: edit them where they were created. Your own session updates immediately. Other members reload translations on their next page load or session start. A hard refresh clears it for anyone stuck. Nothing prevents that, and it is a real risk. If you rename both Groups and Local Centers to "Teams", nothing in the interface distinguishes them any more. Keep replacements distinct. *** ## Related * [Languages](/docs/platform/customization/languages) - enable languages before filling in their columns * [Menu Organizer](/docs/platform/customization/menu-organizer) - rename a single sidebar entry without touching the phrase everywhere * [Customization](/docs/platform/customization) - everything under Settings → Customization * [Branding](/docs/platform/organisation/branding) - logos and login page * [Modules](/docs/platform/organisation/modules) - turn off a feature instead of renaming it # Languages Source: https://orgo.space/docs/platform/customization/languages Enable the interface languages your members speak, set a default, and let members pick their own **Built for** organizations whose members do not all read the same language. **Replaces** running a separate portal per language. Orgo ships its interface in 14 languages. You choose which of them your members can use, set the default, and each member picks their own from the profile menu. Menus, buttons, form labels and system messages switch immediately. Language Settings page with the multi-language toggle, the enabled-language checkboxes and the default language selector **Settings → Customization → Languages** Requires **ADMIN\_TENANT**. The page is a tenant settings route and is not available to local, HR or financial admins. *** ## Setting up languages Go to **Settings → Customization → Languages**. The page is headed **Language Settings**. With this switch off, everyone sees the platform in the single default language and no language picker is shown. With it on, an **Available Languages** checkbox list appears. Every one of the 14 supported languages has a checkbox, including languages added after your organization was created. While multi-language is on, the dropdown only offers languages you ticked. With it off, the dropdown offers all 14. Saving with multi-language on and nothing ticked is refused with **Please enable at least one language**. If your chosen default is not among the ticked languages, Orgo silently moves the default to the first ticked one. *** ## Supported interface languages | Language | Code | Language | Code | | ---------- | ---- | ---------- | ---- | | English | `en` | Italian | `it` | | Romanian | `ro` | Dutch | `nl` | | German | `de` | Czech | `cs` | | French | `fr` | Slovak | `sk` | | Spanish | `es` | Bulgarian | `bg` | | Portuguese | `pr` | Ukrainian | `ua` | | Estonian | `et` | Lithuanian | `lt` | All 14 carry the full interface catalogue, several thousand phrases each. A phrase that has not been translated yet falls back to English rather than showing a blank or a raw key. Note the Portuguese code: Orgo uses `pr`, not the more common `pt`. Only tick the languages members actually use. Every extra language becomes another column to fill in on the [Texts](/docs/platform/customization/labels) page. *** ## How a member's language is decided Orgo resolves the interface language in this order, highest priority first: 1. **A `?lang=` parameter on the URL**, if that language exists in the platform. This is how invitation and campaign links can open in a specific language. 2. **The member's saved preference** on their profile, set the first time they use the language picker. 3. **The organization default** you set on this page. When multi-language support is off, the default always wins over any saved preference. 4. **English**, if the resolved language is not one Orgo ships. Members change their language from the **profile menu** in the sidebar (or the profile menu in the mobile header). The picker only appears when multi-language support is on, and the mobile one additionally needs more than one language enabled. Choosing a language applies it instantly and saves it to the member's profile, so it follows them to other devices. Changing the organization default does not move members who already picked a language. It affects new members and anyone who never chose. *** ## What is and is not translated | Content | Behaviour | | ---------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Interface**: menus, buttons, form labels, validation and system messages | Translated into all 14 languages, with English as the fallback for any missing phrase | | **Your own wording overrides** | Per language, entered on the [Texts](/docs/platform/customization/labels) page for each enabled language | | **System and notification emails** | Sent in the **organization's** language, not the recipient's, and narrowed to Romanian, English or German. Any other organization language falls back to English. The [invoice email and its PDF](/docs/platform/fees/invoices) are the exception and cover all 14 languages | | **Member-written content**: discussion posts, event descriptions, file names, welcome messages | Stored as written. Orgo never translates it | | **Welcome messages** | Written once per message, not per language. See [Dashboard Welcome](/docs/platform/customization/dashboard-welcome) | Email localisation is the one place where the member's own choice does not apply. If your organization runs in, say, Dutch, members see a Dutch interface but receive English emails. Plan announcements accordingly, or use the [Newsletter](/docs/platform/newsletter) for anything that must land in a specific language. *** ## Troubleshooting The picker is tied to **Enable Multi-language Support**. Turn it on and tick at least two languages. On mobile the picker also requires more than one enabled language. Expected. A saved profile preference beats the organization default. Members switch it themselves from the profile menu. The default only rules for members who never chose, and for everyone while multi-language support is off. Any phrase missing from that language file renders in English. This affects a small number of recently added phrases. It is not a configuration problem on your side. System emails render in Romanian, English or German only, chosen from the organization language, with English as the fallback. French is not among them, so English is correct behaviour. Invoices are the exception: the [invoice PDF and the email that carries it](/docs/platform/fees/invoices) cover all 14 languages, so a French organization's invoices do arrive in French. Enable both and make the majority language the default. Posts, event descriptions and file names stay in whatever language they were written in. Bilingual organizations usually post announcements in both languages in the same message. *** ## Related * [Texts](/docs/platform/customization/labels) - replace Orgo's wording with your own, per language * [Customization](/docs/platform/customization) - everything under Settings → Customization * [Organization Info](/docs/platform/organisation/organisation-info) - country, currency and timezone * [Dashboard Welcome](/docs/platform/customization/dashboard-welcome) - the greeting on the dashboard * [Newsletter](/docs/platform/newsletter) - campaigns you write in a specific language # Menu Organizer Source: https://orgo.space/docs/platform/customization/menu-organizer Reorder, rename, hide and permission-scope the sidebar, and add your own links **Built for** organizations that use a subset of Orgo and want a sidebar that reflects it. **Replaces** telling members to ignore half the menu. The Menu Organizer edits the sidebar: the order of categories and items, their names and icons, who sees each one, and any custom links you add on top. Menu organizer with draggable categories, per-item permission dropdowns and the desktop and mobile preview toggle **Settings → Customization → Menu Organizer** Requires **ADMIN\_TENANT**. Changes are held locally until you press **save**; nothing is applied as you drag. *** ## How the sidebar is built The sidebar has two sections, and members switch between them: * **Community**: the Main category, Groups and Projects. * **Administration**: Communication, Finance and Management. The Menu Organizer edits the **Community** categories. The three Administration categories are managed by Orgo and are not listed in the editor: their contents are already permission-scoped so that a member only sees what their role unlocks. **CRM Mode (unified menu without groups)** is a switch at the top of the page. Turning it on merges everything into a single list and drops the Groups category, which suits organizations that use Orgo as a contact database rather than a community. In CRM mode the Communication, Finance and Management categories become editable in the organizer too. *** ## Editing the menu Drag a category by its grip handle to move it, or drag an item between categories. Categories with a padlock instead of a handle cannot be moved. Click a category name to edit it inline. For an item, click the pencil next to it (or double-click the name) and type a replacement. Enter confirms, Escape discards. Click the icon next to an item. The picker has an **Icons** tab with a searchable icon list and an **Emoji** tab. Every category and every item has a permission dropdown. Tick one or more permissions; the entry then shows for anyone holding **any** of them. Leave it empty for **All permissions**, meaning every member. Where your organization uses user types, a second dropdown limits the entry to selected types. The default is **allUserTypes**. The **x** on an item hides it without deleting it. Hidden items stay in the list, greyed out, with a **+** to restore them. Click **save**. The new sidebar applies for everyone. An item's permission cannot be looser than its category's. The dropdown greys out any permission weaker than the one already set on the category above it. *** ## Permissions you can assign The dropdown groups permissions by tier. Which ones appear depends on your enabled modules and structure. | Tier | Permissions | Shown when | | ------------ | -------------------------------------------------------------------------------------------------------- | ----------------------- | | Organization | `ADMIN_TENANT`, `HR_TENANT`, `HR_ASSISTANT_TENANT`, `COMMUNICATION_TENANT` | Always | | Organization | `FINANCIAL_TENANT` | Payments module on | | Organization | `EVENT_TENANT` | Events module on | | Chapter | `ADMIN_LOCAL`, `HR_LOCAL`, `HR_ASSISTANT_LOCAL`, `FINANCIAL_LOCAL`, `COMMUNICATION_LOCAL`, `EVENT_LOCAL` | Local centers enabled | | Regional | the same six as `_PARENT_LOCAL`, reaching an anchor chapter and every chapter beneath it | Parent chapters enabled | `ROLE_ADMIN_TENANT` is offered as a separate top entry: it restricts an entry to organization administrators only. The two dropdowns at the top left of the page are **filters**, not settings. Pick a permission or a user type there to preview which entries that audience would see. *** ## Default menu contents This is what a new organization starts with. Items whose module is off never render, whatever the Menu Organizer says. **Community → Main** | Item | Needs | | ------------------------------------------------------------------------ | ---------------------------------------------------- | | Home | Always (desktop only; hidden on mobile) | | Members | **Who Can See Members in General Groups** permits it | | Events | Events module | | Files | Drive module | | Voting | Voting module | | Local Centers | Local centers module | | Organization (flyout: Courses, Gazette, Organisational Chart, Analytics) | Per child: courses, gazette, analytics | **Community → Groups** and **Community → Projects** are generated from your actual groups and projects. The editor shows their headers only, never their contents, so neither can be reordered internally. In the default menu both are also marked as not modifiable, which is why they carry a padlock instead of a grip handle. Projects requires the project management module. The Groups header carries three extra buttons: **Manage group categories**, **Colors** (the bullet colour per group kind) and **Emojis** (an emoji per group, replacing its bullet). **Administration → Communication**: Email campaigns, Campaign templates, Lists & Segments, Newsletter subscription, Email Log, Moderation queue. **Administration → Finance**: Products, Payments, Subscribers, Local products, Fee payments, Local members fees, Fee settings, Local online payments settings, Invoices. **Administration → Management**: Adhesions, Contacts, Badges, Resignation requests, Merge Records, Waitlist, Transfer requests, Queries, e-Documents, Forms, Local center settings, Companies, Settings. Home cannot be renamed, moved, hidden or permission-scoped. It is the fixed entry point. *** ## Adding your own links **Add new category** creates an empty category you can name, order, permission-scope and fill. **New link** on a category adds a custom entry. Two kinds: | Kind | You provide | Behaviour | | ----------------------- | --------------------------------------------------- | --------------------------------------------------------------------------------------------------- | | **Link** | A title and a **Full URL** | Opens that address | | **Discussion Category** | A title, a **Group**, and optionally a **Category** | Jumps straight into that group's discussions, filtered to the chosen category or **All categories** | Inline New link form on a menu category with the title field, the Link and Discussion Category radio options and the Full URL input Custom links carry the same permission and user type controls as built-in items, and can be renamed and re-iconed the same way. *** ## Previewing and resetting The **Desktop** and **Mobile** buttons at the top switch the preview. The mobile view is read-only: it shows the Community and Administration tabs as members see them, with the reminder that changes are made in Desktop mode. **Reset to defaults** reloads Orgo's standard menu. It asks for confirmation, then stages the reset like any other edit: nothing is applied until you press **save**, so you can navigate away to abandon it. Resetting discards every custom category, custom link, rename, icon change and permission restriction. There is no undo once saved. *** ## Troubleshooting Check, in order: the module it belongs to is still enabled under **Settings → Modules** (a disabled module hides its entries regardless of this page), the item is not hidden (greyed with a **+**), and its category's permission is not narrower than you intended. Both are generated categories, built from your live groups and projects. The editor never lists their contents, and the default menu marks them as not modifiable, so they show a padlock. Groups gets its own colour, emoji and category tools from the buttons on its header. Expected in normal mode: those Administration categories are managed by Orgo. Turn on **CRM Mode** if you need them in the editable list. The category above it is already restricted to a stronger permission. An item cannot be visible to a wider audience than its category. Loosen the category first. A rename here is a single piece of text used in every language. If you need per-language wording, use [Texts](/docs/platform/customization/labels) instead, which has a column per language. The organizer is a staging area. Every action, including Reset to defaults, only applies after **save**. *** ## Related * [Texts](/docs/platform/customization/labels) - per-language wording changes across the whole interface * [Modules](/docs/platform/organisation/modules) - what is available to put in the menu at all * [Permissions](/docs/platform/permissions) - what each permission actually unlocks * [Dashboard Organizer](/docs/platform/customization/dashboard-organizer) - the dashboard equivalent * [Customization](/docs/platform/customization) - everything under Settings → Customization # Blocking Members Source: https://orgo.space/docs/platform/discussion/blocking-members Hide the discussions, posts and replies of one member from your own view of the forum Blocking is the personal counterpart to moderation. A member who does not want to read another member stops seeing them, without anybody having to take the content down for the whole organization. A block is one way, private to the person who made it, and limited to Discussions. *** ## What a block hides Once you block someone, every discussion list you open leaves their content out. | Where | Effect | | ---------------------------------------------- | ------------------------------------------------------------------------------------------- | | Discussions feed, group and local center feeds | Threads they started disappear | | Dashboard discussion lists and widgets | Same | | Search box | Their threads no longer come back among discussion results | | Inside a thread | Their comments and replies disappear, everybody else's stay | | Paging | The list is filtered before it is counted, so page numbers and infinite scroll stay correct | Filtering happens on the server, so blocked content never reaches your browser. The same group feed, before and after one member is blocked. Two of the three threads were started by the blocked member and are simply gone; the third is untouched, and so is everyone else's view of all three. A committee group discussions feed showing three threads: Upcoming activities and events by Iris Vargas, Share your achievements by Freya Ashford, and Refreshing the member newsletter by Iris Vargas, each with reaction and comment counts The same committee group discussions feed after blocking Iris Vargas, now showing only the Share your achievements thread by Freya Ashford, with both of the blocked member's threads absent and no gap or placeholder where they were *** ## What a block does not do * **It does not restrict the blocked member.** They keep posting, commenting and replying, and their content is unchanged for everybody else. * **Nobody is told.** The member you blocked gets no notification and no marker on their posts, and no other member can see that the block exists. * **It does not empty a ticket queue.** Support tickets and issues are excluded from the list filtering on purpose, so a personal block never removes a ticket from a queue somebody works. Inside a ticket or an issue thread the block still applies, so comments by a blocked member are hidden from whoever blocked them. Bear that in mind before blocking anyone you also handle tickets with. See [Help Desk](/docs/platform/help-desk) and [Issues](/docs/platform/issues). * **It does not follow the member around Orgo.** They still appear in the member directory, in group lists, in events and in the event app. Blocking only filters the forum. * **It does not stop notifications.** If somebody you blocked replies to your post or mentions you, the notification still arrives, even though the comment itself is hidden when you open the thread. Two side effects are worth knowing. The comment count shown on a thread is a stored total, so it still counts the comments that are now hidden from you: a card can read "8 comments" while you see 6. And a block filters lists, not links, so a direct link to a thread started by somebody you blocked still opens that thread. *** ## Blocking a member The action lives inside a thread, not on the feed cards. On the post itself to block the person who started the thread, or on any comment or reply to block its author. A confirmation dialog explains that you will no longer see posts and comments written by this member. If you blocked the person who started the thread, you are returned to the discussions list, because there is nothing left on that page to show. Otherwise the comments reload without theirs. An open discussion thread with the three-dot menu expanded on the post itself, showing Block user listed alongside the other post actions The same action sits on every comment and reply, so you can block someone who never started a thread. The three-dot menu open on a single comment inside a discussion thread, showing Block user as one of the available actions for that comment's author The block confirmation dialog, explaining that after confirming you will no longer see posts and comments written by this member, with buttons to cancel or confirm the block **Block user** is only offered where it would work: never on your own content, and never on a member who cannot be blocked. It is also kept off the post that opens an issue, so an issue never disappears from a queue. The action is still offered on comments inside that thread, and those comments are filtered like any other. *** ## Lifting a block Then **Settings & Privacy**. The tab appears on your profile only, never on somebody else's. The panel lists everybody you have blocked, with the date you blocked them. Their discussions, comments and replies are visible again straight away. The Blocked users panel under Settings and Privacy on a member's own profile, listing each blocked member with the date the block was created and an Unblock control beside each row The list is also where a member checks whether a block is the reason somebody seems to have gone quiet. *** ## Who cannot be blocked Administrators are out of reach. The rule is Orgo's own permission ranking: anybody at or above `HR_LOCAL` cannot be blocked, and neither can a tenant admin. | Member | Can be blocked | | ----------------------------------------------------------------------------- | -------------- | | A member with no permissions | Yes | | `USER_LOCAL` | Yes | | `EVENT_LOCAL`, `COMMUNICATION_LOCAL`, `HR_ASSISTANT_LOCAL`, `FINANCIAL_LOCAL` | Yes | | `HR_LOCAL`, `ADMIN_LOCAL` | No | | Any `_PARENT_LOCAL` permission | No | | Any `_TENANT` permission, including `COMMUNICATION_TENANT` | No | | Tenant admins and super admins | No | A local center's discussion moderator holds `COMMUNICATION_LOCAL`, which ranks below the floor, so moderators can be blocked. The people who run the organization cannot. Blocking somebody before they are promoted does not keep them hidden. When a member is given `HR_LOCAL` or anything above it, every block against them is dropped as their permissions are recalculated, and their content comes back for everybody who had blocked them. Two more attempts are refused: blocking yourself, and blocking a member of another organization. *** ## How this differs from moderation | | Blocking | [Moderation](/docs/platform/discussion/moderation) | | ------------------- | ----------------------------------------- | ----------------------------------------------- | | Who it affects | Only the member who blocked | Everybody | | Who can do it | Any member | `COMMUNICATION_LOCAL` or `COMMUNICATION_TENANT` | | What it acts on | Everything one member writes | One post, comment or reply | | Is the author aware | No | Yes, the content is visibly held or hidden | | Who can undo it | The member who blocked | Any moderator for that scope | | Record kept | A private entry on the blocker's own list | The moderation queue and the audit log | Blocking is not a report. If content breaks your rules, it still has to be moderated or deleted, and blocking the author leaves it up for every other member. *** ## What administrators can see Nothing. There is no admin screen, no report and no export that lists who has blocked whom. Every member sees their own blocks and only their own, on their own profile. An administrator opening a member's profile does not get the tab, and asking the API for the block list returns the caller's own blocks even for a tenant admin. Because blocks are invisible to administrators, "that member stopped posting" and "her comments never show up for me" can both be self-inflicted. Ask the member to check **Settings & Privacy** and then **Blocked users** on their own profile before you investigate anything else. *** ## Common questions Have them open their own profile, then **Settings & Privacy** and **Blocked users**. If the person is on the list, **Unblock** restores everything they wrote, everywhere in the forum, immediately. No. Anybody ranked `HR_LOCAL` or above, and every tenant admin, cannot be blocked, and blocks made before somebody was promoted are dropped when the promotion takes effect. No. Blocking filters the forum only. A reply or a mention from a blocked member still produces a notification, and it still follows the member's notification settings. See [Notifications](/docs/platform/notifications). No. Support tickets and issues never disappear from a queue because of a personal block. Comments inside a ticket are a different matter: those are filtered like any other thread, so an agent who blocked a member will not see that member's replies on the ticket. No. There is no notification, nothing changes on their side, and they keep seeing the blocker's content as before. A block is one way. *** ## Related * [Discussions](/docs/platform/discussion) posting, comments and reactions * [Moderation](/docs/platform/discussion/moderation) the organization-wide way to take content down * [Permissions](/docs/platform/permissions) what the permission names above mean * [Privacy Settings](/docs/platform/users/privacy-settings) the other member-owned controls on the same profile screen * [Notifications](/docs/platform/notifications) what still reaches a member after a block # Discussion Namespaces Source: https://orgo.space/docs/platform/discussion/discussion-namespaces Organize discussions into categories so members can find and filter by topic Discussion namespaces, called **categories** everywhere in the interface, turn a flat feed into a browsable forum. Members pick a category when they post, and filter by it when they read. A category does two things a tag cannot: it can belong to a single group, and it can carry its own posting permission. Discussion Categories screen listing categories with their posting permission and rename and delete actions *** ## Turning categories on **Settings** and then **Discussions**, and switch on **Enable Discussion Namespaces** (on by default). A **Discussion Categories** entry appears under the module. *** ## Organization categories and group categories Where you create a category decides its scope, and there is no way to change that afterwards. | Created from | Scope | Effect | | ------------------------------------------------------------------------------------------------------------------- | ----------------- | --------------------------------------------- | | **Settings** and then **Discussions** and then **Discussion Categories**, or the gear icon on the organization feed | Organization-wide | Offered on posts that are not tied to a group | | The gear icon next to **All** while viewing a group, role group or local center | That group only | Offered inside that group only | A group category also decides where the post lands. When a member picks a category that belongs to a group, the new discussion is created in that group even if they started writing from somewhere else. Changing the category on an existing post does not move it. Group forum with the category panel listing All plus each of the group's categories, and the post list filtered to the selected category *** ## Managing categories Open the category manager with the gear icon next to **All** in the category panel, or from **Settings** and then **Discussions** and then **Discussion Categories**. Type a name into the **New category...** box and press Enter. New categories start with posting open to everyone. The people icon means anyone can post in the category. Select it to switch to the padlock, which restricts posting to admins and moderators. Select it again to reverse. The pencil icon edits the name in place. Existing posts keep the category, so they follow the new name. The bin icon removes the category. Only categories with no discussions in them can be removed, so move or delete those posts first. Categories cannot be reordered by hand. *** ## Who can manage categories The permission depends on where the category lives, and it matches the permission needed to moderate the same place. | Category scope | Required permission | | ---------------------------------------- | ------------------------------------------------------------------------- | | Organization-wide, or a role group forum | `COMMUNICATION_TENANT` | | A local center forum | `COMMUNICATION_LOCAL` for that local center | | A group | The group's owner, or a member whose role in the group is marked as admin | *** ## The "anyone can post" switch Each category carries its own posting permission, and in the organization-wide feed it can widen access rather than narrow it. A member who does not meet **Who Can Create Public Discussions** can still post in the organization feed if they choose a category set to "anyone can post". Leave that switch on the padlock for categories you want to keep as announcement channels. Inside a group the switch has no effect. Posting there is governed by the group's own **Who can post?** setting, so leave the category switch alone in group feeds. *** ## Tag groups inside a category A category can carry tag groups (topic types), each holding a fixed list of tags. When a category has them: * the composer shows one tag picker per group, so a post can be labelled along several axes at once * the sidebar shows one filter per group, plus text search, author and "my posts" filters for that category Tag groups have no setup screen. They are created through the API (`POST /topic_types`, then `POST /topics` for their values). Most organizations do not need them: free tags typed as `#hashtags` on a post already filter the feed. *** ## Common questions Only busy ones. A group with a handful of posts a month reads fine as a single feed. Add categories once members start scrolling past things they do not care about. Choosing one is optional, so posts stay uncategorized unless people are nudged. Keep the list short, name categories the way members already talk, and make sure admins categorize their own posts. Yes, by creating them organization-wide. They are then offered on posts that are not tied to a group. A group's own feed only offers that group's categories, so a shared set has to be recreated per group if you want it in group feeds too. The category still has discussions in it. Reassign or delete those discussions first, then delete the category. Yes. A filtered feed has its own address, `/discuss?category=` for the organization feed or `/discuss?unit=&category=` inside a group, so it can be added to the sidebar with the [Menu Organizer](/docs/platform/customization/menu-organizer). *** ## Related * [Discussions](/docs/platform/discussion) the feature overview * [Moderation](/docs/platform/discussion/moderation) holding and hiding posts * [Groups](/docs/platform/groups) where group categories live * [Menu Organizer](/docs/platform/customization/menu-organizer) pinning a category to the sidebar * [Permissions](/docs/platform/permissions) the permission levels used above # Discussions Source: https://orgo.space/docs/platform/discussion/index Forum-style posts and conversations within every group Discussions is Orgo's built-in forum. Members write posts, comment, reply, react and attach files, either in one shared organization-wide feed or inside a specific group, role group or local center. **Built for** membership organizations that want conversation spaces tied to their own group structure: youth organizations, professional associations, alumni networks and advocacy groups. **Replaces** Facebook Groups and standalone forums such as Discourse. It is not a chat tool: posts and comments are asynchronous, and everything is scoped by the group structure you already maintain in Orgo. Discussions feed with the Start a post composer, sort control, the category panel and post cards showing reaction and comment counts *** ## Where a discussion lives Every discussion is either organization-wide or attached to exactly one unit. Groups, role groups, local centers and organizational units are all units, so a discussion attaches to any of them the same way. | View | URL | What it shows | | ------------------------- | ------------------------ | --------------------------------------------------------------------------------- | | **Discussions** (default) | `/discuss` | Everything you can see: the organization-wide feed plus every group you belong to | | Organization feed | `/discuss?generalUnit=1` | Only posts that are not tied to a group | | One group | `/discuss?unit=` | Only that group, role group or local center | | One discussion | `/discuss/` | The post, its comments and replies | Visibility follows group membership: you see a discussion if it has no group, or if its group is one of yours (your local center, groups you hold a role in, groups that include all members, and open-access local centers when that setting is on). Administrators are not exempt, so a tenant admin does not see posts in groups they have not joined. Events do not have discussions. Event conversations live in the event feed inside the event app. *** ## Writing a post Select **Start a post** at the top of the feed, or the **+** button on mobile. | Field | What it does | | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Title** | Optional headline. Decorative Unicode (styled "bold" characters, full-width text) is folded back to plain letters on save. | | Body | Rich text with emoji, inline `@mentions` (up to 50 per post) and automatic link previews when you paste a URL | | **Category** | Puts the post in a category. Picking a category that belongs to a group also posts it into that group. See [Discussion Categories](/docs/platform/discussion/discussion-namespaces). | | Tags | Extra tag pickers, shown only when the selected category has tag groups configured | | **Posting in** | Where the post goes. Locked to the current group when you open the composer from inside one. | | Comment toggle | The speech-bubble icon in the composer footer disables comments on the post | Images, videos and files can be attached with the image, video and folder icons, or by dragging them onto the composer. One selection must stay under 1 GB in total. *** ## Reading and taking part A single discussion showing its category and group chips, attached image, reaction count and comment count **Reactions.** Four reactions are available on a post or any comment: Like, Love, Celebrate and Informative. You hold one at a time. Hovering a reaction shows the first 20 people who used it, and selecting it opens the full list. **Comments and replies.** Comments appear oldest first. Every comment can be replied to, and replies can themselves be replied to, so threads nest as deep as the conversation goes. Long threads can be collapsed. Comments carry the same rich text, mentions and attachments as posts. Comment thread with several members replying, each comment offering Like and Reply, a nested reply under one of them, and a Write a comment box at the bottom **Counts.** The footer of a post shows its reactions and its comment count. Views are recorded too, as unique viewers with the author's own visits excluded, and they are shown on the discussion cards in the dashboard rather than in the feed. **Following.** Creating a discussion or commenting on one follows it automatically. **Subscribe** and **Subscribed** on the discussion page turn following on and off by hand. *** ## Who can post where | Where | Rule | | ----------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Organization feed | The **Who Can Create Public Discussions** setting (default: All Users). Members below that level can still post in a category set to "Anyone can post". | | A group, role group or local center | Anyone with access to it. If the group's **Who can post?** is set to **Only admins**, the composer is offered to group admins and holders of `HR_TENANT` only. | | Editing a post | The author. A moderator can hide it, and a local or tenant admin can delete it. | | Deleting a discussion or comment | The author, an `ADMIN_LOCAL` of the group, or `ADMIN_TENANT` for organization-wide posts. Deleting somebody else's content is written to the audit log. | Deleting a comment that already has visible replies keeps the thread: the comment's text and attachments are cleared, and the replies stay. *** ## Finding things The sort control offers **newest**, **oldest**, **most commented** and **least commented**, and the icon next to it switches between the card view and a compact list. Categories appear as a panel beside the feed on desktop and as tabs on mobile. Selecting a `#tag` under a post filters the feed to that tag. Feeds load more posts as you scroll. *** ## Notifications Followers are notified when a new comment is added, the author of a comment is notified of replies to it, and mentioned members are notified of the mention. Whether each one also arrives by email depends on the member's own settings and on the organization default **Email Notifications: Discussions**. See [Notifications](/docs/platform/notifications). *** ## Settings Discussions module settings with the module toggle, Who Can Create Public Discussions, Enable Discussion Namespaces and Enable Profanity Check **Settings** and then **Discussions**. Changing these requires `ADMIN_TENANT`. | Setting | What it does | Default | | ------------------------------------- | -------------------------------------------------------------------------------------------------------- | --------- | | **Enable Discussions Module** | Turns the whole feature on or off | On | | **Who Can Create Public Discussions** | Permission needed to post in the organization-wide feed | All Users | | **Enable Discussion Namespaces** | Turns on categories and the Discussion Categories screen | On | | **Enable Profanity Check** | Holds posts containing blocked words for a moderator. See [Moderation](/docs/platform/discussion/moderation). | Off | *** ## Common questions Set **Who Can Create Public Discussions** to an admin level. The feed becomes an announcement channel, while members keep posting in their groups and local centers. Comments stay open either way, unless the author disables them on a specific post. Discussions attached to a group are visible only to that group's members, and administrators get no exemption. Check which group the post is in, then check whether the member belongs to it. If the group checks out, have them look at [Blocking Members](/docs/platform/discussion/blocking-members): a member they blocked is hidden from them everywhere in the forum, and only they can see that list. Yes, at any time. If the post is a comment with replies underneath, the text and attachments are removed and the thread structure stays so the replies still read. Discussions are two-way and live in the app. The [newsletter](/docs/platform/newsletter) is a one-way email campaign. Use discussions for conversation, newsletters for announcements that must reach an inbox. *** ## Related * [Discussion Categories](/docs/platform/discussion/discussion-namespaces) organize posts by topic * [Moderation](/docs/platform/discussion/moderation) hold, review and hide posts * [Blocking Members](/docs/platform/discussion/blocking-members) how a member hides one other member's content for themselves * [Groups](/docs/platform/groups) where group discussions live * [Notifications](/docs/platform/notifications) what reaches a member and how * [Permissions](/docs/platform/permissions) the permission levels used above # Discussion Moderation Source: https://orgo.space/docs/platform/discussion/moderation Hold posts for review, work the moderation queue and hide published content Orgo gives moderators three separate tools for discussion content: a word filter that holds posts before anyone sees them, a queue for reviewing what it held, and a hide action for content that is already published. **Built for** organizations whose forums are open to members without prior approval, where something occasionally has to be caught or taken down. **Replaces** the manual "someone emailed me a screenshot" routine, and third-party forum moderation add-ons. *** ## Who moderates what Moderation rights follow the same routing as the rest of discussions: where the post sits decides who can act on it. | Where the post is | Who moderates it | | ------------------------------------ | ----------------------------------------------------------------------------------- | | Organization feed (no group) | `COMMUNICATION_TENANT` | | A public group (members can join it) | `COMMUNICATION_TENANT` | | A role group forum | `COMMUNICATION_TENANT` | | A local center forum | `COMMUNICATION_LOCAL` for that local center. `COMMUNICATION_TENANT` also covers it. | | A private group | Nobody. Private group posts are never filtered and never appear in a queue. | Local moderators only ever see their own local center's held posts, never another center's. *** ## Holding posts with the word filter Discussions module settings with the module toggle, Who Can Create Public Discussions, Enable Discussion Namespaces and Enable Profanity Check **Settings** and then **Discussions**, and switch on **Enable Profanity Check**. It is off by default, and only `ADMIN_TENANT` can change it. Once on, the filter runs on the title and body of every new discussion, every comment, every reply and every edit of one. If it matches, the post is held before it becomes visible. | Detail | Behaviour | | ------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Word list | A built-in English list, plus any custom words you add | | Matching | Words of four letters or more also match inside a longer word. Short words, and words that occur inside innocent ones, match whole words only, so "class" does not trip on "ass". | | Accents | Folded before matching, so "fück" matches "fuck" | | Custom words | Up to 500, added in the moderation queue screen and editable by `ADMIN_TENANT` only | Matching runs inside Orgo against a word list. No post content is sent to any external service. ### What the author sees The post saves, and a message says it was flagged for review and will not be visible until a moderator approves it. Nothing else changes for them: they can still edit it, and editing out the flagged words releases the post immediately, without a moderator. That self-release does not apply once a moderator has rejected the post. ### What everyone else sees Nothing. A held post is hidden from the feed, from comment threads, from its direct link and from the API, for every member including the author. Notifications that would have gone out (followers, mentions, replies) are held back and sent only if the post is approved. *** ## The moderation queue Moderation queue with a Pending review table showing the post text, flagged words, author and group with Approve and Reject buttons, a Rejected posts table below, and the custom blocked words editor The queue is at `/discuss/moderation-queue`. Two things link to it: a **Moderation queue** entry appears in the **COMMUNICATION** section of the Administration sidebar once the profanity check is on, and on a local center a **Moderation queue** button with a pending count appears in the header next to Info. The screen has two tables: * **Pending review**: everything waiting for a decision, newest first. Each row shows the discussion title, the post text (with **Show more** for long ones), the words that were flagged, the author and the group, plus **Approve** and **Reject**. * **Rejected posts**: the audit trail, showing who rejected each post and the reason. You only ever see posts you are allowed to act on, so the two tables are already scoped to your groups and centers. | Action | Effect | | ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Approve** | The post becomes visible, the comment count is recalculated, and the notifications held back while it waited are sent. Your name and the time are recorded. | | **Reject** | The post stays hidden permanently and moves to the rejected table. You are asked for a reason, which is stored with the record. | Approving a rejected post reverses the rejection. Below the tables, `ADMIN_TENANT` holders manage the **Custom blocked words** list. It is a single organization-wide list, so one edit changes what gets held everywhere. Moderators can work the queue without being able to change it. ### Being told about a hold When a post is held, every moderator for that scope gets an in-app notification linking to the queue, and an email. The author is never alerted about their own held post. Email is capped at 50 moderators per held post; anyone past that still gets the in-app notification and the queue badge. *** ## Hiding a published post The word filter only catches what it knows. For anything already published, open the post or the comment, then use the three-dot menu. | Action | Who | Effect | | --------------------- | ------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Moderate** | `COMMUNICATION_LOCAL` on the discussion, and not on your own post | Hides the text and any attachments. The discussion shows "Moderated discussion", the comment count drops, and the action is written to the audit log with the original content. | | **Remove moderation** | Same permission | Restores the post and its count | | **Delete** | The author, an `ADMIN_LOCAL` of the group, or `ADMIN_TENANT` on the organization feed | Removes it. Deleting someone else's content is logged. | Hiding is reversible and keeps the evidence. Prefer it to deletion when a decision might be challenged later. *** ## Member reports Any member can use **Report** on a post or comment that is not their own. The report is recorded against the post, once per member. Reporting does not hide the post, does not notify anyone, and does not create a queue entry. Reported content still has to be found and hidden by a moderator, so tell members to flag anything urgent to an admin directly. A member who simply does not want to read another member does not need a moderator at all. See [Blocking Members](/docs/platform/discussion/blocking-members), which hides one member's content for one other member and leaves it up for everybody else. *** ## Common questions Check the moderation queue. If the word filter is on, the post is held and invisible to everyone, including its author, until it is approved. The author can also release it themselves by editing out the flagged word. Words of four letters or more match inside longer words, which is what usually causes it. You cannot remove entries from the built-in list, so if a specific term keeps misfiring, turn the check off for a while and rely on Moderate, or keep the check on and work the queue. The sidebar entry needs `COMMUNICATION_TENANT` and only appears once **Enable Profanity Check** is on, and the header button only appears in a local center. Open `/discuss/moderation-queue` directly if you have neither. If both tables are empty, either there is nothing held or you do not hold moderation rights for any group with held posts. By design. Private groups are excluded from the filter entirely, so their posts publish straight away and no one can moderate them from the queue. Group admins can still delete content there. *** ## Related * [Discussions](/docs/platform/discussion) posting, comments and reactions * [Discussion Categories](/docs/platform/discussion/discussion-namespaces) category scope and posting permissions * [Permissions](/docs/platform/permissions) what `COMMUNICATION_TENANT` and `COMMUNICATION_LOCAL` cover * [Notifications](/docs/platform/notifications) how moderators are alerted * [Groups](/docs/platform/groups) public, private and role groups # E-Document Records and Legal Weight Source: https://orgo.space/docs/platform/e-documents Exactly what Orgo captures when someone signs, where it is stored, how long a signed document stays valid, and what that evidence is worth This page describes the record Orgo creates when an [e-document](/docs/platform/contracts) is signed: what a signature technically is, what is stored alongside it, and what is not. Read it before you rely on Orgo signatures for anything with legal weight. **Built for** administrators and legal or compliance staff who need to know what evidence a signed document actually carries. **Replaces** guessing at what your e-signature tool records. *** ## What a signature is A signature in Orgo is an image, not a cryptographic operation. * **Sign by finger on screen.** The signer draws in a box on the page. The drawing is exported from the browser as a PNG image and uploaded. * **Sign by file upload.** The signer uploads a file (typically a scan or photo of a signed page). The file is stored as-is and becomes the document of record. No PDF is generated for this path. There is no certificate, no key pair, no cryptographic hash of the document content, and no third-party timestamping authority. *** ## What is stored when someone signs on screen | Recorded | Detail | | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | | Signature image | The PNG drawn by the signer | | Signer identity | The member or contact record the document was assigned to | | Signing date | The calendar date, in your organization's configured timezone. The time of day is **not** stored | | Document text | A frozen copy of the template body, taken when the document was created, so later edits to the template do not change what was signed | | Filled-in values | A snapshot of every placeholder and the value it resolved to at the moment of signing | | Document number | A whole number, unique and sequential within your organization, assigned at signing and available as `{autoContractNumber}` | | Validity dates | Start and end of the period the document covers | | Rendered PDF | The document text with the values and signature images merged, generated at signing | | Administrator signature | If the template requires a countersignature, the admin's signature image and the date it was applied | | Log entry | A row in the audit log linked to the document, recording the resulting status and the placeholder snapshot | Orgo does **not** record the signer's IP address, browser, device, or location with an e-document signature, and there is no field anywhere in the record for them. If your jurisdiction or your counterparty requires that evidence, Orgo signatures alone will not supply it. *** ## Three ways a document reaches "Signed" Only the first is an e-signature. The other two are administrative records, and the difference matters if the document is ever challenged. | Path | What it stores | | -------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- | | The signer draws a signature | Everything in the table above | | The signer uploads a file | The uploaded file, the signing date, and a lock on the record. No signature image, no placeholder snapshot, no generated PDF | | An admin uses **Mark as signed** | Status, validity dates, the date the admin chose as the signing date, and which admin did it. No signature of any kind | **Sign with default signature** and **Pre-sign with default signature** apply one reusable image stored on the template as the administrator's countersignature. The same image is reused on every document, so it evidences that the template was approved for countersigning, not that a named person reviewed that individual document. *** ## Where the files live Signature images and generated PDFs are stored in Orgo's object storage in a private bucket, never on a public address. Links to them are signed on demand and **expire after 15 minutes**, so a PDF link copied out of the admin screen stops working shortly afterwards. Download the file rather than sharing the link. The one exception is the reusable administrator signature stored on a template. It is served from a stable public address so it does not break inside older generated PDFs. A signed PDF can also be regenerated on demand from the frozen document text, the stored values, and the signature images. That is what **Download PDF** on a history entry does, and it is why a signed document from years ago still renders correctly after the template has moved on. *** ## Validity, expiry and renewal A template with **Infinite contract duration** produces documents that never expire. Otherwise validity runs from the signing date for the configured number of months, unless the admin set custom dates when sending it. * A nightly job flips signed documents to **Expired** the day after their validity end date. * Members are emailed **30 days before**, **7 days before**, **on the day**, and **7 days after** the validity end date. Reminders go to members only, not to contacts, and only for the most recent signed copy of each document. * A member may re-sign early, but only inside a **60 day window** before the current document expires. Attempting it sooner returns the date on which re-signing opens. * When someone re-signs inside that window, the new document starts on the day the old one ends rather than today, so the two periods run back to back with no gap. Re-signing after expiry starts from today. *** ## Ending a signed document | Action | Who | Effect | | ---------------------------------------------- | -------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Revoke** on a signed document | `HR_TENANT`, and only when the template has **Enable signature cancellation** on | Deletes the document record | | **Delete** on a pending document | `HR_TENANT`, or the person it was assigned to | Deletes the document record | | **Cancel all signed** on a template | `ADMIN_TENANT` | Marks every outstanding document from that template as cancelled, records who cancelled it and when, and regenerates the template's identifier so everyone is asked to sign again | | Signing again outside the renewal window rules | The signer | The previous document is marked cancelled with the signer recorded as the canceller, and a new one is created | Cancelled documents stay in the member's history with a **Canceled** tag, the name of who cancelled them, and the date. Deleted documents are removed. *** ## Retention and export Signed documents are kept for as long as the member record exists; there is no automatic purge of signed e-documents. Public signing links are the exception: they are removed 72 hours after they are created. Individual PDFs are downloaded from the document row, the side panel, or the member's own E-Documents tab. To take every signed PDF for one template at once, ask Orgo support: there is an operator command that regenerates and exports them in bulk. *** ## Are these signatures legally binding? That depends entirely on your jurisdiction and on the document. Use the facts above rather than a general assurance: * Orgo records who signed, on what calendar date, exactly what text they saw, and an image of the mark they drew. * Orgo does not record the time of day, the IP address, the device, or any cryptographic proof that the stored PDF has not been altered since. In many jurisdictions that is enough for a simple electronic signature on routine internal agreements, and not enough for an advanced or qualified electronic signature. For anything where the answer matters, take this page to your legal counsel before deciding. *** ## Related * [E-Document Templates and Signing](/docs/platform/contracts) - templates, sending, signing and tracking * [Identity Validation](/docs/platform/identity-validation) - verifying who a member actually is * [Privacy Settings](/docs/platform/users/privacy-settings) - what member data is visible and to whom * [Files](/docs/platform/files) - general document storage and share links * [Permissions](/docs/platform/permissions) - what `HR_TENANT` and `ADMIN_TENANT` unlock # E-Voting Source: https://orgo.space/docs/platform/e-voting Run elections, motions and polls with timed ballots, anonymous or attributed voting, and live results Orgo E-Voting runs elections, motions and polls on a timed ballot, with one vote per person and results the whole organisation can watch. **Built for** organisations that hold statutory elections or democratic votes, including professional associations, trade unions, political parties, cooperatives and other member-governed bodies. **Replaces** paper ballots and show-of-hands counts at general assemblies. It does not interpret your bylaws: Orgo reports raw counts and percentages, and has no quorum or majority threshold setting. Voting list showing live, draft, upcoming and finished votes with question count, target group and a turnout bar per vote E-Voting is a module. Turn it on at **Settings → Modules → Voting → Enable Voting Module**. It is on by default for new organisations. When it is off, the Voting entry disappears from the sidebar and the mobile tab bar. *** ## Creating a vote Open **Voting** and select **Create Voting**, shown to members with `ADMIN_TENANT` or `HR_TENANT`. Create Voting modal with the question builder filled in, the single and multiple answer toggle, start and end dates with timezone, the audience cards and all three settings switches A question needs at least one option; options can be added, deleted and dragged into order. **Single answer** shows radio buttons and accepts exactly one option. **Multiple answers** shows checkboxes and accepts any number, but at least one. **Add another question** makes it a multi-question ballot, one question per board seat for example. Voters answer every question in one submission; a partial ballot is rejected. Two or more questions also require a vote title, which becomes its name in the list. Start and end dates are optional and carry a timezone you pick per vote. With no start date voting opens on publish; with no end date it stays open until every eligible voter has voted or an administrator closes it. Pick the audience, then **Save draft** to keep it hidden, or **Publish** to make it live or upcoming and notify voters. *** ## Who can vote The **Who is voting?** cards set eligibility. | Audience | Who is eligible | | ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Group vote** | Everyone in the selected group. With no group selected, every active member of the organisation. For a local group, its members. For a role group, everyone bound to it. For a regular group, everyone with a role in it that has not ended. | | **Private vote** | Only the members the vote creator adds by name. The creator is added automatically when the vote is created. | | **Event attendees** | Set automatically when you start the vote from an event. Eligible attendees are those invited or fully registered, and not cancelled. Pending approval, waiting list and awaiting payment are excluded. | On a private vote only the creator can add or remove voters, using the member search in the Participation panel and only while the vote is still editable. A voter who has already cast a ballot cannot be removed. *** ## Settings | Setting | What it controls | | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | **Real-time results** | Voters see running totals while voting is live. Off means results appear only after the vote closes. | | **Hide voters list** | Hides who has and has not voted from ordinary voters; `HR_LOCAL` on the vote's group and above still see it. Leave it off and every eligible voter sees the roster and each person's voted or pending state. | | **Anonymous voting** | On by default. See [Anonymity](#anonymity-and-integrity). Changeable only while the vote is an unpublished draft with no ballots cast. | *** ## Lifecycle | Status | What is happening | | ------------ | ---------------------------------------------------------------------------------------------------------------- | | **Draft** | Being set up. Not visible to voters, not shareable. | | **Upcoming** | Published with a start date in the future. Voters see the questions and options but cannot answer yet. | | **Live** | Voting is open. | | **Finished** | The end date has passed, an administrator closed the vote, or every eligible voter has voted. Results are final. | A vote is editable only while it has no ballots and is neither live nor finished, so questions and options can still be corrected during **Upcoming**. Once it goes live the question builder is locked, dates included. **Close voting** appears only on a live vote with no end date, and only for people who can manage it; a vote with an end date runs until that moment. **Archive**, offered once a vote is finished, hides it from the default list; the **Archived** checkbox above the list brings archived votes back. **Duplicate** copies the questions, options and, on a private vote, the eligible voters into a new draft named "Copy ..." with no results and a fresh one-hour window that you then adjust. A published vote cannot be reverted to draft, and questions cannot be edited once it is live. If you find a serious mistake, close the vote and duplicate it into a corrected one. *** ## Voting and results Live vote showing the three question ballot with radio options, the Vote now button, and the participation panel with turnout percentage and the voter roster An eligible member answers every question and selects **Vote now**. The confirmation panel offers an **Integrity verification** code to copy and keep. Voting twice is refused. The Participation panel shows turnout as a percentage plus Voted, Pending and Eligible counts, and the roster below it lists every eligible voter with their Voted or Pending state. The three counts double as filters, so clicking **Pending** narrows the roster to the people who have not answered yet. Orgo sends no voting reminders, so use that list to follow up through a [newsletter](/docs/platform/newsletter) or a message. Results are bars with the count and percentage per option, per question, including options with zero votes. Percentages are shares of the answers recorded for that question, so a multiple-answer question divides them across selections rather than per voter. They appear once the vote closes, or immediately if **Real-time results** is on; live pages update as ballots arrive and **Refresh** forces a reload. **Fullscreen** presents the results with your organisation's logo, for a projector at a general assembly. Finished two question funding vote showing per-option result bars with counts and percentages next to the participation panel On a finished vote the actions menu offers two CSV downloads: * **Export results**: on an anonymous vote, one row per recorded answer with the question, the answer and that ballot's integrity seal, and no voter names. On a non-anonymous vote the same button downloads the per-voter file instead. * **Export voter list**: one row per eligible voter with name, email and a yes or no for having voted, plus a company column when the Companies module is on. Offered on anonymous votes. *** ## Anonymity and integrity **Anonymous voting on** (the default): a ballot is stored with no reference to the person who cast it and no linking record is written anywhere. Administrators see who voted, never what they chose. This is structural rather than a display rule: the storage that would hold the voter's identity is never populated. **Anonymous voting off**: each ballot is linked to its voter, who is warned of that on the ballot before answering. After the vote closes, people who can manage it get an **Individual results** panel listing each voter with their answers, and **Export results** downloads a per-voter CSV with one column per question. The panel shows up to 500 voters; the CSV holds all of them. The setting freezes once the vote is published or the first ballot is cast, so a vote presented as secret can never be opened up afterwards, and the reverse is blocked too. Ballots cast from the [Event App](/docs/platform/events/event-app) voting tab are recorded without the voter link, even on a vote configured as non-anonymous. Those ballots count in the totals but do not appear in Individual results or the per-voter export. Run non-anonymous votes on the main member app. ### The integrity code Voting in the member app returns an integrity code, shown once in the confirmation panel. Paste it into **Integrity verification** in the vote's actions menu and Orgo confirms whether the tally recorded when that ballot was counted still matches the stored ballots. Integrity verification page with the validation code field and the Validate button A code that validates means no ballot recorded at or before that point was altered, deleted or inserted afterwards. It carries no identity and does not reveal which option was chosen: it is tamper evidence on the stored ballots, not a signature from an external authority. Codes are issued only in the member app; the Event App and the emailed link for non-member attendees do not return one. Orgo records who has voted and when each ballot was stored. In a very small electorate, anyone watching the live participation roster can narrow down who cast what by timing alone. That is inherent to showing live turnout; turn on **Hide voters list** if it matters for your vote. *** ## Event votes, sharing and notifications Start a vote from an event and it is bound to that event's attendees for its whole life. Attaching it requires you to be the event owner or to hold `EVENT_LOCAL` on the event. Published event votes appear on a **Votes** tab on the event page and in the [Event App](/docs/platform/events/event-app), where attendees answer on their phone. Non-member attendees invited as contacts get an emailed link to a public voting page. **Share** in the actions menu mints a stable link and QR code that you can show fullscreen for a room to scan. It appears only while the vote is live, and only for people who can manage it; draft votes cannot be shared. The link routes to the vote page, or to the Event App for an event vote, and asks anyone not signed in to log in first. It does not grant eligibility: the rules above still decide who may vote. Publishing a vote sends a notification: to the listed voters on a private vote, to the attendees on an event vote, and to the organisation or the selected group's audience on a group vote. Closing a vote sends a second one. Each reaches the member in the app, and by email when that member's **Voting / Polls** preference is set to Instant. The organisation default for new members is **Email Notifications: Votes** under Notification Defaults. See [Notifications](/docs/platform/notifications). *** ## Permissions | Action | Who | | --------------------------------------------------- | -------------------------------------------------------------------------------------- | | See the Voting section and vote | Any member who is eligible for the vote | | Create a vote | `ADMIN_TENANT`, `HR_TENANT` | | Edit, publish, close, archive, duplicate, export | `ADMIN_TENANT`, the vote's creator, or `HR_LOCAL` on the vote's group | | Add or remove voters on a private vote | The vote's creator | | See the voters list when **Hide voters list** is on | `HR_LOCAL` on the vote's group and above | | See Individual results on a non-anonymous vote | `ADMIN_TENANT`, the vote's creator, or `HR_LOCAL` on the vote's group, after it closes | | Attach a vote to an event | The event owner, or `EVENT_LOCAL` on the event | | Turn the module on or off | `ADMIN_TENANT` | See [Permissions](/docs/platform/permissions) for what each level means. *** ## Common questions Check the audience: on a group vote they must be in the group with an active role, on a private vote on the voter list, on an event vote invited or fully registered and not cancelled. Then check the status: an upcoming vote refuses ballots, and a member who already voted sees their own answers instead of the ballot. A vote also closes once the number of ballots equals the number of eligible voters. On a group vote that count is recalculated live, so it moves as members join or leave the group. You cannot. Close it, use **Duplicate**, correct the copy and publish that, telling voters why. No. Orgo has no quorum or threshold setting. It reports counts and percentages, and your organisation applies its own rule and records the outcome. Someone probably archived it. Tick **Archived** above the list to see archived votes. *** ## Related * [Events](/docs/platform/events) for attaching a vote to a general assembly or conference * [Event App](/docs/platform/events/event-app) for in-event voting on a phone * [Groups](/docs/platform/groups) for the groups a vote can be scoped to * [Notifications](/docs/platform/notifications) for how members are told a vote opened * [Permissions](/docs/platform/permissions) for the roles named on this page # Email lists Source: https://orgo.space/docs/platform/emails/email-lists Reusable audiences for campaigns: how lists behave when an email is actually sent, and what feeds them An email list is a saved audience: the people a campaign goes to. This page covers what a list does once email starts moving. For building one, criterion by criterion, see [Lists & Segments](/docs/platform/users/lists). **Built for** organisations sending to part of their base rather than all of it. **Replaces** pasting addresses into a mail client. Lists live at **Administration** → **Communication** → **Lists & Segments** (`/email-lists`). Creating, editing and deleting a list needs HR\_TENANT or COMMUNICATION\_TENANT. Adding or removing an individual person from a manual list needs ADMIN\_TENANT. *** ## Two kinds, one difference that matters for email An **automated** list is a set of criteria. A **manual** list is a fixed set of people. For email the difference is timing. An automated list is evaluated again at the moment the campaign is sent, not when you drafted it, so anyone who became eligible in between is included and anyone who no longer qualifies is dropped. A manual list sends to the rows in it, less two subtractions: anyone who is not subscribed, and anyone whose member account has since been merged away or deleted. Nothing is ever added to it. That makes automated lists the right choice for anything recurring ("members who have not paid") and manual lists the right choice for anything deliberate ("the twelve people going to the retreat"). *** ## Subscribed is not the same as in the list Every member and contact carries a subscription state for email. A list shows both numbers: the total and how many of those are **Subscribed**. Campaigns only reach subscribed people. A list of 900 with 620 subscribed sends to 620\. The count shown next to **From a list** when you pick a newsletter audience is the subscribed count, which is why it is often lower than the list total you were expecting. Unsubscribing is the member's decision and lists do not override it. Removing someone from a list does not unsubscribe them, and unsubscribing does not remove them from any list: the two are independent. System emails ignore lists entirely. A renewal reminder goes to the member whose fee is expiring, whether or not they are in any list and whether or not they have unsubscribed from campaigns. Unsubscribing stops marketing, not the messages about someone's own membership. See [System emails](/docs/platform/emails/system-emails). *** ## Where a list gets used In the newsletter composer, choose **From a list** and pick it. This is the main use. See [Newsletter](/docs/platform/newsletter). A data import can add everyone in the file to a manual list as it runs, which is the fastest way to turn a spreadsheet into an audience. Only manual lists can be picked: an automated list decides its own membership, so Orgo refuses the import rather than silently ignoring it. See [Importing data](/docs/platform/customization/import). Ask Orgo can propose a list from a plain-language question and save it as a real list you can then send to. See [Insights](/docs/platform/insights). *** ## Adding people to a manual list Three ways in: **Add** searches members and contacts by name, **Add CSV** takes a file of addresses, and an import can populate the list as part of a larger job. Adding someone who is already in the list is safe. The existing entry is kept and the row is reported as skipped, rather than failing. This matters more than it sounds: the add dialog only knows about the page of members it has loaded, so on a long list you will regularly try to add someone twice without realising. Removing someone deletes their place in the list and nothing else. Their profile, history and subscription state are untouched. *** ## Local centre boundaries If a newsletter belongs to a local centre, that centre's boundary is applied on top of the list. A list containing people from three centres, used by one centre's newsletter, reaches only that centre's people. A list cannot be used to reach past a boundary that the sender does not have. *** ## Troubleshooting Open the list and compare **Total** with **Subscribed**. The gap is everyone without an explicit opt-in: people who unsubscribed, and people who never made a choice. On an automated list the subscription chips on the recipients table show exactly who was skipped. A manual list has no such chips, so use the [email log](/docs/platform/emails/email-log) to see who actually received the campaign, or open the individual records. Check the list's member status setting. Automated lists default to active members only, so lapsed members drop out of them silently. That one setting can still be changed after the list is created. You cannot: the type is fixed when the list is created. Create a new automated list with the criteria you want and retire the old one. Check [Email logs](/docs/platform/emails/email-log) for what they actually received. If it is a system email (renewal, invoice, event confirmation) that is expected: unsubscribing only stops campaigns. *** ## Related * [Lists & Segments](/docs/platform/users/lists) - building a list and the full criteria reference * [Newsletter](/docs/platform/newsletter) - choosing a list as a campaign audience * [System emails](/docs/platform/emails/system-emails) - the email lists do not control * [Contacts](/docs/platform/contacts) - non-member people who can be in a list * [Email logs](/docs/platform/emails/email-log) - proving what a given person received # Email logs Source: https://orgo.space/docs/platform/emails/email-log A record of every email Orgo sent, with the exact body, for answering "the member never got it" The email log answers one question well: did we send it, and what did it say. Most email the platform sends is recorded with its recipient, subject, time and, where available, the exact rendered body. Two gaps are worth knowing before you rely on the log as proof: notification email (discussions, comments, mentions, events, votes) is logged as **Transactional email** with the subject only and no body; and a handful of emails are produced outside the logging path and leave no row at all, among them the fee payment approval, the newsletter signup confirmation, waitlist messages, family invitations, the vote seal and the discussion digest. **Built for** whoever fields "I never got the renewal reminder". **Replaces** taking the member's word for it, or your own. The log is at **Administration** → **Email logs** (`/email-log`) and needs ADMIN\_TENANT. It is also embedded in two places where you are more likely to want it: a member profile has a **Logs** tab with an **Email Logs** view, and a contact record shows an **Email logs** card. Email logs list with a recipient search box and a table of ID, sent date, member, subject and type *** ## Reading the list Newest first, twenty per page. Each row shows: | Column | What it is | | ------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **ID** | The log entry number, and the link to the full entry | | **Sent date** | When Orgo handed the message to the mail service | | **Member** | The member, contact or company it went to, linked to their record. When the address matches nobody, the address itself is shown | | **Subject** | The subject line as sent, with placeholders already filled in | | **Type** | Which kind of email it was. Only the labelled kinds carry a tag: welcome, the four membership fee reminders, the two subscription renewal results, transactional email, newsletter, and admin notification. Everything else is logged with its own internal type and leaves this column blank, so a blank Type is normal for most system mail | **Search by recipient** at the top finds a member or contact and filters the list to them. ID, sent date and type are sortable. *** ## Reading one entry Opening an entry shows the recipient, the subject, the sent date, the type, and **Email Preview**: the message body exactly as it was rendered for that person, with their name, dates and links already substituted. Rows tagged **Transactional email** that came from a notification (a discussion, comment, mention, event or vote alert) store the subject only, so their preview is empty. Everything else stores the full body. Email log entry showing recipient, subject, sent date and type cards above a rendered preview of the email body This is the part that settles arguments. If a member says the payment link did not work, you can see the link that was in their copy. *** ## Answering "the member never got it" Search by recipient, or open their profile and use the **Logs** tab. Working from the profile is usually faster and avoids picking the wrong person. Usually Orgo did not send it: either the email is switched off (check [Emails Config](/docs/platform/emails/system-emails)) or the thing that triggers it did not happen. Check first that the email is one Orgo logs. Waitlist messages, family invitations, the fee payment approval, the newsletter signup confirmation and the discussion digest are never written to the log, so their absence here is normal. Orgo handed it to the mail service. Check the address on the row: an old address, a typo, or a placeholder address left by a data import all produce a row that was never going to arrive. If a whole day's mail is missing for everybody rather than for one member, it is not the address: tell Orgo support, because the row records the handover and not the delivery. It is a delivery problem, not an Orgo problem. Ask them to check spam and quarantine, and check whether their employer's mail filter is involved. The message was queued but could not be delivered after repeated attempts, and the entry records why instead of the body. Usually the address is invalid. *** ## What the log does not tell you The log is a record of sending, not of delivery. It has no opened, clicked, bounced or delivered status. Those exist only for newsletter campaigns, where they are shown as campaign statistics: see [Newsletter](/docs/platform/newsletter). Two more gaps worth knowing: * **Login and multi-factor codes are not logged.** Nothing at all is written for them. Other one-time codes (email verification, password reset, password change, email change, event app sign-in) do get a row, but with the code removed from the subject and no body stored, so nobody with access to the log can use it to get into a member's account. * **Deleting a member deletes their email history.** Log entries are attached to the member or contact record and go with it. Export anything you need to keep before deleting an account. *** ## Newsletters in the log Campaign sends appear here too, one entry per recipient, tagged as **Newsletter** and linked to the campaign that produced them. So a member who says they received a campaign they should not have appears in the log with the campaign named. *** ## Retention Orgo does not expire log entries on a schedule: they stay until the person they belong to is deleted. On a large organisation the log grows to millions of rows, which is why it always opens filtered to a page rather than counted in full. The log stores the full body of most emails, which means it holds personal data: names, addresses, amounts, membership dates. It is restricted to ADMIN\_TENANT for that reason. Take that into account in your data retention policy. *** ## Related * [System emails](/docs/platform/emails/system-emails) - what should have been sent, and its switch * [Email templates](/docs/platform/emails/email-templates) - changing what a message says * [Emails](/docs/platform/emails) - sender identity and deliverability * [Newsletter](/docs/platform/newsletter) - campaign statistics, including opens and clicks * [Users & Profiles](/docs/platform/users) - the profile Logs tab # Email templates Source: https://orgo.space/docs/platform/emails/email-templates Rewrite the subject and body of an automatic email, insert placeholders, preview it and send yourself a test Every automatic email ships with a written-for-you version. When that version does not sound like your organisation, you can replace it: your own subject line, your own body, your own wording. **Built for** organisations whose voice matters. **Replaces** apologising for the robot that emailed your members. Templates live at **Settings** → **Notifications & Email Campaign** → **Email Templates** (`/email-templates`) and need ADMIN\_TENANT. Email Templates screen with template categories in the sidebar and a grid of template cards for the Users category, each with a name and a one-line description *** ## Finding the template you want Templates are grouped into categories in the left sidebar: **Users**, **Referrals**, **Adhesion**, **Membership & Fees**, **Identity**, **eDocuments**, **Events**, **Donations**, **Subscriptions** and **System**. Only categories that apply to you appear: Referrals and Adhesion show when those features are switched on, Membership, Identity, eDocuments, Events, Donations and Subscriptions disappear when the matching feature is off, and **Users** and **System** are always there. A card greyed out with a **Disabled** tag is switched off: still editable, but not sent until you switch it back on. *** ## Editing a template The editor opens with the current subject and body loaded. If you have never customised this email, that is the built-in version in your organisation's language. A single line at the top. Placeholders work here too. A rich text editor with formatting, links and images. Images you paste or upload are stored when you save. The **Insert Placeholder** button lists the values available for this email, each with a short description. Inserting from the menu is safer than typing: the list is filtered to what this email actually knows about. **Preview** renders the message with your own account's details filled in. **Send Test Email** sends it to your own address with `[TEST]` in front of the subject, from your organisation's real sending address. It saves nothing. **Save** makes your version the one members receive from that moment on. Template editor over the templates grid, with the subject field, the Use default and Insert Placeholder buttons, the rich text body, and Send Test Email, Enabled, Preview and Save in the header The **Enabled** switch in the editor header turns this one email on or off, overriding the broader category switch on the [Emails Config](/docs/platform/emails/system-emails) screen. *** ## Placeholders A placeholder is written `{{name}}` and is replaced with real data when the email is sent. These are available in every template: | Placeholder | Becomes | | ---------------------------------------------------------------------------------- | ---------------------------------------------------------------- | | `{{firstName}}`, `{{lastName}}`, `{{fullName}}` | The recipient's name | | `{{userEmail}}` | The recipient's address | | `{{userPhoneNumber}}`, `{{userAddress}}`, `{{userTown}}`, `{{userCountry}}` | Their contact details | | `{{localCenterName}}` | Their local centre | | `{{companyName}}` | Their company, when the Companies feature is on | | `{{membershipLevelName}}`, `{{membershipLevelPrice}}` | Their membership tier and its price | | `{{subscriptionEndDate}}` | The date their membership runs to | | `{{organizationName}}`, `{{organizationLogo}}` | Your organisation's name and logo image | | `{{organizationHost}}`, `{{platformLink}}` | Your Orgo address | | `{{organizationCurrency}}`, `{{organizationTimezone}}`, `{{organizationLanguage}}` | Your organisation's settings | | `{{contactEmail}}` | Your organisation's contact address | | `{{profileLink}}` | A link to the recipient's profile | | `{{paymentLink}}` | A link that takes the member straight to paying their membership | | `{{contractsLink}}` | A link to the recipient's documents | | `{{unsubscribeUrl}}`, `{{preferencesUrl}}` | Unsubscribe and notification preference links | Individual templates add their own. Event emails carry `{{eventName}}`, `{{eventDate}}`, `{{eventLocation}}` and calendar links; contract reminders carry `{{contractName}}` and `{{contractExpiryDate}}`; renewal reminders carry `{{expirationDate}}` and `{{productName}}`. The **Insert Placeholder** menu is the authoritative list for the template you have open. `{{ name }}` with spaces and `%name%` both work as well as `{{name}}`. A placeholder the email does not know about is left in the message as literal text, so check the preview before saving. *** ## Going back to the original **Use default** in the editor toolbar throws your version away and reloads the built-in one. It asks for confirmation, and cannot be undone: the saved custom template is deleted, not archived, and the email falls back to the built-in wording exactly as it behaved before you touched it. *** ## Language The built-in templates exist in English, Romanian and German, and Orgo picks the one matching your organisation's default language. Your own version has no language: it is used for every recipient, whatever their language. A multilingual organisation therefore trades wording control against translation, keeping the built-in templates for all three languages or customising and getting one. The invoice email is the exception, because it is not a template at all. It and the PDF it carries render in your organisation's default language across all 14 interface languages, falling back to English only when the default is not one of them. See [Invoices](/docs/platform/fees/invoices). *** ## What you cannot change Sign-in and security emails cannot be customised at all: login codes, multi-factor codes, verification codes, password reset and change codes, the password-changed confirmation and the email-change request. Orgo refuses to save a template for these types, because they carry live one-time codes and letting stored HTML into them would turn a compromised admin account into an account takeover of every member. A few emails also have no card here at all and always send in their built-in wording, among them invoices, family invitations, waitlist messages, task notifications, event-app networking messages and the discussion digest. Four cards exist for emails that are still produced outside the template system, so editing them has no effect on what members receive: **Newsletter Registration**, **Fee Payment Approval**, **Adult Eligibility Notification** and **Waitlist Eligibility Notification**. Preview and test send still work, which makes this easy to miss. Treat the built-in wording for those four as fixed. *** ## Troubleshooting Check whether the email is one of the four listed above, then check [Email logs](/docs/platform/emails/email-log): the log stores the body that was actually sent, which settles it immediately. That value is not available to that template. Open the template, delete the placeholder and pick a replacement from the **Insert Placeholder** menu. Test sends go to the address on your own account and use the same sending path as everything else, so a missing test usually means a delivery problem rather than a template problem. Check your spam folder, then see [Emails](/docs/platform/emails). Use **Use default** in that template. It affects only the template you have open. *** ## Related * [System emails](/docs/platform/emails/system-emails) - what each template is for and when it sends * [Emails](/docs/platform/emails) - sender identity and language rules * [Email logs](/docs/platform/emails/email-log) - the body that actually went out * [Newsletter builder](/docs/platform/newsletter-builder) - designing campaigns rather than system emails * [Languages](/docs/platform/customization/languages) - the setting that picks the built-in language # Emails Source: https://orgo.space/docs/platform/emails/index How Orgo sends email on your behalf: sender identity, template language, delivery, and where each control lives Orgo sends email on your behalf all day: a welcome message when someone joins, a renewal reminder a month before a fee lapses, a ticket confirmation after a purchase, a login code when a member cannot remember their password. This section covers the machinery behind all of it. **Built for** organisations that need their automatic email to look and sound like them. **Replaces** the transactional email service you would otherwise wire up yourself. Everything here lives under **Settings** → **Notifications & Email Campaign** (`/tenants/modules/emails`) and requires ADMIN\_TENANT. The delivery log and the lists sit in the Administration area instead. *** ## The four surfaces | Surface | Where | What it is for | | -------------------- | ----------------------------------------------------------- | ---------------------------------------------------- | | **Emails Config** | Settings → Notifications & Email Campaign → Emails Config | Switch whole categories of automatic email on or off | | **Email Templates** | Settings → Notifications & Email Campaign → Email Templates | Rewrite the subject and body of an individual email | | **Email logs** | Administration → `/email-log` | Every email the platform sent, with the exact body | | **Lists & Segments** | Administration → `/email-lists` | Reusable audiences that campaigns send to | Campaigns you write and send yourself are a separate feature: see [Newsletter](/docs/platform/newsletter). *** ## Who the email comes from Three things decide what a recipient sees in their inbox. **From name** is always your organisation's name as it appears in [Organisation info](/docs/platform/organisation/organisation-info). **From address** is your organisation's contact email, but only once that address has been verified for sending. Until then Orgo sends from `no-reply@orgo.space`. Verification is done by Orgo rather than in the settings screen, because it requires DNS records on your domain: ask support to verify the address you want to send from. **Reply-To** is always your contact email, verified or not. So even on a brand new organisation, a member who hits reply reaches you rather than a dead no-reply mailbox. Change the contact email at **Settings** → **Organisation** → **Contact email**. Changing it to an unverified address moves the From address back to `no-reply@orgo.space` until the new one is verified. *** ## What language an email is written in Automatic emails are written in your organisation's default interface language, not the recipient's. Only English, Romanian and German are supported for email: if your default language is anything else, emails fall back to English. This applies to the built-in wording of a template. If you write your own version of a template, that version is used for every recipient regardless of language, so a multilingual organisation should think carefully before customising. The [invoice email](/docs/platform/fees/invoices) and the PDF attached to it are the exception: they follow your organisation's default language across all 14 interface languages, and fall back to English only when the default is not one of them. See [Email templates](/docs/platform/emails/email-templates) for what you can rewrite, and [Languages](/docs/platform/customization/languages) for the interface language setting itself. *** ## How a message actually gets sent A member registers, a fee approaches its renewal date, a ticket is paid for. Each of these has one email type attached to it. If the matching switch in **Emails Config** is off, nothing is sent and nothing is logged as sent. Login codes, password emails and workflow emails ignore this check and always send. Your customised version if you saved one, otherwise the built-in template in your organisation's language. Names, dates, amounts, links. See the [placeholder reference](/docs/platform/emails/email-templates#placeholders). Login codes, verification codes, password emails, registration confirmations and admin-created account emails are sent on the spot so a failure surfaces right away. Everything else is queued and sent by a background worker. With the rendered body, so you can see exactly what the recipient got. Codes are the exception: login and multi-factor codes are not logged at all, and the other one-time codes are logged with the code removed and no body stored. *** ## Deliverability A few things Orgo does for you, and one it cannot: * Emails sent through the template system carry a plain text version alongside the HTML, which mailbox providers (Microsoft in particular) treat as a quality signal. * Notification and campaign email carries a `List-Unsubscribe` header, so the unsubscribe button in Gmail and Apple Mail works without the recipient opening the message. Campaign email additionally supports RFC 8058 one-click unsubscribe. * Addresses that were minted during a data import for people who had no email of their own are recognised and skipped rather than bounced. A member with one of these will simply never receive email until you give them a real address. * If you run a [custom domain](/docs/platform/custom-domain), the setup asks you to publish DKIM keys plus an MX and a TXT record on `bounce.`. Those last two put the envelope sender on your own domain, so SPF passes *and* aligns with the address recipients see instead of resolving to Amazon. Mail sends either way, but a domain missing them authenticates on DKIM alone. * Orgo cannot fix your domain's reputation. The DMARC policy on your domain, and the SPF record on your apex covering everything else you send from it, are still yours to maintain. *** ## Troubleshooting Start at [Email logs](/docs/platform/emails/email-log) and search for them. The log answers whether Orgo sent it, to which address, and what it said. If there is no row at all, check first whether that email is one Orgo logs: waitlist messages, family invitations, the fee payment approval, the newsletter signup confirmation and the discussion digest are never written to the log. Otherwise the email was either disabled in **Emails Config** or the triggering action did not happen. Your contact email has not been verified for sending yet. Replies still reach your contact address. Ask support to verify the address. Automatic email follows the organisation's default language, clamped to English, Romanian or German. A member's own interface language does not change it. Invoice emails are the exception and cover all 14 languages. Open that template in **Email Templates** and use the **Enabled** switch in the template header. That per-template switch overrides the broader category switch. *** ## Related * [System emails](/docs/platform/emails/system-emails) - the catalogue of automatic emails and what triggers each * [Email templates](/docs/platform/emails/email-templates) - rewriting subject and body, and the placeholder list * [Email logs](/docs/platform/emails/email-log) - what was sent, to whom, and what it said * [Newsletter](/docs/platform/newsletter) - campaigns you compose and send yourself * [Notifications](/docs/platform/notifications) - in-app and push delivery, and per-member preferences # System emails Source: https://orgo.space/docs/platform/emails/system-emails Every automatic email Orgo sends, what triggers it, when timed ones run, and which can be switched off System emails are the messages Orgo sends on its own: nobody presses send. This page lists them, says what makes each one go out, and shows which you can turn off. **Built for** admins who need to know exactly what their members are receiving. **Replaces** guessing from the support inbox. The switches live at **Settings** → **Notifications & Email Campaign** → **Emails Config** (`/tenants/modules/emails/system-emails`) and need ADMIN\_TENANT. Changes save as you flip them. Emails Config screen with the module menu on the left and grouped switches for User Lifecycle, Membership and Fees, and the start of Adhesion or Applications, with the remaining categories below the fold *** ## How the switches work A **category switch** on the Emails Config screen covers a group of related emails: turning off **Membership Renewal Reminders** silences all fourteen reminders, personal and company. A **per-email switch** sits in the header of each card in [Email Templates](/docs/platform/emails/email-templates) and beats the category switch in both directions, so you can leave the reminder category on and silence only the 30-days-after one. A switched-off email is not sent and no log row is written. Nothing queues up for later. Login codes, verification codes, multi-factor codes, password emails and email-change confirmations always send. They have no switch, by design: a member locked out of their account is not a preference. *** ## Members and accounts | Email | Sent when | Category switch | | ----------------------------- | --------------------------------------------------------------- | ----------------------------- | | **Registration confirmation** | Someone registers and must confirm their address | Registration Confirmation | | **Welcome** | A member's account becomes active | Welcome Email | | **User invitation** | An admin invites someone to join | User Invitation | | **Company invitation** | Someone is invited to join a company profile | User Invitation | | **Account created by admin** | An admin creates the account rather than the member registering | User Created by Admin | | **New member notification** | A new member registers, sent to admins | New Member Admin Notification | | **Reactivation request** | A former member asks to come back, sent to admins | New Member Admin Notification | | **Account deactivated** | An account is deactivated, sent to admins | none, always sends | | **Family invitation** | A member invites a family member to link accounts | none, always sends | *** ## Sign-in and security None of these can be switched off or edited. Seven of them are refused by the platform outright if anyone tries to save a template for them; the event app code has no card on the Email Templates screen and renders from the built-in template like the rest. | Email | Sent when | | --------------------------- | ------------------------------------------------------- | | **Login code** | A member requests a one-time code instead of a password | | **Multi-factor code** | A member with MFA enabled signs in | | **Email verification code** | A member confirms a new address | | **Password reset code** | A member starts a password reset | | **Password change code** | A member changes their password while signed in | | **Password changed** | A password change is confirmed | | **Email change request** | A member asks to change the address on their account | | **Event app code** | A ticket holder signs in to the event app | Login and multi-factor codes are never written to the log. The other code-carrying messages (email verification, password reset, password change, email change and the event app code) do get a row, but with the code stripped from the subject and no body stored, so an admin reading the log cannot lift a live code and take over an account. The two messages here that carry no code, **Password changed** and **Email change request**, are logged in full like any other email. *** ## Membership and fees The renewal ladder runs once a day at 18:00 UTC and picks one message per member based on how far the renewal date is away. All fourteen (seven here, seven for companies) sit under the **Membership Renewal Reminders** switch. | Reminder | Window | | -------------------------- | -------------------- | | **1 Month Reminder** | 24 to 30 days before | | **7 Days Reminder** | 2 to 7 days before | | **1 Day Reminder** | the day before | | **Renewal Day Notice** | on the day | | **Lapsed Reminder** | 1 to 7 days after | | **14 Days After Reminder** | 8 to 14 days after | | **30 Days After Reminder** | 15 to 30 days after | Company memberships have their own ladder at 18:30 UTC, addressed to the company's contact email, with the primary contacts and any additional addresses in copy. When the company has no contact email, the first primary contact becomes the recipient instead. A company with neither is skipped and nothing is sent. | Other fee emails | Sent when | Category switch | | ------------------------ | -------------------------------------------- | ------------------ | | **Renewal Confirmed** | A recurring membership charge succeeds | Payment Success | | **Renewal Failed** | A recurring membership charge fails | Payment Failed | | **Fee Payment Approval** | An admin approves a recorded fee payment | none, always sends | | **Invoice** | An invoice is emailed, with the PDF attached | none, always sends | See [Renewals](/docs/platform/fees/renewals) for what a member experiences when a fee lapses, and [Invoices](/docs/platform/fees/invoices) for invoice delivery. *** ## Events | Email | Sent when | Category switch | | -------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ | ------------------------------- | | **Event invitation** | A member is invited to an event | Event Invitations | | **Free event registration** | Someone registers for a free event | Event Registration Confirmation | | **Paid event registration** | A ticket purchase completes | Ticket Payment Confirmation | | **Guest tickets** | A buyer's tickets are issued for other people | Event Invitations | | **Ticket confirmed** | A ticket is confirmed for an attendee | Event Invitations | | **Day-before reminder** | A published event starts tomorrow, sent only to people who registered more than 7 days in advance, once each | Event Reminders | | **1-hour reminder** | An event with the one-hour reminder enabled starts in about an hour, checked every 10 minutes | Event Reminders | | **Attendance reminder** | An event ended 24 hours ago and attendance still needs recording | Event Reminders | | **Networking invitation, accepted, declined, cancelled** | A meeting request in the event app changes state | none, always sends | *** ## Applications, identity and documents | Email | Sent when | Category switch | | ----------------------------------------------------------- | ---------------------------------------------------------------- | ----------------------------- | | **Adhesion pending review** | An application is submitted, sent to admins and HR | Adhesion Notifications | | **Adhesion approved** | An application is approved | Adhesion Notifications | | **Adhesion rejected** | An application is rejected | Adhesion Notifications | | **Adhesion reverted to draft** | An admin sends an application back for changes | Adhesion Notifications | | **Adhesion form validated** | An admin validates the signed form | Adhesion Notifications | | **Identity validation requested** | A member uploads identity documents | Identity Validation Emails | | **Identity rejected** | A submission is rejected, with the reason | Identity Validation Emails | | **Identity payment reminders (3)** | Hourly job, for members who owe an identity validation payment | Identity Validation Emails | | **New identity for review** | Sent to finance when a document needs checking | Identity Validation Emails | | **Contract expiry: 30 days, 7 days, today, 7 days overdue** | Daily job at 08:00 UTC against each document's validity end date | Contract Expiry Reminders | | **Contract signed, pending** | One party has signed and others have not | Contract Signed Notifications | | **Contract signed, complete** | Everyone has signed, sent to the signer and to admins | Contract Signed Notifications | *** ## Subscriptions and payments | Email | Sent when | Category switch | | ---------------------------------- | ------------------------------------------------------------------------------------ | -------------------------- | | **Subscription created** | A recurring payment is set up | Subscription Notifications | | **Subscription payment received** | A recurring charge succeeds | Subscription Notifications | | **Subscription cancelled** | A recurring payment is cancelled | Subscription Notifications | | **Identity expiring** | Daily job at 07:00 UTC, for subscriptions whose identity document is about to expire | Subscription Notifications | | **Identity expiring (second run)** | A second daily job at 08:00 UTC sends the same message | none, always sends | | **Checkout reminder** | Daily job at 08:00 UTC, for an abandoned checkout | none, always sends | | **Donation thank you** | A donation payment completes | Payment Confirmations | | **Form submission confirmation** | Someone submits a form that has confirmation enabled | Payment Confirmations | *** ## Community, local centres and everything else | Email | Sent when | Category switch | | ------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------- | | **Local centre request, approved, declined** | A member asks to join a local centre and an admin decides | Local Center Request Notifications | | **Resignation request** and **approved** | A member asks to resign and an admin decides | Resignation Notifications | | **Referral received** | Someone signs up through a referral link | Referral Notifications | | **Referral complete** | A referral is finished, one version for the referrer and one for admins, differing by whether your organisation approves registrations manually | Referral Notifications | | **Post held for moderation** | A discussion post is held, sent to moderators | none, always sends | | **Connection request** and **accepted** | Members connect in the event app | none, always sends | | **Vote published** | A vote opens. Members receive it through their vote notification preference; non-member attendees of an event vote receive it with a personal voting link | none, always sends | | **Waitlist confirmation, approved, rejected, position update, new entry** | The registration waitlist changes | none, always sends | | **Task assigned, status changed, comment added, due soon, overdue** | Task activity | none, always sends | *** ## Digests Three summary emails run on a schedule instead of reacting to one event. | Digest | Runs | Contains | | ---------------------------- | -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Daily discussion digest** | 06:00 UTC | Sent to active members whose discussion preference is Daily who have an unread discussion notification from the last 25 hours. The email itself lists their 10 most recent unread notifications of any kind | | **Weekly discussion digest** | Wednesdays 09:00 UTC | The same, selected over the last 7 days, for members set to Weekly | | **Daily task digest** | 06:00 UTC | Open tasks assigned to the member | An unread discussion notification is what triggers the digest, but the email carries the member's ten most recent unread notifications whatever their type, so events, mentions and votes they have switched off individually still surface here. Members choose Instant, Daily or Weekly in their own notification preferences, or switch discussion email off entirely. Discussion email follows each member's notification preference rather than the **Discussion Notifications** switch on the Emails Config screen. To reduce discussion email across the organisation, change the default in **Notification Preferences** instead. See [Notifications](/docs/platform/notifications). *** ## Related * [Emails](/docs/platform/emails) - sender identity, language and delivery * [Email templates](/docs/platform/emails/email-templates) - rewriting a system email * [Email logs](/docs/platform/emails/email-log) - proving an email was sent * [Notifications](/docs/platform/notifications) - in-app, push, and per-member preferences * [Renewals](/docs/platform/fees/renewals) - what the fee reminder ladder is enforcing # Event Analytics Source: https://orgo.space/docs/platform/events/analytics Counted attendance, capacity, RSVP mix and ticket revenue for a single event Analytics is the numbers view of one event: how many people are registered, how full it is, what the RSVPs look like, what each ticket tier has sold, and how registrations arrived over time. Everything on it is computed from the attendee and payment records, so it needs no input from the organiser. Event analytics page showing Attendees, Capacity used, Total revenue and Refunded tiles above an RSVP donut chart *** ## Opening it Open the event, then **Analytics** in the event sidebar. No module setting controls it: the entry is there for every event. You see it if you can manage the event, meaning you are the **event owner**, or you hold **EVENT\_LOCAL** for the event's local centre, or **EVENT\_TENANT** organisation-wide. `ADMIN_TENANT` covers all of these. Ordinary members have no analytics entry, and the underlying request is refused for anyone outside those roles or from another organisation. *** ## The period selector Three choices sit in the page header: **Lifetime**, **30 days** and **7 days**. The window applies to when people registered, not when the event runs. **30 days** means registrations created in the last 30 days, and every figure on the page (attendees, revenue, RSVP mix, ticket sales, timeline) is recalculated for that slice. **Lifetime** is the whole history of the event and is what loads by default. *** ## The four tiles | Tile | What it counts | | ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Attendees** | Registrations that are not cancelled. Rows attached to another registration, such as a guest or an attendee created by an add-on, are not counted separately. Shows "of N" when the event has a capacity. | | **Capacity used** | Attendees divided by the event's maximum capacity. Shows a dash and **Not set** when no capacity is defined, which is different from 0%. | | **Total revenue** | Successful ticket payments, before refunds. When there are refunds it also shows the net figure. | | **Refunded** | Refunded ticket payments, with the share of gross revenue underneath. | **Attendees** counts every registration status except cancelled, so people who are only **Invited** or on the **Waiting list** are in the figure. Capacity is enforced against **Registered** alone, which means **Capacity used** can reach 100% while the event is still accepting sign-ups. Read it as "how many rows exist", not "how full the room is". The **Attendees** tile excludes cancellations by registration status while the RSVP donut, the **Sold** column and the timeline exclude them by cancellation timestamp, so a registration cancelled through one signal and not the other appears in one section and not the other. *** ## RSVP A donut with a coloured tile per response: **attending**, **maybe**, **attended** and **not attending**. Responses with no one in them are left out rather than shown as zero. The RSVP figures cover registrations that have not been cancelled, again excluding guest and add-on rows attached to another registration. Someone who registered, answered "attending" and later cancelled disappears from this section, while their money, if any, stays in the revenue figures until it is actually refunded. *** ## Revenue by ticket Revenue by ticket table with sold, revenue and refunded columns beside a donut of revenue share, above the registrations over time chart This section appears only when the event has ticketing enabled. It lists one row per ticket tier with **Ticket**, **Sold**, **Revenue** and **Refunded**, beside a donut showing each tier's share of gross revenue. Tiers that have taken no money are left out of the donut but stay in the table. Attendees who are not attached to a ticket tier, such as people added by an organiser, are grouped into a single **Unspecified** row. Two counting rules are worth knowing, because they make the columns disagree in a way that is deliberate: * **Sold** counts registrations that are not cancelled. * **Revenue** and **Refunded** follow the money instead. A cancelled registration whose payment was never refunded still contributes to revenue, because the money is still in the account, and a refund tied to a cancelled registration still appears under Refunded. *** ## Registrations over time A daily line of new registrations, by the date the registration was created, excluding cancelled ones. It is the quickest way to see whether an announcement, a newsletter or a deadline moved sign-ups. Individual points are marked while the series has fewer than 30 days of data, and the line is smoothed once it grows past that. *** ## How current the numbers are **Lifetime** figures are served from a stored summary that is recomputed in the background whenever something relevant changes: a registration is added, cancelled or moved to another ticket, or a payment is created, refunded or changes amount. Bulk operations such as an import or a batch cancellation trigger one recompute for the event rather than one per row. A nightly job (`app:event-analytics:refresh-stale`) recomputes any summary older than 24 hours, so a missed update corrects itself within a day. Capacity is always read live from the event, so changing the maximum capacity moves the **Capacity used** tile immediately. The **30 days** and **7 days** views skip the stored summary entirely and are computed on request, so they are always current. If the page shows "No analytics available for this event yet", the event has no attendee records in the selected window. Switch to **Lifetime** before concluding anything is wrong. *** ## What this page is not * **There is no export button here.** To get the underlying rows, use the attendee export on the [participants screen](/docs/platform/events/attendance), which produces a CSV with names, contact details, ticket type, price, statuses and custom field answers. * **There is no comparison across events** and no organisation-wide roll-up. Each page covers one event. * **It does not replace the written report.** Goals, activities and budget live in the [event report](/docs/platform/events/event-report). *** ## Related * [Attendance](/docs/platform/events/attendance): participant records, statuses and the CSV export * [Ticketing](/docs/platform/events/ticketing): ticket tiers, capacity and refunds * [Event Reports](/docs/platform/events/event-report): the written record of an event * [Annual Report](/docs/platform/events/annual-report): compiling reports for a local centre * [Permissions](/docs/platform/permissions): who holds event permission # Annual Event Report Source: https://orgo.space/docs/platform/events/annual-report Compile a printable booklet of a local centre events over any date range The annual report gathers the events of one local centre over a date range you choose and lays them out as a single printable document: photo, dates, place, description, and the written [event report](/docs/platform/events/event-report) for each one. It is designed to be printed or saved as a PDF and handed to a board, a funder or an assembly. *** ## Turn it on **Settings → Modules → Events → Reporting & Analytics**. Changing these requires `ADMIN_TENANT`. | Setting | What it does | | ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------ | | **Annual Event Reports** | Enables the feature. Adds the **Annual report** action to local centre pages and the **Add to annual report** checkbox to the event report form. | | **Local Annual Report** | Also enables the same action. This toggle only appears once **Annual Event Reports** is on and the Local Centers module is active. | Either setting is enough on its own: the app checks for one or the other. The module list also shows **National Annual Report**. Nothing in the product reads that setting. The per-local-centre report described on this page is the only annual report Orgo generates. *** ## Mark the events to include An event appears in the report only if someone ticks **Add to annual report** on the event's [Report](/docs/platform/events/event-report) screen. There is no automatic inclusion and no bulk action for it, so this is the step that decides what the report contains. *** ## Generate the report Go to the local centre page. Its actions list includes **Annual report**. Pick a **Report begin date** and a **Report end date**. Any range works, not just a calendar year: a season, a quarter or a mandate period is equally valid. Annual report modal with report begin date and end date pickers and the note that a report can contain maximum 200 events Press **Generate report**. The report opens in a new browser tab, without the app sidebar and navigation, so the page is ready to print as it stands. Press **Print as PDF** at the top. That opens your browser's print dialog, where you can print or choose "Save as PDF". Background colours and images are forced on for printing. *** ## What goes in An event is included when all of these are true: * it is ticked **Add to annual report**; * its start date falls inside the range you chose; * it is hosted by the local centre itself or by one of that centre's active groups; * it is published, or it is your own draft (drafts belonging to other people are never listed); * it is a top-level event, not a sub-event of an agenda. The report is capped at 200 events, which the date modal also states. A longer period simply stops at that ceiling, so split a very active decade into shorter ranges. Generated annual report showing the local centre header and the first event entry with its dates, place, description and report fields Events are listed oldest first. For each one the report prints: | Element | Source | | ---------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Logo and title | The event record. The page header above them carries the local centre's own logo and name, and its town after the name only where the organization has `localCenter.hasNameDifferentThanTown` switched on, so a chapter named after its own town is not printed twice | | Dates | Start date, and end date when it differs | | Location | The event's location field | | Description | The event description | | Goals, Target, Activities, Advertising, Budget | The event report, showing only the fields that were filled in | | Photo gallery | The event's media gallery | A field containing only a dash is skipped, so importing placeholder dashes will not produce empty headings. Gallery items are rendered as images. Videos and documents attached to an event will not display correctly in the printed report, so keep the gallery to photos for the events you intend to report on. *** ## What it does not include The report is a qualitative compilation, not a statistics pack. Verify this against your expectations before promising numbers to a board: * **No totals or averages.** There is no count of events, no total attendance, no attendance rate, no unique attendees. * **No charts and no year on year comparison.** * **No breakdown by event type, group, SDG or volunteer hours.** * **No CSV or data export.** The only output is the printable page. * **No organisation-wide roll-up.** One report covers one local centre. For a whole organisation, generate one per centre. For counted figures on a single event, use [Analytics](/docs/platform/events/analytics), which computes attendance, capacity and revenue from the attendee records. *** ## Common questions Check the four conditions in order: the **Add to annual report** checkbox is ticked, the start date is inside the range, the event is hosted by this local centre or one of its active groups, and the event is published. A draft belonging to someone else will not appear even when it is ticked. That message means the filter returned nothing. Widen the dates first, then confirm that at least one event of that centre carries the annual report tick. Not in the app. The report prints as it renders. If you need a cover, an introduction or a different order, print to PDF and assemble the final document outside Orgo. No. The report is generated from a local centre page and is scoped to that centre and its groups. *** ## Related * [Event Reports](/docs/platform/events/event-report): the per-event text this report compiles * [Analytics](/docs/platform/events/analytics): counted attendance, capacity and revenue per event * [Local Groups](/docs/platform/groups/local-groups): local centres and their groups * [Events Overview](/docs/platform/events): module settings and the event lifecycle # Event Attendance Source: https://orgo.space/docs/platform/events/attendance Run the participant list: registration status, RSVP, invitations, walk-ins, check-in and the attendee export Every event has a **Participants** screen listing everyone attached to it: members who registered, non-members who bought a ticket, people you invited, and guests riding on somebody else's ticket. It is where you invite, chase, check in and export. **Built for** organisers who need the turnout figure to come from the same system that holds the member records, so attendance feeds profiles, reports and the next mailing without a re-import. **Replaces** the shared spreadsheet that lists who said yes and the separate clipboard that records who actually came. Participants screen listing attendees with name, town, ticket, RSVP and invited status *** ## Who can open it **Participants** appears in the event sidebar for the event owner, `EVENT_LOCAL` or `ADMIN_LOCAL` on the event's group, `EVENT_TENANT` or `ADMIN_TENANT` organisation-wide, and to the owner or an admin of the hosting group. When **Restrict Event Editing by User Type** is on, a local user whose type does not match the event's loses this even if they hold `EVENT_LOCAL`. Attendees never reach it. They get the **Participants** block on the event page, and only when they are registered themselves and the event has **Visibility of attendee list** on (event → **Modify** → **Features**). With it off, the attendee list is organisers only. *** ## Two statuses, not one Each participant carries two independent statuses. Confusing them is the most common source of "the numbers are wrong". **Registration status** is where the person sits in the sign-up workflow. The column only appears on events that require registration. | Status | Meaning | | -------------------- | ----------------------------------------------------------------------- | | **Invited** | Added by an organiser, has not confirmed yet | | **Registered** | Sign-up complete, and paid if the event is ticketed | | **Pending approval** | Waiting for an organiser to accept the registration | | **Waiting list** | Parked by an organiser. Nothing moves people on or off it automatically | | **Awaiting payment** | An invoice was issued and is not settled yet | | **Canceled** | Withdrawn by the attendee or the organiser | **RSVP status** is the person's own answer, and after the event it is where attendance is recorded. | Status | Meaning | | ----------------- | ------------------------------------------------------------- | | **Attending** | Coming | | **Maybe** | Undecided. Not offered on events that use a registration form | | **Not attending** | Declined | | **Attended** | Present. This is what check-in sets | Participant list of an event without ticketing, showing only the RSVP column with Attending, Attended and Not attending values Checking somebody in sets RSVP to **Attended**. There is no separate "checked in" flag, so an attendance figure is a count of participants whose RSVP is Attended. Both are editable from the dropdowns in the list. The registration dropdown greys out once a payment is attached: cancel or refund the payment first, since the status follows the money. *** ## Adding people Use **Invite** at the top right. The **Member** tab searches the directory; the **External** tab takes a name and email, matching the address against members first, then contacts, and creating a new contact only if neither exists. **Guest tickets** takes a number from 0 to 20: each guest is a separate registration and ticket issued to the same person, with its own QR code, so they can bring people whose names you do not need. Invite participant dialog with Member and External tabs, a member search box, and the guest tickets number control Either route confirms immediately: registration **Registered**, RSVP **Attending**, and an emailed ticket with a QR code and a calendar invite, so speakers, sponsors and staff get in without paying. ### Everyone in the group at once With **Bulk Invites** enabled (**Settings → Modules → Events → Additional Features → Bulk Invites**), a published event shows **Send Invites to All Members**, and publishing offers the same. It adds every active member of the event's group as **Invited** with RSVP **Maybe**, or of the whole organisation when the event has no group. People already listed are skipped, and it runs once per event. Bulk invite fills the participant list. It does not currently send the invitation email, so announce the event separately (a [newsletter](/docs/platform/newsletter) or the event's Messages tab) rather than assuming everybody has been contacted. ### Capacity On an event with **Max capacity** set and no ticketing, registration is refused with "This event is full" once **Registered** participants reach the limit. The **X / N Participants (M seats left)** line on the event page is not this number. It counts every participant row that has not been cancelled, including people who are only **Invited**, on the **Waiting list**, or awaiting payment, and including guest tickets. So the event page can say "This event is full" while sign-ups are still going through, most visibly after a bulk invite. The public event page and the refusal itself both count only **Registered**. Nobody is queued automatically: move people to **Waiting list** yourself. To let one in, set their registration to **Registered**, and note that this sends nothing. If they need a ticket by email, set them to **Invited** first and then use the confirm action on their row, which is the only status the confirm action accepts. *** ## Recording who came * **Scan the QR code** at the door. See [QR check-in](/docs/platform/events/check-in). * **Set RSVP to Attended** in the list, one participant at a time: there is no multi-select or bulk check-in action. * **Walk-ins** must exist on the list first: add them with **Invite**, then set them to Attended. A row-actions column carrying **Logs**, the confirm action, **Generate guest tickets** and **Remove** appears only for the person who owns the event and for `HR_TENANT`. An `EVENT_TENANT` or `EVENT_LOCAL` admin who does not own the event can still change statuses from the dropdowns but gets none of those four actions. *** ## Filtering, columns and export The control bar filters by name, email, RSVP, registration status, ticket type and an **Invited** checkbox; events with an agenda add a session selector. The list paginates at 100 rows, and the count above it includes guest tickets and add-on attendees while the rows show only the people they were issued to. **Columns** offers Membership and Membership Fee (only with the fees module on), Organisation, Role, Email, Phone, LinkedIn, Date, and one column per custom field on the event's registration form, with **Show all** and **Hide all** at the bottom of the menu. **Export** downloads `attendees__.csv` and needs `EVENT_TENANT`, `EVENT_LOCAL` on the event, or event ownership; a session selected in the agenda filter narrows it to that session. Its columns are Name, Email, every standard profile field on the event's [registration form](/docs/platform/events/registration-forms), Ticket Type, Ticket Price, Registration Status, RSVP Status, Date Registered, and one per event custom field (dropdown and checkbox answers written as their labels), plus Discount Code when at least one attendee used a voucher and Partner Name and Partner Email when add-ons created extra attendees. *** ## Attendance reminders Switch on **Settings → Modules → Events → Additional Features → Enable Attendance Reminder** and each event gains **Send attendance reminder 24 hours after event ends**, on by default. It goes to the **event owner**, not to attendees, links back to the event so they can fill in the RSVP column, and is sent once per event. The wording lives in **Settings → Modules → Events → Attendance Reminder**, a full email editor with preview and test send. Placeholders: `{{firstName}}`, `{{eventName}}`, `{{eventDate}}`, `{{eventLocation}}`, `{{attendanceLink}}`, `{{organizationName}}`. *** ## Troubleshooting Registrations holding a ticket cannot be deleted, because that would orphan the payment. Set them to **Canceled** and refund through [payments](/docs/platform/fees/record-payment) if money changed hands. They are already on the list, possibly as Canceled or Invited. Change the existing row instead of adding a second one. Events with a registration form only accept sign-ups through the form. Organisers can still add people with **Invite**. *** ## Related * [QR Check-in](/docs/platform/events/check-in): scanning at the door and who is allowed to * [Registration Forms](/docs/platform/events/registration-forms): what you collect and what exports * [Ticketing](/docs/platform/events/ticketing): paid registration, add-ons and refunds * [Speakers and Trainers](/docs/platform/events/speakers-trainers): the other people lists on an event * [Event Reports](/docs/platform/events/event-report): turning attendance into a report # QR Check-in Source: https://orgo.space/docs/platform/events/check-in Scan attendees in at the door, what the scanner shows, and the exact permission it needs Every confirmed registration carries a QR code. Scanning it at the door pulls up the attendee, shows what they hold, and records them as present in one tap, so your turnout figure comes out of the event itself. **Built for** door teams who need to know in a second whether the person in front of them is on the list, what they paid for, and whether they have already been let in. **Replaces** a printed list and a highlighter. *** ## Where the code comes from Each registration gets its own code the moment the row is created, whatever its status. What confirmation adds is the emailed ticket carrying that code. Guest tickets each get their own, so a member bringing three people hands over four different codes. Attendees find theirs in three places: * the **PDF ticket** attached to their confirmation email, with the code, ticket number, event, date and location; * on the **event page**, once their registration shows as confirmed; * in the event app, under their tickets. Public event page showing a confirmed registration with the Registration confirmed badge and the QR code to show at the entrance The PDF ticket is only generated for events that have a location, or that use a registration form. A locationless event with simple RSVP still produces a code on screen, but no attachment. *** ## Who can scan This is the thing to sort out before the doors open, not on the day. | Which code you scan | Permission needed | | --------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | | The code on the emailed PDF ticket, scanned with any phone camera or from the Orgo mobile app | `HR_TENANT` or `EVENT_TENANT` (`ADMIN_TENANT` covers both) | | The Event App badge code, which opens the Event App scanner | Event App access to that event, plus `ADMIN_TENANT`, `EVENT_TENANT`, or `EVENT_LOCAL` on the event's group to check anyone in | Local events permission is not enough for the emailed ticket code. Somebody with `EVENT_LOCAL` who scans a PDF ticket gets an access error even though the ticket is perfectly valid. Give door staff `EVENT_TENANT`, or have them work in the Event App and scan attendees' badge codes there, where `EVENT_LOCAL` is enough. The Event App scanner refuses your own badge, so a helper needs someone else's code to test with. Marking somebody present without a scan is wider: the event owner, `EVENT_LOCAL` on the event's group, `HR_TENANT` and admins of the event's group can all set an RSVP to **Attended** from the participant list, and the attendee can set their own row. A refunded registration is the exception: its row shows a static **Refunded** tag with no RSVP to change. *** ## Scanning Any phone camera works. The code is a link to your organisation's Orgo address, so it opens the check-in page in the browser. Inside the Orgo mobile app, open the event and use **Scan** instead, which keeps you in the app between attendees. You get the attendee's photo, name and email, the event name, the ticket number, the ticket type and price, and a badge saying whether this is a paid, free, invited or guest entry. A guest pass also shows who it was issued to. The card turns green and the registration's RSVP becomes **Attended**. Scanning the same code again shows that they are already checked in rather than an error, so a double scan is harmless. If the payment behind a ticket has not completed, the card shows a payment warning but still lets you check the person in. That is deliberate: sort the money out afterwards rather than holding up a queue. *** ## When there is no code Speakers, sponsors, staff and anyone who paid by bank transfer often turn up with nothing to scan. A code exists only where a registration exists, so the fix is always the same: put them on the list. Open the event → **Participants** → **Invite**, add them as a member or by email, and Orgo confirms them and emails a ticket with a code. Then either scan it or set their RSVP to **Attended** directly. There is no way to issue a bare code without a registration behind it. *** ## Troubleshooting Almost always permission, not the ticket. Check the scanning account against the table above, especially if a helper was handed a phone at the door. Fix it in [permissions](/docs/platform/permissions) and rescan. The scanner on the event page is rendered only inside the Orgo mobile app. Two things still work on a laptop: the Event App's own **Scan QR** button, which runs in any browser and accepts `EVENT_LOCAL`, and checking people in by hand from the participant list. You can also scan an emailed ticket with a phone camera and use the page it opens, which needs `EVENT_TENANT`. The scanner reports the reason rather than failing silently: "Camera access denied" when the device has refused the permission, "No camera found" when there is no usable camera. Grant the permission in the device settings and reopen the scanner. It resolves to whatever registration it belongs to, and the card names the event. Read the event name on the card before tapping check in, particularly at multi-day or multi-session gatherings. Check their registration first. The ticket email goes out when a registration is confirmed, so an attendee sitting at **Invited** has a code but no email yet. Use the confirm action on their row, which sends the ticket. A row at **Pending approval** or **Awaiting payment** has no confirm action at all: move it to **Invited** first, or set it to **Registered** and accept that no email is sent. Check-in is online only. Fall back to an exported participant list on paper, mark it up, and record the RSVPs afterwards from the participant screen. *** ## Related * [Attendance](/docs/platform/events/attendance): the participant list, statuses and export * [Ticketing](/docs/platform/events/ticketing): what a ticket is and how it gets paid for * [Registration Forms](/docs/platform/events/registration-forms): what confirms a registration * [Speakers and Trainers](/docs/platform/events/speakers-trainers): the people who usually arrive without a ticket * [Permissions](/docs/platform/permissions): granting `EVENT_TENANT` to door staff # Create Event Source: https://orgo.space/docs/platform/events/create-event Every field on the event form, what it controls, and what happens when you publish The event form is the same for a 10-person committee meeting and a 500-person ticketed conference. Sections appear or stay hidden depending on your permissions and which modules your organization has enabled, so most people see a shorter form than the one described here. **Built for** anyone in your organization who runs events: national staff, local center coordinators, and group admins. Create Event form with cover image on the left and group, event type, title, location, online meetup, start and end times with timezone on the right *** ## Before you start Go to **Events** and select **Create an event**, or open a group and use its Events tab. You can reach the form if you either hold the permission set in **Settings → Modules → Events → Who Can Create Public Events**, or belong to at least one group. If neither is true, the page tells you so and offers a link to browse groups. Reaching the form is not the same as being allowed to save into every group it offers. Each chapter carries its own **Who can create events in this chapter** setting, and a group can be set so that only its admins create events; either is checked when you save and refuses with a permission message. See [Local Centers](/docs/platform/groups/local-groups#creating-a-chapter). *** ## Cover image The image panel sits on the left of the form. Upload a PNG or JPEG and a cropper opens: position and scale the image there, then confirm. Covers are **square (1:1) and saved at 800 by 800 pixels**. If you keep design templates for event artwork, build them at 1:1. A 16:9 banner gets cropped to the centre square, so text near the left and right edges disappears. The same file is reused at several sizes across the event list, the event page, the public page, and the mobile app. *** ## Event details | Field | What it does | | --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Group** | Who the event belongs to. The dropdown has two sections: **Main groups** (your organization as a whole, local centers, role groups, and unit-typed groups) and **groups** (regular groups you belong to). The organization-wide option only appears if you hold the **Who Can Create Public Events** permission. A chapter is offered whether or not you may create events in it, so picking one is only accepted on save if you meet that chapter's own threshold. Once the event is published the group is locked and shown as a tag. | | **Event type** | Optional category. Admins get a **Manage types** shortcut next to the label. See [Event Types](/docs/platform/events/event-types). | | **Title** | Required. | | **Custom Status** | Only when **Enable Custom Statuses** is on. Pick one of your organization's statuses, or None. | | **Location** | Address autocomplete backed by Google Places. Picking a suggestion stores coordinates and draws a map preview on the event page. You can also type a plain address. | | **Online meetup** | A URL for Zoom, Meet, Teams, or anything else. You can fill in both this and a physical location for a hybrid event. | | **Start** and **End** | Date picker plus a time dropdown. The end row is optional: use **Add end time** and **Remove end time**. Moving the start past the end pushes the end to start plus two hours. | | **Timezone** | Set per event, defaulting to your own profile timezone. Choose from a shortlist of popular zones or search the full list. | | **Description** | Collapsed by default. Rich text with formatting, links, and pasted images. | Choosing the event type set as **Training Event Type** in module settings adds a **Training type** selector. Choosing the type set as **General Meeting Event Type** adds the general meeting checkboxes (general meeting, elective, extraordinary). There is no recurrence feature. For a weekly meeting, create the first event and use **Duplicate Event** from the event sidebar for each later date, or build an [event template](/docs/platform/events/event-templates) so each new instance starts pre-filled. *** ## Access and audience This block only appears if you can manage events (`EVENT_LOCAL` or the tenant's public-posting permission). **Access** is **Free** or **Paid**. Paid is only offered when the Online Payments module is active, and only to holders of `FINANCIAL_TENANT` or `EVENT_TENANT`. Choosing Paid turns the event into a ticketed one and creates a linked product behind the scenes, plus a Stripe product when a Stripe account is connected. Saving a Paid event needs `EVENT_TENANT` specifically. `FINANCIAL_TENANT` reveals the option but the save is rejected with a permission error. See [Ticketing](/docs/platform/events/ticketing). **Audience** is **Members only** or **Public**. The Public option is shown only if you hold the permission named in **Who Can Create Public Events**, and it is hidden entirely for non-joinable (private) groups. The server enforces both rules, so a request that sets Public without the permission is saved as Members only rather than rejected. Access and Audience option cards followed by the Registration and Features setting rows with toggles ### Registration | Setting | What it does | | ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------- | | **Require registration form for members** | Members fill in a form instead of a one-click RSVP. Forced on and locked for paid events. | | **Max capacity** | A cap on registrations. Empty means unlimited. Hidden for paid events, where seats are set per ticket type instead. | | **Close registrations** | Stops all new registrations and ticket purchases without deleting anything. | ### Features | Setting | What it does | | -------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Enable speakers** | Adds the Speakers tab to the event sidebar. | | **Visibility of attendee list** | Off: admins only. On: admins and event attendees. | | **Enable 1:1 networking** | Lets attendees book 15-minute meetings with each other in the [event app](/docs/platform/events/event-app). Requires the attendee list to be visible, and turning that off again clears this. | | **Send reminder 1 hour before event starts** | Emails registered attendees an hour ahead. | *** ## Optional sections **Gamification** (when tiers are enabled and you hold `EVENT_TENANT`): award **Points** for the event, and optionally a badge granted to participants marked as attended. **SDG** (when the SDG setting is on): tag the event with any of the 17 UN Sustainable Development Goals. **Detect SDGs** proposes tags from the title and description, and needs a title plus at least 20 characters of description. Admins get a **Disable SDG functionality** link that switches the setting off organization-wide. **Send attendance reminder 24 hours after event ends** appears when the module setting is on: the reminder goes to you, the host, so attendance actually gets recorded. **Restrict editing to user type** appears when **Restrict Event Editing by User Type** is on and you hold `EVENT_TENANT` or `ADMIN_TENANT`. Local users then need the chosen user type to edit the event, and deleting it requires `EVENT_TENANT`. **Propagate event to all local centers** appears on creation only, for `EVENT_TENANT` holders, when both the Local Centers module and **Propagate Events to Local Centers** are on, and the selected group is not private. Saving then creates one **published** copy in every active local center rather than a single event, and returns you to the events list. A second toggle, **Send invites to members**, adds every member of all those centres to each copy's participant list as **Invited**. It does not currently send any email, so announce the event separately. *** ## Draft, publish, invite New events are saved as **drafts**. A draft appears in the events list only for the person who created it; other managers can open it by direct link, and ordinary members are turned away. An event whose dates are already in the past is published immediately on save. Open the event and the draft banner reads "Only you can see this event" with a **Publish Event** button. Publishing a future event notifies the members of its group. Publishing a past event does not notify anyone. If **Bulk Invites** is enabled, publishing asks whether to invite all members of the group, with **Send Invites** and **Skip Invites**. A published event shows **Send Invites to All Members** until invites go out. Sending switches to "Sending invites..." and then to a confirmation. Invites cannot be sent while the event is still a draft. *** ## After publishing Editing is at **Modify** in the event sidebar. Everything stays editable except the hosting group, which the form locks on publish. Attendees are not told automatically when you change details, so send them a message from the event's **Messages** entry. Deleting behaves differently either side of five participants. Under five, the delete is refused if any attendee has a payment attached. From five upwards the event is hidden rather than erased: it disappears from every list and its address stops working, but the record and its attendees are kept. There is no undo button, so recovering one means asking Orgo support. *** ## Related * [Events overview](/docs/platform/events) - module settings and the event workspace * [Event Types](/docs/platform/events/event-types) - categories and custom statuses * [Event Templates](/docs/platform/events/event-templates) - pre-filled events, tickets, and forms * [Ticketing](/docs/platform/events/ticketing) - ticket types, add-ons, and checkout * [Attendance](/docs/platform/events/attendance) - invitations, RSVPs, and check-in # Event App Source: https://orgo.space/docs/platform/events/event-app The mobile companion app your attendees use during an event: agenda, feed, networking, badge and votes The Event App is the attendee-facing side of an Orgo event. It runs in the browser at the event's own `/event-app/` address, is built mobile first, and gives everyone registered for the event a single place to see the agenda, read announcements, find other attendees, book meetings, vote and show their badge at the door. **Built for** conferences, congresses, general assemblies and multi-day gatherings where attendees need something in their hand during the event, not just a confirmation email. **Replaces** a separate event app product bolted onto your registration system. It uses the same registrations, the same people and the same permissions as the rest of Orgo. Event App on a phone showing the event cover, title, tab strip and the Details tab with date, location and description *** ## Who can open it Access is decided per event, not per organisation. | Who | Condition | | ----------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | | **A member** (has an Orgo account in your organisation) | Holds a registration for the event that is not cancelled, with status Registered, Invited or Awaiting invoice payment | | **A non-member attendee** (a contact created by a ticket purchase or an invitation) | Same registration condition, on an event that belongs to the same organisation | | **An event manager** | Has `EVENT_TENANT`, or `EVENT_LOCAL` on that event, even with no registration | | **A tenant administrator** | `ADMIN_TENANT` opens any event in the organisation, but only from a full password login (see below) | Everyone else is redirected to the normal event page with "You are not registered for this event". There is no organisation-wide switch: any event with attendees has the Event App. You control only which tabs appear, under [What organisers configure](#what-organisers-configure). *** ## The three ways in | Way in | How it works | | ----------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Members already signed in** | The **Event app** shortcut sits in the event page header (for people who can edit the event) and in the event sidebar, both only once the event has a **location** filled in. Dashboard event cards open it directly for the owner and for anyone with a registration | | **Non-members: the link in their confirmation email** | Ticket and registration confirmations sent to a non-member contact link straight into the Event App, carrying a private key tied to that registration: no password, no account, and it works until the registration is cancelled. Treat it as their ticket | | **Anyone: a code sent by email** | On the normal login screen, an email with no member account anywhere still works: Orgo sends a six-digit code and signs the person in to the Event App only | *** ## Signing in with an email code This login is deliberately not the normal member login. It proves that someone controls an email address, and nothing more. **How it behaves** * Six digits, valid for **5 minutes**. * **20 seconds** between requests for a new code. * At most **10 codes per 5 minutes** to one email address, counted across every organisation. * Up to **15** attempts per code, and **10 failed attempts within 10 minutes** lock that email out of this login for the rest of the lockout window. * The screen never says whether the email is known to Orgo: an unknown address returns exactly the same response as a known one, and no email is sent. **What the session can do** The session is scope limited to member-level and event-level permissions (`USER`, `USER_LOCAL`, `EVENT_TENANT`, `EVENT_LOCAL`, `EVENT_PARENT_LOCAL`). `ADMIN_TENANT`, `HR_TENANT`, `FINANCIAL_TENANT` and their local equivalents are all refused, and administrator roles are stripped from the session token when it is issued. An administrator who signs in with an email code gets an attendee session, not an admin session. They can moderate the events they manage, but the admin areas of Orgo stay closed until they sign in with their password. Non-member attendees are limited further: their session reaches Event App endpoints only, not your member directory, your finances or anything else. **Which organisation the session belongs to** * On a **custom domain or your organisation's own subdomain**, the login is pinned to your organisation: a code is only sent if the email exists there, and it can only be redeemed on the host it was requested on. There is no way to pivot from your domain into another organisation. * On the shared **app.orgo.space** address, one code signs the person in to every organisation where that email is registered, as a member or as a contact, and they pick from a workspace list. Up to 20 organisations are signed in at once; anything beyond that is available on demand. *** ## My events My events screen on a phone listing event cards grouped under an organisation logo, with a Signed in as line and an avatar button that opens the profile Non-member attendees have no dashboard, so they land on **My events** (`/event-app/my-events`): every event in that organisation where they hold a registration that is Registered or Invited and not cancelled, most recent first, one card each, with a "Signed in as" line showing the verified email. The header opens their profile; the workspace drawer switches organisation or logs out. The screen works for members too. It matches on the verified email rather than on the kind of account, so a member who signs in with a code sees the same list, covering registrations held against their member account and against a contact record carrying the same address. *** ## The tabs The tab strip adapts to the event: | Tab | Appears when | | ---------------- | ----------------------------------------------------------------------------------------------------------------- | | **Program** | The event has at least one sub-event (session). The same label is used for the event sidebar entry that builds it | | **Details** | Always. Date, local time, add to calendar, map link, description, media, speakers | | **Feed** | Always | | **Participants** | Only for people who can manage the event, and only on mobile. This is the administrative roster | | **Networking** | **Visibility of attendee list** is on for the event | | **Vote** | The event has at least one vote that is upcoming, live or closed | | **Profile** | Always | See [Event App: Program, feed and votes](/docs/platform/events/event-app-feed) and [Event App: networking](/docs/platform/events/event-app-networking) for what each one does. Above the tabs, every attendee has a **Badge** button: a QR code identifying their registration, used at check-in and to swap details with other attendees. Event managers also get **Scan QR** next to it. *** ## What organisers configure Everything that shapes the Event App lives on the event itself, under **Features** on the event form. Editing needs the same permission as editing the event: ownership, or `EVENT_LOCAL`, `EVENT_TENANT` or `ADMIN_TENANT`. | Setting | What it does | | ------------------------------- | --------------------------------------------------------------------------------------------------------------------- | | **Visibility of attendee list** | Off: the roster is visible to admins only. On: attendees can see each other, which is what creates the Networking tab | | **Enable 1:1 networking** | Adds meeting booking inside the Networking tab. Cannot be switched on until the attendee list is visible | | **Enable speakers** | Adds the speakers block to the Details tab | *** ## Troubleshooting The event has no **location**, and the shortcut only renders once one is entered. Attendees arriving by email link are unaffected. Their status does not grant access: Registered, Invited and Awaiting invoice payment work, Cancelled, Waitlist and No show do not. Check the participant list. Requests for an address registered nowhere are silently ignored so the screen cannot reveal who has an account. Confirm the address against the participant list, then check the 20 second cooldown and the 10 codes per 5 minutes limit. By design: email-code sessions cap out at member and event-level permissions. Sign out and sign in with the password for the full workspace. The link is that person's credential for the event, so treat it like a ticket. Cancelling the registration invalidates it immediately. *** ## Related * [Event App: networking](/docs/platform/events/event-app-networking) - Attendee profiles, connections and 1:1 meetings * [Event App: Program, feed and votes](/docs/platform/events/event-app-feed) - The in-event surfaces * [Event Attendance](/docs/platform/events/attendance) - Registration statuses and the participant list * [Check-in](/docs/platform/events/check-in) - Scanning badges at the door * [Permissions](/docs/platform/permissions) - What each permission level unlocks # Event App Program, Feed and Votes Source: https://orgo.space/docs/platform/events/event-app-feed The live surfaces attendees use during an event: the session agenda, the announcement feed, in-event voting and the organiser roster Alongside [networking](/docs/platform/events/event-app-networking), the [Event App](/docs/platform/events/event-app) carries four more tabs: **Program**, **Feed**, **Vote** and, for organisers, **Participants**. Each one appears only when there is something in it. Program tab on a phone with a day chip, stage filter chips, and sessions showing times, stage, speaker and an Attend button *** ## Program The agenda is built from the event's **sessions**, which are sub-events of the main event. If the event has no sessions, there is no Program tab and the app opens on Details instead. **Program** is the label everywhere in the interface: this tab, the event sidebar entry that builds it, and the tab on the public event page. Only the underlying addresses still say agenda, which is why the embed URL and the `{eventAgendaUrl}` email placeholder use that word. **What attendees see** * Day chips across the top, then sessions in the order you arranged them. * Per session: title, description, start and end time, place, tags, cover image, speakers, and how many people are attending. * **Search sessions or speakers**, and a stage filter when your sessions use stages. * A toggle between **All sessions** and **My Agenda**, with a count. It appears only once the attendee has marked at least one session. * Tapping a speaker opens their profile with their other sessions and any co-speakers. * A copy-link action for sharing a session. **My Agenda** Attendees mark a session to say they are attending it. Those sessions become their personal agenda, and the count on each session updates. Two rules apply: * Only people with an active registration on the main event can mark sessions. An organiser who is not registered can browse the agenda but not add themselves to sessions, so rosters and reports stay clean. * Sessions someone is attending also affect 1:1 networking: a meeting slot that overlaps one of their sessions is flagged as a clash before they book it. Sessions can be marked as unavailable for networking, which removes that time from the bookable grid entirely. *** ## Feed The Feed is the event's announcement stream. It updates live, so a post published from the organiser's laptop appears on attendees' phones without a refresh. Feed tab on a phone showing category chips, a pinned announcement, an image post with reactions and a reply count **Who can post what** | Action | Who | | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Post to the feed | The event owner, `EVENT_LOCAL` on the event, or `ADMIN_TENANT`. Non-member attendees cannot start a post | | Reply to a post | Any attendee with Event App access, members and non-members alike | | React to a post | Any attendee | | Pin or unpin a post | Same as posting | | Edit a post | The author, plus `EVENT_LOCAL` and `ADMIN_TENANT` on anyone's post | | Delete a post | The author, plus `EVENT_LOCAL` and `ADMIN_TENANT` on anyone's post. A post with replies keeps its place in the thread with its content removed, so the conversation still makes sense | **What a post can contain** Text, images, mentions of other members, and a link preview. Replies can carry images too. Posts can be filed under **categories** that you define per event, each with its own name and colour; attendees filter the feed by category with the chips at the top, or by **Pinned**. Pinned posts sit at the top of the feed, most recently pinned first. **Notifications** Publishing a post notifies every active attendee (in-app, push and email, depending on each person's settings). Replying notifies the author of the post you replied to, unless you are replying to yourself. *** ## Vote The Vote tab appears when the event has at least one vote that is upcoming, live or closed. Drafts never appear. Each vote shows its state: **upcoming**, **Live**, or **Finished**, with the number of questions and the participation rate. Attendees answer every question and submit once; the tab then shows "You voted". Submitting is refused before a vote opens and after it closes. Results follow the vote's own configuration. Some show results immediately, others only once voting has ended, in which case attendees see "Result will be available at the end of the voting period". Votes that stay open until everyone has voted or until an administrator closes them say so on the card. Eligibility to see and cast an event vote is a registration with status Registered or Invited that is not cancelled. Note this is slightly narrower than the rule for opening the app itself, so someone whose registration is awaiting an invoice payment can browse the app but cannot vote. See [E-Voting](/docs/platform/e-voting) for how votes are created and configured. *** ## Participants (organisers only) The Participants tab is the full administrative attendance screen, embedded in the app so organisers can work from a phone at the venue. It shows every registration, including people who have hidden themselves from the attendee directory, with the same filters, columns, invites, exports and status management as the desktop participant list. It appears only for people who can manage the event (`ADMIN_TENANT`, `EVENT_TENANT`, or `EVENT_LOCAL` on that event), and only on phones. On a desktop the event sidebar already offers the same screen, so the tab is hidden to keep the tab strip short. Anyone without the permission who opens the URL directly is redirected to Networking or Program. See [Event Attendance](/docs/platform/events/attendance) for what that screen does. *** ## Badge and scanning Attendee badge modal on a phone showing the event name, the attendee photo and name, and a large QR code Every tab keeps a **Badge** button in the header. It opens the attendee's badge: their name, the event, and a QR code tied to their registration. It is what gets scanned at the door, and what other attendees scan to save a contact or book a 1:1. People who can manage the event also get a **Scan QR** button. Scanning another attendee's badge shows who they are and offers the actions available to you, which include checking that person in when you have the permission for it. See [Check-in](/docs/platform/events/check-in). *** ## Troubleshooting The event has no sessions. Add sub-events to the event and the tab appears; until then the app opens on Details. Marking sessions requires an active registration on the main event. Managing an event is not the same as attending it. Register them for the event and the option appears. Starting a post is limited to the event owner, `EVENT_LOCAL` admins and `ADMIN_TENANT`. Everyone else replies and reacts. This keeps the feed an announcement channel rather than an open forum. Deleting a post that already has replies leaves an empty placeholder so the replies keep their context. Posts with no replies are removed completely. Voting requires a registration that is Registered or Invited. A registration awaiting an invoice payment grants access to the app but not to voting. Take the payment or change the status. *** ## Related * [Event App](/docs/platform/events/event-app) - Access, login and the tab overview * [Event App: networking](/docs/platform/events/event-app-networking) - Directory, connections and 1:1 meetings * [E-Voting](/docs/platform/e-voting) - Creating and running votes * [Event Attendance](/docs/platform/events/attendance) - The participant list and statuses * [Notifications](/docs/platform/notifications) - How attendees receive feed alerts # Event App Networking Source: https://orgo.space/docs/platform/events/event-app-networking Attendee profiles, connection requests and 15-minute 1:1 meetings inside the Event App The **Networking** tab in the [Event App](/docs/platform/events/event-app) is where attendees find each other. It has two halves: **Participants**, a searchable directory of everyone attending, and **My meetings**, the 1:1 meetings they have booked. **Built for** conferences and business events where meeting the right person is the reason people came. Networking tab on a phone showing attendee cards with headline, Connect and Book 1:1 buttons, and search and country filters *** ## Turning it on Two switches on the event form, under **Features**: | Setting | Effect | | ------------------------------- | -------------------------------------------------------------------------------------------------------------- | | **Visibility of attendee list** | Off, the roster is admin-only and there is no Networking tab. On, attendees see each other and the tab appears | | **Enable 1:1 networking** | Adds meeting booking on top of the directory. It cannot be switched on until the attendee list is visible | Editing them needs event ownership, `EVENT_LOCAL`, `EVENT_TENANT` or `ADMIN_TENANT`. *** ## The participant directory Attendees can search by name, filter by country, and filter to people they have saved. Each card shows the photo, name, headline, country, bio (expandable), LinkedIn and Bluesky links, and phone and email when the person has chosen to share them. **Who appears in it** * People whose registration is Registered, Invited, or Awaiting invoice payment, and not cancelled. * Only people with an email address on file. A registration with no email is skipped. * One card per person, even if they hold several tickets. * Up to 500 people. Larger events show the first 500 by surname. Organisers (`ADMIN_TENANT`, `EVENT_TENANT`, `EVENT_LOCAL`) see the full roster in this tab too, including people who hid themselves, with phone and email unmasked regardless of the individual's privacy choices. The **Participants** tab is the same data in the administrative screen. *** ## Privacy controls Every attendee controls their own visibility from the **Profile** tab, and the choice applies to every event they attend, not just this one. | Control | What it does | Default for members | Default for non-member attendees | | ---------------------- | ------------------------------------------------------------------------------------ | -------------------------- | -------------------------------- | | **Profile visibility** | Off: "Only visible to organizers", the person is removed from the directory entirely | Visible | Visible | | **Phone number** | Private hides the number from other attendees | Visible | Private | | **Email** | Private hides the address from other attendees | Private is off, so visible | Private | For members these are the same privacy flags as their normal Orgo profile, so a change made here also applies across the platform, and the other way round. For non-member attendees the flags live on their contact record. Attendees can also edit their photo, headline, bio, LinkedIn, Bluesky and town from the Profile tab. Name, email and phone values themselves are managed on the member or contact record, not here. *** ## Connections **Connect** sends a lasting connection request, the same relationship used elsewhere in Orgo, not just for this event. The recipient accepts or rejects it; the card shows Connect, Pending, Awaits you, or Connected. There is a fifth state: after a rejection the card shows a greyed-out, non-clickable **Connect** tag, visually near-identical to the live button. * Only members can send and receive connection requests. Non-member attendees do not have this button; 1:1 meetings are their equivalent. * One connection per pair of people. * Removing an accepted connection deletes it and the pair can connect again. Rejecting or withdrawing a pending one is effectively permanent from inside the Event App: the card keeps showing a greyed-out **Connect** and the request is refused, and the 21-day cooldown that applies elsewhere in Orgo never lifts here. *** ## 1:1 meetings Meetings are fixed **15-minute** slots. Tap **Book 1:1** on their card, or scan their badge QR code and book from the result panel. The grid shows every 15-minute slot in the event's agenda, day by day, with a status: **available**, **warned**, or **full**. Warned means it clashes with a meeting you already have or with an agenda session you said you would attend. You can still book a warned slot. The meeting is created as **pending** and a space is assigned automatically. Both people get an email and an in-app notification. Accepting moves it to **confirmed**. Declining releases the slot back to everyone else. Either person can cancel a meeting at any point until the slot has passed, and the other one is notified. **How the slot grid is built** * Only days that have at least one agenda session are bookable, and only between the first start and the last end on that day. An event with no agenda has no bookable slots. * Slots are aligned to :00, :15, :30 and :45. * Sessions marked as not available for networking are cut out of the grid. * A slot is full when no space has capacity left. Pending and confirmed meetings hold capacity; declined and cancelled ones release it. **My meetings** groups the results into Pending incoming, Pending outgoing, Confirmed, and Past and canceled, with a day filter across the top. *** ## Networking spaces Spaces are the rooms or tables the meetings happen in. Without at least one space, no slot has capacity and nothing can be booked. Open the event and use **Networking spaces** in the event sidebar. The entry appears once **Enable 1:1 networking** is on, and only for people who can manage the event (event owner, `EVENT_LOCAL`, `EVENT_TENANT` or `ADMIN_TENANT`). Networking spaces admin screen listing spaces with name and capacity per slot, and the Add space form open | Field | Meaning | | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | **Name** | What attendees see on a confirmed meeting, for example "Table 4" or "Lounge" | | **Capacity per slot** | 1 is a single one-to-one table. A higher number allows that many parallel meetings in the same space at the same time. Leaving it empty or setting 0 means **unlimited parallel meetings** | | Order | Spaces are offered to bookings in the order listed. The first one with room takes the meeting | Attendees never choose a space. It is assigned when the meeting is created. Deleting a space keeps existing meetings at their slot but they lose the space reference. *** ## Saved people Scanning another attendee's badge QR code offers to save them. Saved people are filterable in the directory with the **Saved** pill. This is a private, per-event list for the person who scanned. It creates no connection and writes nothing to your contact records. *** ## Troubleshooting **Visibility of attendee list** is off for that event. Turn it on in the event's Features section. Check three things: **Enable 1:1 networking** is on, the event has agenda sessions (the bookable window comes from the agenda), and at least one networking space exists. Either they set their profile visibility to organisers only, their registration has no email address on file, or their registration status is not one that grants access. An organiser sees hidden attendees in this tab anyway, so compare what they describe against what you see rather than against the Participants tab. That is the default for non-member attendees: their phone and email start private and stay hidden until they choose to share. Members start with both visible. Total capacity is the sum of the capacity of your spaces. With one 1:1 table only one meeting can happen per 15 minutes across the whole event. Add spaces or raise their capacity per slot. Connections are a member-to-member relationship. Non-member attendees use 1:1 meetings instead. *** ## Related * [Event App](/docs/platform/events/event-app) - Access, login and the tab overview * [Event App: Program, feed and votes](/docs/platform/events/event-app-feed) - The other in-event tabs * [Create Event](/docs/platform/events/create-event) - Where the Features switches live * [Event Attendance](/docs/platform/events/attendance) - Registration statuses that grant access * [Privacy Settings](/docs/platform/users/privacy-settings) - The member-level privacy flags this shares # Event Reports Source: https://orgo.space/docs/platform/events/event-report Record what an event set out to do, what happened, and what it cost An event report is a short written record attached to the event itself: what it aimed to achieve, what took place, who it was for, how it was promoted, what it cost, and how many people took part. It is free text, filled in by the organiser, and it is what the [Annual Report](/docs/platform/events/annual-report) compiles. Event report form showing the Add to annual report checkbox and the Goals, Activities, Target, Advertising and Budget fields *** ## Turn it on **Settings → Modules → Events → Reporting & Analytics → Event Reports**. Changing it requires `ADMIN_TENANT`. The setting is off by default. Once it is on, every event gains a **Report** entry in the event sidebar, next to Participants and Tickets. *** ## The report form The form has six fields and a save button. Nothing is mandatory, and you can come back and edit it at any time. | Field | What it holds | | -------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | | **Add to annual report** | Checkbox. Includes this event in the local centre's annual report. Only appears when **Annual Event Reports** or **Local Annual Report** is enabled. | | **Goals** | Free text. What the event set out to achieve. | | **Activities** | Free text. What actually took place. | | **Target** | Free text. Who the event was aimed at. | | **Advertising** | Free text. How the event was promoted. | | **Budget** | Free text. What it cost, in whatever form your organisation reports it. | | **Number of participants** | Whole number. Your own headcount for the event. | All five text fields accept line breaks, so you can write short paragraphs or bullet-style lists. They are stored as plain text: there is no rich text editor, no formatting toolbar, and no image upload inside the report. Photos are not part of the report form. They live in the event's own media gallery on the event page, and the annual report pulls its images from there. *** ## Who can fill one in Saving a report writes to the event itself, so it needs the same permission as editing the event: you must be the **event owner**, or hold **EVENT\_LOCAL** for the event's local centre. `EVENT_TENANT` and `ADMIN_TENANT` satisfy that check organisation-wide. The **Report** entry is shown to anyone viewing the event while the setting is on, but a member without edit rights gets an access error when they press Save. Grant the person writing the report event permission first. *** ## Where the report appears | Surface | What is shown | | ----------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | | Event page | A short **Event Report** block with Goals, Activities, Advertising and Budget, shown once at least one of those four is filled in. | | [Annual report](/docs/platform/events/annual-report) | Goals, Target, Activities, Advertising and Budget for every event ticked **Add to annual report**, plus the event's photos. | Target and Number of participants are stored on the event and returned by the API, but no screen in the app displays them. Treat them as data you are recording for export and reporting rather than something members will read. The report block is part of the member-facing event page, not the public one. The report fields are excluded from the anonymous event payload, so nothing you write here is visible to visitors on the [public event page](/docs/platform/events/public-page). *** ## What event reports do not do These are worth stating plainly, because reporting features in other tools often work differently: * **They do not gate anything.** An event can be published, finished, duplicated or deleted whether or not a report exists. No status depends on it. * **They do not have a draft or published state.** A saved report is immediately visible to everyone who can see the event page. * **They do not calculate attendance.** Number of participants is typed in by hand and is never reconciled against check-ins. For counted figures use [Analytics](/docs/platform/events/analytics), which reads the attendee records directly. * **They do not track volunteer hours or SDG alignment.** SDG tags are set on the event itself, not in the report, and are not summarised anywhere in reporting. *** ## Common questions Yes. Anyone with EVENT\_TENANT, or EVENT\_LOCAL for that local centre, can open the event and fill the report in afterwards. There is no time limit. It only renders when **Annual Event Reports** or **Local Annual Report** is enabled in the Events module. With both off, the report is still usable, it just cannot feed an annual compilation. Not from this screen. The annual report gathers them for one local centre over a date range and prints, and the fields are available on the events API for anything more involved. *** ## Related * [Annual Report](/docs/platform/events/annual-report): compiling reports for a local centre * [Analytics](/docs/platform/events/analytics): counted attendance, capacity and revenue * [Attendance](/docs/platform/events/attendance): participant records and statuses * [Events Overview](/docs/platform/events): module settings and the event lifecycle # Event Templates Source: https://orgo.space/docs/platform/events/event-templates Save an event setup once and start every new event from it, tickets and registration form included An event template is a saved blueprint: title, type, location, description, cover image, access settings, registration form, ticket types, and discount codes. Organizers pick a template when creating an event and everything arrives pre-filled. **Built for** organizations that run the same shape of event repeatedly (monthly meetups, a standard training, a recurring gala) and want every organizer to start from the approved setup instead of rebuilding it. **Replaces** the copy-paste-and-hope approach of duplicating last year's event. *** ## Where templates live **Settings → Modules → Events → Templates**. Creating, editing, and deleting templates requires `ADMIN_TENANT`. Templates belong to the whole organization, not to a group or local center. Event templates list showing template cards with Free or Ticket badges, audience badges, ticket counts, and cover thumbnails Each card shows the template name, whether it is free or ticketed, whether it is members-only or public, whether it needs a registration form, how many ticket types it carries, and its default event type. Selecting a card opens it for editing; the trash button deletes it after a confirmation. *** ## Two ways to create one **Settings → Modules → Events → Templates → Create Template**. Open any event, then use **Save as Template** in the event sidebar and give it a name. This copies the event's settings, its live ticket types (skipping archived ones), its vouchers, and its custom registration fields. Requires `ADMIN_TENANT`. *** ## What a template stores Event template editor showing Template Name, Event Defaults, Description, Access and Audience cards, and the registration form builder | Section | Fields | | ----------------- | ---------------------------------------------------------------------------------------- | | Identity | **Template Name** (what admins see in the list; never shown to attendees) | | Event Defaults | **Event title**, **Event type**, **Location** (with Places autocomplete and map preview) | | Description | Rich text, pre-filled into the event description | | Access | **Free** or **Paid** | | Audience | **Members only** or **Public** | | Registration | **Require registration form for members** (locked on for paid), **Max capacity** | | Features | **Enable speakers**, **Send reminder 1 hour before event starts** | | Registration Form | Form fields, form settings, and styling (see below) | | Tickets | Ticket types, when Access is Paid | | Vouchers | Discount codes, when Access is Paid | | Cover image | Uploaded and cropped in the right-hand panel | A template deliberately does **not** carry dates and times, the hosting group, attendees, or speakers. Those are decided per event. ### Registration form The **Form fields** tab is a drag-and-drop builder. Standard fields available: Email and Name (always required), plus Phone, Organisation, Role, Town, LinkedIn, X (Twitter), Instagram, Company Identifier, Company Name, and Company Address. You can also define custom fields with a name and a type: text input, text area, dropdown, radio, checkboxes, date, or yes/no. Dropdown, radio, and checkbox fields need at least two options. The **Settings** tab holds **Disable newsletter subscription**, **Disable register checkbox**, and **Custom text at bottom of registration form** (shown above the consent checkboxes). The **Styling** tab holds **Display title**, **Selected color**, **Button color** and **Hero image border radius**. ### Tickets and vouchers Ticket types carry their name, price, currency, description, seat limit, sort order, group name, members-only flag, and sale window. Vouchers carry a **Code**, a percentage or fixed **Discount type** and value, a **Currency**, an optional **Max discount amount**, **Max uses**, **Max tickets per use**, the **Active** flag, and an optional restriction to specific ticket types. See [Ticketing](/docs/platform/events/ticketing) for what each of those does at checkout. *** ## Using a template On the events list, select **Create an event**. When your organization has at least one template, a **Start from template** button appears in the header of the create panel. Template picker modal listing templates with badges and a preview button, plus No template and Done actions The picker lists every template with its badges. The eye button opens a full preview: cover image, event title, type, location, description, ticket types, vouchers, registration form fields, and max capacity. From the preview you can select **Use this template**. Selecting a template pre-fills the form. You can still change anything before saving. **No template** clears the form back to defaults while keeping the timezone and the group you already chose. When you save, Orgo creates the event and then applies the rest of the template: it copies the cover image, creates the ticket types, creates the vouchers, creates the custom fields, and writes the registration form layout. Template management is admin-only, but the picker itself works for any organizer who can create an event. That is the point: admins curate the setups, everyone else uses them. *** ## Common questions No. A template is applied once, at creation. Events created earlier keep whatever they had. Duplicate copies one specific event, including its group and its agenda, and is quickest for "same event, new date". A template is the right tool when several people create similar events and you want a consistent starting point without them hunting for last year's event. No. The group is always chosen on the event form, because it decides who sees the event and which permissions apply. Ticket buyers have to supply at least a name and email to receive a ticket, so paid events always collect a form. The toggle is shown but locked. *** ## Related * [Create Event](/docs/platform/events/create-event) - the form a template pre-fills * [Event Types and Statuses](/docs/platform/events/event-types) - the type a template can default to * [Ticketing](/docs/platform/events/ticketing) - ticket types, vouchers, and checkout * [Registration forms](/docs/platform/events/registration-forms) - the per-event form builder * [Events overview](/docs/platform/events) - module settings and the event workspace # Event Types and Statuses Source: https://orgo.space/docs/platform/events/event-types Categorize events, mark trainings and general meetings, and track progress with custom statuses Two separate lists shape how events are labelled. **Event types** say what kind of event it is (Workshop, Camp, General Assembly). **Event statuses** say where the event is in your own workflow (Planned, Confirmed, Finalized). Types are always available; statuses are an opt-in feature. **Built for** organizations running more than one kind of event and wanting to filter and report on them. *** ## Event types **Settings → Modules → Events → Event Types**. Creating, renaming, and deleting types requires `ADMIN_TENANT`. Every member can see and choose types. Event types settings page listing type names with inline editing and delete actions, and a Create Event type button A type has one field: its **name**. Select **Create Event type** to add one, or click a name in the table to rename it in place. Once created, the type appears in the **Event type** dropdown on the event form and in the **All event types** filter on the events list. The type name shows on event cards alongside the Free or Ticket badge. Deleting a type does not delete its events. Those events simply lose their type and become uncategorized, which also removes them from type-filtered views. Reassign them first if the history matters. ### The two special types Two settings under **Settings → Modules → Events → Configuration** point at a type and change what the event form shows when it is selected: | Setting | What selecting that type adds to the event form | | ------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Training Event Type** | A **Training type** selector. The event also gains a **Trainers** entry in its sidebar. Members flagged as trainers can pick this type even when their permission level would not normally allow it. | | **General Meeting Event Type** | Three checkboxes: general meeting (set automatically and read-only), elective general meeting, and extraordinary general meeting. Switching away from the type clears all three. | Nothing else about an event changes with its type. Ticketing, capacity, visibility, and permissions are all set on the event itself. *** ## Custom event statuses Statuses are off by default. Turn on **Enable Custom Statuses** in **Settings → Modules → Events → Configuration** and an **Event Statuses** entry appears in the module menu. Event statuses settings listing named statuses with their colors and a final-status marker Each status has: | Field | What it does | | ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Name** | What shows in the status dropdown and the events list filter. | | **Color** | The colour of the status tag. New statuses default to amber. | | **Mark as final status** | Flags the status as an end state. Statuses marked final are labelled **Final** in the dropdown, and saving an event into one shows the organizer a congratulations dialog. Only one status can be final: marking a second one silently un-marks the first. | Creating, editing, and deleting statuses requires `ADMIN_TENANT`. ### Using statuses On the event form, a **Custom Status** dropdown appears above the description with your statuses plus a **None** option. Admins get a **Manage event statuses** shortcut next to it. On the events list, an **All statuses** filter appears next to the event type filter. Custom statuses are a label you control. They are independent of the built-in draft and published states, which decide who can actually see an event. Moving an event to a status named "Cancelled" does not hide it or stop registrations; use **Close registrations** on the event form for that. *** ## Choosing your types Most organizations settle on five to eight types. Fewer and the filter is not worth using; more and organizers start picking at random. Some working sets: | Organization | Types | | ------------------------ | --------------------------------------------------------------------------- | | Youth or scouting | Meeting, Training, Camp, Social Event, General Assembly, Volunteer Activity | | Professional association | Networking, Conference, Webinar, Workshop, Board Meeting, AGM | | Community group | Meetup, Workshop, Social, Fundraiser, Meeting | Statuses work best as a short pipeline, for example Planned, Confirmed, Running, Finalized, with only the last one marked final. *** ## Common questions Not directly. Open the events on the type you want to retire, switch each to the type you are keeping, then delete the empty type. Yes. The type name appears on event cards and members can filter the events list by it, so name them for members rather than for admins. No. One type per event. Use [SDG tags](/docs/platform/events/create-event) if you need a second, multi-value dimension for reporting. The setting keeps pointing at a type that no longer exists, so the training and general meeting fields stop appearing. Pick a new type in **Settings → Modules → Events → Configuration**. *** ## Related * [Create Event](/docs/platform/events/create-event) - where types and statuses get applied * [Event Templates](/docs/platform/events/event-templates) - templates can carry a default event type * [Events overview](/docs/platform/events) - all Events module settings * [Annual Report](/docs/platform/events/annual-report) - reporting across events # Events Source: https://orgo.space/docs/platform/events/index Create events, sell tickets, track attendance, and report on impact Orgo Events lets your organization create and publish events, take free RSVPs or sell tickets, run the event day itself, and report on what happened, all against your member database rather than a separate tool. **Built for** membership organizations running events for members and the public: professional associations, youth organizations, alumni networks, faith communities, and federated nonprofits. **Replaces** Eventbrite for ticketing and RSVP management tied to your member list, not for public marketplace discovery. *** ## What you can do Dates, timezone, location or online link, cover image, capacity, and visibility. Multiple ticket types with seat limits and sale windows, add-ons, discount codes, and Stripe checkout. A page non-members can open and register on without an Orgo account. QR tickets, a scanner in the mobile app, and manual check-in from the participant list. Program, live feed, participants, 1:1 networking, and in-event votes for attendees. Per-event analytics, event reports, and annual summaries. *** ## The events list **Events** in the main menu opens the list: **Upcoming** and **Past** views, a hero card for the next event, a month calendar that dots the days with events, and a filter panel holding a search box over title and description, **All event types**, **All statuses** (only when custom statuses are enabled), **SDG** (only when SDG tagging is enabled), and a **My events** checkbox. **Create an event** opens the form in a panel over the list, with a **Start from template** button when your organization has event templates. *** ## Where events live Every event belongs to one place, chosen in the **Group** field on the event form. | Choice | Who sees it | | ----------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Your organization (the top option in **Main groups**) | Everyone, subject to the audience setting. Only offered if you hold the permission set in **Who Can Create Public Events**. | | A **local center** | People in that center. Creating here follows that chapter's own **Who can create events in this chapter** setting, which is `EVENT_LOCAL` until the chapter changes it. See [chapter event permissions](/docs/platform/groups/local-groups#creating-a-chapter). | | A **group** | Group members. If the group is marked so that only its admins can create events, you need to be a group admin or owner, or hold `ADMIN_TENANT` or `EVENT_TENANT`. | Chapters set their own bar. **Who can create events in this chapter**, on the chapter edit form, is one of **Event managers (default)** (`EVENT_LOCAL`), **Any member of this chapter** (`USER`), or **Chapter admins only** (`ADMIN_LOCAL`). **Any member of this chapter** in practice means any signed-in member of your organisation: chapter membership is not checked. `ADMIN_TENANT` clears all three. `EVENT_TENANT` clears the first two, but not **Chapter admins only**: that one is satisfied by chapter admins and organization admins alone, so an organization-wide event manager is refused there. The setting covers only the chapter it is set on and is never inherited by the chapters below it, and anyone below the bar is refused on save with *You do not have permission to create events in this local center*. Each event is also **Members only** or **Public**. Public needs the **Who Can Create Public Events** permission and is never offered for non-joinable (private) groups. Events start as **drafts** until someone publishes them. A draft appears in the events list only for the person who created it; other managers can open it by direct link, and ordinary members are turned away. See [Create Event](/docs/platform/events/create-event). *** ## The event workspace Opening an event gives it a sidebar whose entries depend on the event's own settings and your permissions. "Manager" below means anyone who can manage the event: its owner, or a holder of the event permissions listed under [Who can do what](#who-can-do-what). Event page with the event sidebar on the left and the event hero, date, location and Get tickets panel on the right The registration panel on the right only appears while the event is still ahead. On a past event the hero carries a **The event has passed** pill and the panel is gone. | Entry | Shown when | What it does | | ---------------------------- | --------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- | | **Modify** | manager | The full event form | | **View event** | always | The event page members see | | **Event app** | the event has a location | Opens the [attendee app](/docs/platform/events/event-app) | | **Participants** | manager | [Participants, invitations, and check-in](/docs/platform/events/attendance) | | **Trainers** | the event uses the training type | Assign trainers | | **Speakers** | **Enable speakers** is on | Add internal members or external people as speakers | | **Networking spaces** | **Enable 1:1 networking** is on | Define where and when meetings can be booked | | **Program** | manager | Build the agenda from sub-events | | **Votes** | manager | [Votes](/docs/platform/e-voting) attached to this event | | **Registration form** | the event requires a registration form | [The form builder](/docs/platform/events/registration-forms) | | **Tickets** and **Payments** | ticketed event, plus `FINANCIAL_TENANT` or `EVENT_TENANT` | [Ticket types and orders](/docs/platform/events/ticketing) | | **Analytics** | manager | [Registration and revenue metrics](/docs/platform/events/analytics) | | **Messages** | manager, and one of `EVENT_TENANT`, `EVENT_LOCAL` or `COMMUNICATION_TENANT` | Email the event's audience | | **Landing page** | the event is public or ticketed | Opens the [public page](/docs/platform/events/public-page) | | **Copy link** | the event is published and public | Copies the shareable URL | | **Report** | **Event Reports** is on | [The post-event report](/docs/platform/events/event-report) | | **Duplicate Event** | manager | Copies everything except attendees into a new draft, optionally in another group | | **Save as Template** | `ADMIN_TENANT` | Turns this event into a reusable [template](/docs/platform/events/event-templates) | | **Email Templates** | `ADMIN_TENANT` | The email templates used by event mail | | **Delete** | manager | Refused if a payment is attached; from five participants up the event is hidden rather than erased | *** ## Module settings **Settings → Modules → Events**, requiring `ADMIN_TENANT`. Events module settings showing Event Configuration, Ticketing and Payments, Reporting and Analytics, and Additional Features sections The module menu also holds **Event Types**, **Templates** and, once the matching setting is on, **Event Statuses** and **Attendance Reminder**. | Setting | What it does | | --------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Who Can Create Public Events** | The permission level needed to create an organization-wide event and to mark any event Public. Defaults to HR Tenant. This is a ceiling: a local event manager cannot exceed it. It does not decide who may create an event inside a chapter, which each chapter sets for itself. | | **Training Event Type** | Which [event type](/docs/platform/events/event-types) marks an event as a training. | | **General Meeting Event Type** | Which event type marks an event as a general meeting. | | **Enable Custom Statuses** | Adds your own event statuses alongside draft and published. | | **Online Ticket Payments** | Listed under Ticketing and Payments. In practice the Paid option on the event form is gated by the Online Payments module being active and by your Stripe connection. | | **Event Reports** | Adds the post-event report. | | **Annual Event Reports** | Generates annual summaries of events. | | **National Annual Report** | Annual reporting at organization level. | | **Local Annual Report** | Annual reporting per local center. | | **Sustainable Development Goals (SDG)** | Adds SDG tagging and the SDG filter. On by default. | | **Enable Attendance Reminder** | Emails the host 24 hours after the event ends to record attendance. | | **Bulk Invites** | Lets organizers invite every member of the event's group at once. | | **Propagate Events to Local Centers** | Lets an `EVENT_TENANT` holder create one event as a published copy in every active local center. Needs the Local Centers module. | | **Restrict Event Editing by User Type** | Lets tenant admins limit which user type may edit a propagated event locally. | | **Disable Company Invoice in Checkout** | Hides the "I want company invoice" option at ticket checkout. Needs the Invoices module. | Paid tickets need Stripe connected first. See [Stripe integration](/docs/platform/fees/stripe-integration). Without it you can create free events and free ticket types only. *** ## Who can do what | Permission | What it unlocks in Events | | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `EVENT_LOCAL` | Create and manage events in their own local center (creating also has to clear that chapter's **Who can create events in this chapter** setting), and manage organization-wide events (events with no group) | | `EVENT_PARENT_LOCAL` | The same, extended across every center below their anchor center, at any depth | | `EVENT_TENANT` | Manage any event, enable ticketing, and propagate events to all local centers | | `FINANCIAL_TENANT` | See the Access (Free or Paid) choice, and the Tickets and Payments tabs | | `ADMIN_TENANT` | Everything above, plus event types, statuses, and templates | Event owners can always manage their own event, whatever their permission level. An event created at organization level has no group, and the permission check treats it as unscoped. Anyone holding `EVENT_LOCAL` can therefore manage organization-wide events, not only events in their own center. Set **Who Can Create Public Events** to a tenant-level permission if that is not what you want. *** ## Related * [Create Event](/docs/platform/events/create-event) - every field on the form * [Event Types and Statuses](/docs/platform/events/event-types) - categories and workflow labels * [Event Templates](/docs/platform/events/event-templates) - reusable event setups * [Ticketing](/docs/platform/events/ticketing) - ticket types, add-ons, and checkout * [Attendance](/docs/platform/events/attendance) - invitations, RSVPs, and check-in * [Public event pages](/docs/platform/events/public-page) - what non-members see # Public Event Page Source: https://orgo.space/docs/platform/events/public-page The standalone event page anyone can open without an account, and exactly what it exposes Some events have a page that anyone can open without signing in: cover image, description, speakers, an agenda when the event has sessions, and a card to register or buy a ticket. **Built for** organisers promoting an event to people who are not members yet, and who should be able to register without creating an account first. **Replaces** a separate event site or ticketing page that has no idea who your members are. Public event page with the cover image and Hosted by block on the left, and the event title, date, location and Get tickets card with ticket types on the right *** ## Which events have one Exactly two kinds, and this is the rule that matters: * events marked **Public**, and * events with **ticketing** enabled, whether or not they are public. Anything else refuses the request. A members-only event with no ticketing returns nothing at the public address: the visitor gets an empty page, not a login prompt and not the event details. Turning on ticketing makes the event page publicly readable even if the event itself is not public. If an event should stay internal, keep it free and use RSVP rather than tickets, and share the in-app link instead. Marking an event public is gated by **Settings → Events → Who Can Create Public Events**. That setting is a ceiling, not an alternative route: if it is set to `EVENT_TENANT`, someone with only `EVENT_LOCAL` who ticks "Public" has the flag silently dropped on save. Events hosted by a private (non-joinable) group can never be public. Ticketing needs `EVENT_TENANT`. `FINANCIAL_TENANT` shows the Paid option and the Tickets and Payments screens, but saving a Paid event still needs `EVENT_TENANT`. *** ## The address ``` https:///public/event/ ``` On the shared domain `app.orgo.space` the link also needs `?workspace=` so the page knows which organisation it belongs to. On a [custom domain](/docs/platform/custom-domain) the organisation is resolved from the domain and no parameter is needed. Open the event and use **Landing page** in the event sidebar to see the page as a visitor does, with the right parameters already attached. The entry appears once the event is public or ticketed. *** ## What a visitor sees | Area | Content | | ----------------------- | ---------------------------------------------------------------------------------------------------- | | Cover image | The event image, falling back to the last photo in the event gallery, then to a coloured placeholder | | Hosted by | Your organisation logo (clicking it opens your public event list) | | Share | Copy the link, or post to Facebook, WhatsApp or LinkedIn. Desktop only | | Title, date, time | With a timezone switcher, so a visitor can read the times in their own zone | | Location | Address, plus a map when the venue was picked from the place search | | Online event | An "online" marker only. The joining link is never sent to the public page | | About | Description, event videos, and SDG icons when **Sustainable Development Goals** is on | | Program | Sessions on their own tab, with times, stages, and session speakers | | Speakers | Speaker cards with photo, headline and bio, grouped by day on multi-day events | | Tickets or registration | Ticket types and prices, or a single **Register** button on free events | Someone who already registered sees their own status instead of the ticket picker: their ticket or registration, a button to show the QR code, and, when the event runs votes, a **Votes** tab. That also works for a non-member ticket holder, whose emailed link carries a personal `hash` parameter that identifies them without an account. The `{eventAgendaUrl}` placeholder in emails and newsletters produces exactly that personalised link. Registration is covered in [Ticketing](/docs/platform/events/ticketing) and [Registration forms](/docs/platform/events/registration-forms). The page also shows state: "Registrations are closed" when the organiser closed them, "This event is full" when capacity is reached, and no registration card at all once the event has ended (after its end time, or 24 hours after the start when no end time was set). *** ## What is never exposed The public payload is a deliberately narrow slice of the event. These are left out entirely, so they cannot leak through the page or through the underlying request: * the online meeting link (visitors see only that the event is online), * the attendee list, and the organiser and hosting group, * the event's draft or published state, and any internal report fields, * **ticket types that name specific membership levels**, which are fetched separately after sign-in and only for a member whose level is on the allowlist. A plain **Members only** ticket, one with no membership levels named, is **not** hidden from the public page. Its name, price and remaining seats are served to anonymous visitors, greyed out with a **members only** badge. Only tickets that name specific levels are withheld. Treat a ticketed event page as public. If a price should not be seen by non-members, do not put it on a ticketed event. Cover images and agenda images are copied into a public storage folder when an event becomes public or ticketed, so they can be served to signed-out visitors. *** ## Appearance Colours and the hero image rounding are set per event under **Registration form → Appearance** (**Selected color**, **Button color**, **Hero image border radius**, **Display title**). That editor only exists on events that require a registration form, which every ticketed event does. See [Registration forms](/docs/platform/events/registration-forms) for the full table. There is no per-event logo control and no theme picker: the page uses your organisation logo and follows the visitor's light or dark preference unless the link carries `?light` or `?iframe`. *** ## Common questions The link is missing `?workspace=` and the visitor has never opened your organisation in that browser. Copy the link from **Landing page** in the event sidebar rather than from your address bar. Yes, if your organisation has a custom domain. The page is then served from it and the workspace parameter is unnecessary. Otherwise it lives on `app.orgo.space`. The `/public/event/...` address has no per-event preview data. Use the short share link instead: it serves a preview page carrying the event title, description and cover image, then forwards to the event. See [Sharing events](/docs/platform/events/sharing). Member-only tickets are only returned to a signed-in member whose current membership level matches the ticket. Ask them to sign in on the same page, then reload. It does. Past events keep their address and keep showing the description, agenda and speakers. Only the registration card disappears. *** ## Related * [Sharing events](/docs/platform/events/sharing) - short links, embeds and the public event directory * [Ticketing](/docs/platform/events/ticketing) - ticket types, pricing and checkout * [Registration forms](/docs/platform/events/registration-forms) - the questions asked at registration * [Create an event](/docs/platform/events/create-event) - visibility, capacity and cover image * [Attendance](/docs/platform/events/attendance) - what happens after someone registers # Event Registration Forms Source: https://orgo.space/docs/platform/events/registration-forms Build the form each event asks at registration, from a fixed list of profile fields plus your own questions Every event can ask its own questions when someone registers. A conference needs dietary requirements and an organisation name; a members' evening needs almost nothing. **Built for** organisers who need more than a name and an email from the people attending, and who want the answers to land on the member's profile and in the participant export rather than in a spreadsheet somewhere else. **Replaces** a Google Form bolted onto an event page, with the answers already attached to the right attendee record. The form belongs to the individual event, so building it well once does not carry over to the next. *** ## Turning the form on Open the event, go to **Modify**, and under **Registration** switch on **Require registration form for members**. A **Registration form** entry then appears in the event sidebar. Without it, members simply RSVP. Editing the form needs `EVENT_LOCAL` on the event's group, which `EVENT_TENANT` and `ADMIN_TENANT` satisfy tenant-wide. Ticketed events always use a registration form. Switching an event to **Paid** turns this on automatically and locks the toggle, with the hint "Paid events always require a registration form". Switching an event's audience to **Public** turns it on too, though there the toggle stays editable. *** ## Building the form The **Form fields** tab is a two-panel builder: **Available fields** left, **Form fields** right. Click or drag a field across to add it, drag rows to reorder, tick **required** where an answer is mandatory, then **Save changes**. Registration form builder with Standard fields and Custom fields tabs on the left and the assembled form on the right, each row carrying a required checkbox ### Standard fields Twelve fields, no others, and their labels cannot be edited. For a logged-in member they arrive prefilled, so the member confirms rather than retypes. | Field | Notes | Written back to the profile | | ------------------- | --------------------------------------------------- | ------------------------------------------------------------------------- | | **Email** | Always present, always required, cannot be removed. | No | | **Full Name** | Always present, always required, cannot be removed. | No | | **Phone** | Country prefix selector. | Phone number | | **Organisation** | | Profession organisation (and, for a non-member contact, the company name) | | **Role** | | Profession organisation role | | **Town** | | No | | **LinkedIn** | | Matching profile social link | | **X.com** | | Matching profile social link | | **Instagram** | | Matching profile social link | | **Company ID** | | No | | **Company Name** | | No | | **Company Address** | | No | Write-back happens only when the answer is not empty and differs from what is stored. Fields marked **No** are still collected and exported, just not copied onto the profile by this path. Removing Email or Full Name through the API silently puts them back at the top of the form on save. ### Custom fields Anything the standard list does not cover becomes a custom field: use **Create** on the **Custom fields** tab of the left panel. | Type | Behaviour | | ----------------- | ------------------------------------------------------------ | | **Text input** | Single line. | | **Text area** | Multi-line. | | **Dropdown** | Select one from a list. Needs at least two options. | | **Radio buttons** | Choose one, all options visible. Needs at least two options. | | **Checkboxes** | Choose several. Needs at least two options. | | **Date** | Date picker. | | **Yes/No** | A switch. | Options for the three list types are entered one per row and can be dragged into order. Deleting a custom field also removes it from the form layout, and needs the same permission as editing the form. Event custom fields belong to that one event. They are not the organisation-wide [custom fields](/docs/platform/users/custom-fields), they do not appear in the picker on any other event, and there is no way to copy them across. Budget for rebuilding them on each event, or start the event from an [event template](/docs/platform/events/event-templates). *** ## Settings tab | Setting | What it does | | ---------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | | **Disable newsletter subscription** | Hides the "I want to subscribe to the newsletter" switch from the form. | | **Disable register checkbox** | Hides the "I want to create an user account on the online community" switch that anonymous registrants otherwise see. | | **Custom text at bottom of registration form** | Free text shown after the fields, before the consent checkboxes: house rules, refund terms, cancellation policy. | Settings tab of the event registration form showing the two registration option switches and the custom text box Consent checkboxes are not configured here: the GDPR checkbox appears when your organisation has a GDPR policy URL, the terms checkbox when it has a terms URL. Both come from [Organisation Info](/docs/platform/organisation/organisation-info). *** ## Appearance tab | Setting | What it does | | ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | | **Display title** | A switch under its own **Display** heading at the top of the tab, on by default, recording whether the form's title is shown above the fields. | | **Selected color** | Highlight colour for the selected ticket and other accents on the public event page. Defaults to `#FFE089`. | | **Button color** | Colour of the primary buttons on the public event page. Defaults to `#3173EE`. | | **Hero image border radius** | Corner rounding of the event's hero image, for example `14px`. | **Hero image border radius** is only applied when **Selected color** also has a value, so set a selected colour if you want the rounding to take effect. *** ## Where the answers end up * **Custom field answers** are stored per registration, on that attendee's record for that event. The same person answering differently at two events keeps two answers. * **Standard answers** update the profile as in the table above. * **The participant export** contains exactly the standard fields on the form, plus every custom field, once a form layout has been saved. An event that requires a form but has no saved layout exports all ten profile fields instead, and an event that does not require a form exports six legacy fields: phone, organisation, role, LinkedIn, X and Instagram. Checkbox, radio and dropdown answers export as their visible labels, dates as `YYYY-MM-DD`. Exporting needs `EVENT_TENANT`, `EVENT_LOCAL` on the event, or event ownership. Decide what you need before the event: you cannot ask retrospectively. Be sparing with **required**, since every mandatory field is a reason to abandon registration, and on a paid event that is a lost sale. Test in a private window: the form an anonymous visitor sees is not the one you see as an administrator. *** ## Troubleshooting It appears only when **Require registration form for members** is on for that event, and only for someone who can edit the event. Public event pages are cached. Saving the form clears that cache for public and ticketed events, so reload the public page itself, in a private window, rather than the editor. Standard field labels are fixed. Add a custom field with the wording you want and leave the standard field off the form. Build the event once with its form and custom fields, save it as an [event template](/docs/platform/events/event-templates), and create future events from that. The export includes only the standard fields currently on the form. Remove a field after people registered and their answers stop appearing in the export, even though the profile values remain. *** ## Related * [Create an Event](/docs/platform/events/create-event) - the Registration section of the event form * [Ticketing](/docs/platform/events/ticketing) - paid registration, which always uses this form * [Event Templates](/docs/platform/events/event-templates) - reusing a form across events * [Custom Fields](/docs/platform/users/custom-fields) - organisation-wide fields, which are a different thing * [Attendance](/docs/platform/events/attendance) - the participant list and its export # Sharing Events Source: https://orgo.space/docs/platform/events/sharing Short share links with social previews, the public event directory, and embedding events or an agenda on your own site Once an event has a [public page](/docs/platform/events/public-page), there are three ways to put it in front of people: a short link built for social media, a directory of everything coming up, and embeds for your own website. **Built for** organisers who post events to Facebook or LinkedIn, keep an events page on their own site, and want both to stay current without copying details around. **Replaces** manually maintained "upcoming events" pages and hand-built social cards. *** ## The short share link Open the event and use **Copy link** in the event sidebar. It appears once the event is published and public. The first time you use it, the event is given a permanent seven-character code and a small preview page is published for it. You get a link shaped like: ``` https:///share/ ``` The preview page exists for one reason: social platforms and messaging apps read a page's preview tags before showing a card, and they do not run the event page's JavaScript. It carries the event name as the title, the first 256 characters of the description as the summary, the event cover image, and your organisation's icon. A visitor who clicks it is forwarded to the event about a second later. It forwards to the event's public page with your organisation and interface language already set in the address, so nothing else needs to be appended by hand. Copying the link again republishes the preview page, so a new title or cover image is picked up. Facebook, LinkedIn and X cache previews aggressively, so use their own preview debugging tools if an old card keeps appearing. Visitors can share too. The public event page has a **Share** button that copies the link or hands it to Facebook, WhatsApp or LinkedIn. *** ## The public event directory Every organisation has a page listing its public events: ``` https:///public/events?workspace=&upcoming=1 ``` From inside the app, open **Events** and use **Public events** in the header to jump to it. Visitors reach it by clicking your logo on any public event page, or "Explore events" on a phone. Public event directory showing the next event as a large hero card, a list of upcoming events with dates and cover images, and a month calendar with event dates marked It shows only events that are both **published** and **public**. A ticketed event that was never marked public has a working page of its own but is never listed here. | Element | Behaviour | | --------------- | --------------------------------------------------------------------------- | | Hero card | The next upcoming event, shown large above the list | | Upcoming / Past | Two pills; past events stay browsable indefinitely | | Calendar | Inline month calendar on desktop, with dates that have events marked | | Event cards | Date, title, location and cover image, each opening the event's public page | Visitors get no search box and no filters. Those controls are for signed-in members on the internal event list. *** ## Embedding on your own website The directory and the agenda are both embeddable in an `iframe`. Adding `iframe=true` to the address strips the page down for embedding: it hides your logo and the "built with Orgo.space" line, and forces the light theme so the embed does not turn dark on a visitor whose device prefers dark mode. ```html theme={null} ``` Give it generous height. The embed does not resize its parent frame, so a short frame cuts the list off rather than scrolling neatly. If your organisation uses the built-in website, its "Upcoming events" section already embeds this exact page for you, so you do not need to paste anything. *** ## Embedding the agenda For a conference the agenda is often what people want on the website. Open the event, go to **Program**, and use **Iframe URL**. The button only appears when the event is public or ticketed. It copies an address of the form `https:///public/event-agenda/?workspace=&iframe=true`, ready to drop into an `iframe`. The embed shows the sessions grouped by day with their times, stages and locations, and speaker cards that open a profile with the speaker's bio and their other sessions. The event title is hidden in embed mode so it sits under your own heading. Embedded event agenda showing sessions grouped by day with start and end times, stage labels and speaker avatars, without the event title Session data is cached for five minutes, so a change to the schedule shows up on the embed shortly after you save it. For events that are neither public nor ticketed the address returns "not found", which is the same rule the public page follows. *** ## Print and QR codes The public page address is a plain URL, so any QR code generator can turn it into a code for posters and flyers. Nothing in Orgo needs to be configured for that, and the code keeps working as long as the event exists. Do not confuse it with the QR code an attendee receives after registering. That one identifies the person, not the event, and is what gets scanned at [check-in](/docs/platform/events/check-in). *** ## Search engines Crawling is not blocked, but do not plan a search strategy around it. The public event page is a JavaScript application whose browser tab title is your organisation name, not the event name. The only page that serves proper title, description and image tags to a machine reading the raw HTML is the short share link's preview page, which is what makes social cards work. If search visibility matters, publish the event on your own site and link out to the Orgo page for registration. *** ## Permissions | Action | Needs | | --------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | | Mark an event public | The level set in **Settings → Events → Who Can Create Public Events** | | Enable ticketing | `EVENT_TENANT`. `FINANCIAL_TENANT` shows the Paid option and the Tickets and Payments screens, but saving a Paid event still needs `EVENT_TENANT` | | Copy the share link, publish the preview page | Event owner, `EVENT_LOCAL` on the event's group, or `EVENT_TENANT` | | Copy the agenda embed address | Access to the event's **Program** screen: owner, `EVENT_LOCAL` or `EVENT_TENANT` | `ADMIN_TENANT` satisfies all of these organisation-wide. *** ## Related * [Public event page](/docs/platform/events/public-page) - what the page shows and what it never exposes * [Ticketing](/docs/platform/events/ticketing) - tickets, pricing and checkout * [Create an event](/docs/platform/events/create-event) - visibility, cover image and description * [Custom domain](/docs/platform/custom-domain) - serving public pages from your own domain * [Check-in](/docs/platform/events/check-in) - the attendee QR code and scanning at the door # Speakers and Trainers Source: https://orgo.space/docs/platform/events/speakers-trainers List the people presenting at an event, on the event page and per agenda session, and record who trained what An event can list two kinds of people who are not simply attending: **speakers**, who appear on the event page and sell the event, and **trainers**, who are recorded against training events and show up on the member's own profile. **Built for** conferences, general meetings and training programmes where the line-up is part of the offer and the record of who taught what has to survive the event. **Replaces** a hand-written line-up on a landing page, and a separate list of who ran which course. Neither list registers anybody for the event. A speaker who also needs a seat, a badge or a QR code must be added on **Participants** as well. See [Attendance](/docs/platform/events/attendance). *** ## Speakers ### Turning the list on Open the event → **Modify** → **Features** → **Enable speakers**. A **Speakers** entry then appears in the event sidebar. ### Adding speakers **Add speaker** opens a search across members and contacts. Pick as many as you need; they stack up in a list before you commit. **Create new speaker** takes a full name and an optional email. If the email matches an existing member or contact, that record is used instead of creating a duplicate. Otherwise a new contact is created. The button confirms the count, for example **Add 3 speakers**. Adding somebody twice is rejected. ### What the audience sees Each speaker is rendered as a card with their photo, name, role and organisation, and their bio. Speakers tab of an event listing speakers with profile photos, names and bios All of that comes from the underlying member profile or contact record. There are no speaker-specific fields, so to fix a title or a bio you edit the person: the pencil on a speaker card opens the member's profile edit screen, or the contact record for a non-member. Speakers show on the event page inside Orgo and on the [public event page](/docs/platform/events/public-page), which is the argument for filling in a decent photo and headline before you publish. ### Speakers per session Events with an agenda can give each session its own speakers. Edit a session and use the same search and **Create new speaker** controls there. Session speakers are independent of the event-level list, so somebody chairing two sessions is listed on both. ### Permissions | Action | Who | | ------------------------ | ------------------------------------------------------------------------------------------------------- | | Add a speaker | The event owner, or `EVENT_LOCAL` on the event's group, which `EVENT_TENANT` and `ADMIN_TENANT` satisfy | | Edit or remove a speaker | The event owner, or `ADMIN_TENANT` | Removing a speaker is narrower than adding one. Somebody with `EVENT_TENANT` who does not own the event can add speakers but cannot delete them. Either hand the event over or ask an organisation administrator. *** ## Trainers Trainers exist only where the organisation runs training as an event type. ### Prerequisite Set **Settings → Modules → Events → Configuration → Training Event Type** to one of your [event types](/docs/platform/events/event-types). A **Trainers** entry then appears in the sidebar of every event using that type, and nowhere else. ### Managing the list **Add trainer** searches members only: a trainer has to be a member record, because the assignment is written back to their profile. Removing one asks for confirmation and needs the event owner or `ADMIN_TENANT`. Trainers carry no dates, topics or rates. The record is simply "this member trained at this event". ### The trainer flag on a member A member's **Permissions** tab (member → **Modify** → **Permissions**) has an **is Trainer** checkbox, visible once a Training Event Type is configured. Editing that tab needs `HR_LOCAL` on the member's local centre, and `HR_TENANT` when the organisation does not let local admins change permissions. The flag does two things: * the member may create events of the training type, even without the permission that event type normally requires; * their profile gains a **Trainer** section listing the trainings they led. ### On the member's profile With a Training Event Type configured, a profile shows a **Trainings** card: the training events the member attended, and, for a flagged trainer, the trainings they ran. Both lists link straight to the events. Certifications on a profile are typed in by hand and are not produced by attending a training. Nothing in Orgo turns an attendance record into a certificate automatically. *** ## Troubleshooting **Enable speakers** is off for that event. It is per event, not organisation-wide, so a new event starts without it. Either the organisation has no Training Event Type set, or this event is not using that type. Check the event's type first. Fix it on the person, not the event. Members show their profile headline and photo; contacts show their organisation and logo. The change appears on every event they speak at. Correct: speakers and trainers are separate lists. Add them on **Participants** too if they need a seat or a ticket. They are on the event-level list already. Session-level speakers are stored separately, so check the agenda session as well before assuming it is a bug. *** ## Related * [Attendance](/docs/platform/events/attendance): the participant list, where speakers also need a place * [Create an Event](/docs/platform/events/create-event): the Features section and the event type * [Event Types](/docs/platform/events/event-types): including the type used for training * [Public Event Page](/docs/platform/events/public-page): where the speaker line-up is shown * [QR Check-in](/docs/platform/events/check-in): getting speakers through the door # Event Ticketing Source: https://orgo.space/docs/platform/events/ticketing Sell tickets with multiple price tiers, member pricing, addons, vouchers and QR check-in Orgo Event Ticketing sells event tickets from inside your membership platform, with member-only pricing tied to your fee levels, addons, discount vouchers, and QR code check-in. **Built for** membership organisations running paid events for members and non-members: professional associations, youth organisations, alumni networks, trade unions, and similar member-based groups. **Replaces** Eventbrite, Ticket Tailor or Cvent with ticketing tied directly to your member database and your own Stripe account. Orgo charges no per-ticket fee, you pay only Stripe's rate. Buyers pay by card in an inline Stripe checkout, receive a ticket by email, and check in at the door by QR scan. Tickets page for an event showing the Allow only one ticket per order switch, three ticket types with price, availability tags and seat counts, and the start of the Addons section The same screen continues below the fold with the rest of [Addons](#addons) and then [Vouchers](#vouchers). *** ## Turning ticketing on Ticketing is a property of the individual event, not a module you switch on once. The **Online Payments** module must be active and your Stripe account connected, otherwise the **Paid** option does not appear on the event form. See [Stripe Setup](/docs/platform/fees/stripe-integration). On the event form, under **Access**, choose **Paid** instead of **Free**. This section is only visible to users with `FINANCIAL_TENANT` or `EVENT_TENANT`. A **Tickets** entry appears in the event sidebar. Open it and add one or more ticket types. Tickets appear on the [event page](/docs/platform/events/public-page) as soon as they are within their availability window. Switching an event to **Paid** also forces **Require registration form for members** on, and the toggle becomes read only. Every ticket buyer goes through the [registration form](/docs/platform/events/registration-forms), never a simple RSVP. The **Max capacity** field disappears from the event form once ticketing is on, and event-level capacity is not applied to ticket sales. Cap attendance with **Max Seats** on each ticket type instead. The **Tickets** and **Payments** sidebar entries appear only for `FINANCIAL_TENANT` or `EVENT_TENANT`, and only once the event is Paid. Every write on the Tickets page (ticket types, addons and vouchers alike) requires `EVENT_TENANT`, which `ADMIN_TENANT` satisfies. `EVENT_LOCAL` alone can run the event and edit its [registration form](/docs/platform/events/registration-forms) but cannot change what is on sale. *** ## Ticket type settings Open the event, then **Tickets** in the sidebar, then **Add ticket**. | Setting | What it does | | ------------------------------------------ | -------------------------------------------------------------------------------------------- | | **Title** | What buyers see: "Member Ticket", "Guest Ticket", "Early Bird". | | **Price** | Amount in your organisation's currency. Set to 0 for a free registration category. | | **Description** | Longer text shown under the ticket name on the event page. | | **Availability** | **Members & external** (anyone) or **Members only**. | | **Restrict to specific membership levels** | Members-only tickets only. Pick one or more membership fee levels; empty means every member. | | **Max Seats** | Seats for this ticket type. Empty means unlimited. | | **Available from** / **Available until** | Purchase window. Cannot start before the event was created or end after the event ends. | The **Price** field is read only once a ticket has been created. To change a price, add a new ticket type and let the old one expire. **Allow only one ticket per order**, a switch at the top of the Tickets page, hides the quantity controls so a buyer can select one ticket per checkout. ### Availability tags The ticket list labels each ticket automatically: **Active**, **Upcoming** (start date in the future), **Expired** (end date passed), **Sold Out**, **Only N left!** (fewer than 10 seats), **Limited availability** (fewer than 20 seats), and **archived**. The public page is vaguer: the exact count at 10 seats or fewer, "limited" between 11 and 20, nothing above 20. *** ## Member pricing **Members only** tickets stay visible to logged-out visitors but cannot be selected. They carry a **members only** badge, and the page shows a notice with **login** and **register** buttons. **Members only** checks that the browser is signed in, and nothing else. It does not check that the person is one of your members, that their account is active, or that their fee is paid. Any signed-in account can select the ticket. Use it to put the right price in front of the right person and to stop your own members choosing the wrong tier. Do not rely on it to keep a member rate away from non-members. If a price must not reach the public, do not put it on a ticketed event. Adding levels under **Restrict to specific membership levels** narrows this to buyers whose recorded membership level is on the allowlist. Two things about that comparison are worth knowing: * It reads the level stored on the member's record, **not whether that membership is still paid up**. A lapsed member on a listed level still matches. * A member who does not qualify is **not refused, they simply never see the ticket**. It is absent from the list with no badge and no explanation, which is why the usual report is "the members ticket is not on the page". A member with no membership level assigned sees no level-restricted tickets at all. **Only one membership-restricted ticket is allowed per attendee per event**, counted across the whole event rather than per ticket type. That count includes only attendees linked to a member account, and only tickets that carry named levels. These checks are skipped when the person doing the booking holds `EVENT_TENANT`, holds `EVENT_LOCAL` on the event's group, or owns the event, so an organiser can still book on someone's behalf. The test is against the person doing the booking, not the person attending. The membership level list is read from your organisation's [membership fee](/docs/platform/fees/fees) product. If no membership fee product is configured the dropdown is empty, and **Members only** then simply means any signed-in member. Two tickets with adjoining availability windows give you early bird then regular pricing; a members-only ticket beside a members-and-external one gives you member and non-member prices; tickets priced 0 still separate members from guests. *** ## Common ticket structures Every structure below is built from the same ticket type fields. The amounts and dates are **examples**, not defaults: nothing here is preconfigured. | What you want | How to build it | | ------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Early bird, then regular** | Two ticket types on the same event. "Early Bird" at 60, **Available until** 31 March 23:59. "Regular" at 80, **Available from** 1 April 00:00. Both stay listed all along: the early bird turns **Expired** and the regular sits at **Upcoming** until its window opens. Neither is selectable outside its window. | | **Member versus non-member** | "Member" at 40 with **Availability** set to **Members only**, "Standard" at 70 with **Members & external**. A logged-out visitor sees both, can select only Standard, and gets the login and register prompt on the member one. | | **Tiered access by membership level** | Start from a members-only ticket, then add levels under **Restrict to specific membership levels**: "Student rate" at 25 restricted to your Student level, "Full rate" at 55 restricted to Standard and Senior. A member whose level is not listed is refused. Because only one membership-restricted ticket is allowed per attendee per event, these tiers are mutually exclusive by construction. | | **Free event with categories** | Price every type 0: "In person" with **Max Seats** 120, "Online" with no seat limit. A zero-priced ticket goes through free registration with no card step, so the attendee still fills in the registration form and still gets a QR ticket. An event where every ticket has a price cannot be used for free registration. | | **Paid event with one free category** | Mix them: a paid ticket type and a 0 priced one on the same event. The free one is completed without a card; the paid ones go to Stripe. | | **One ticket per person** | Turn on **Allow only one ticket per order** at the top of the Tickets page. For anything larger, note that one browser session can hold at most 10 tickets per event, so a company buying 12 places has to do it in two checkouts. | A ticket priced 0 is not the same as a members-only ticket priced 0. Price decides whether Stripe is involved; **Availability** decides who can select it. You can combine them freely. *** ## Addons Addons are extras sold alongside a ticket: a meal, a workshop track, parking, a partner place. They live in the **Addons** section of the Tickets page, and you need at least one ticket type first. | Setting | What it does | | ------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Tickets** | Which ticket types the addon is offered with. At least one is required, and the selection is locked once the addon exists. | | **Name** | What buyers see, for example "Spouse/Partner". | | **description** | Detail line under the name. | | **price** | Cost per unit, read only after creation. Set to 0 for a free extra. | | **Max per ticket** | How many of this addon one ticket can carry. Empty means unlimited. | | **Total inventory** | Overall stock across all buyers. Empty means unlimited. When it runs out the addon shows **Sold Out**. | | **Creates a separate attendee** | The buyer fills in a separate name and email, producing its own attendee record, ticket and check-in, linked back to the ticket that bought it. This is how you sell a "+1". | An addon that has been purchased cannot be deleted. Set **Archived** on it instead, which hides it from checkout while keeping the sales history. Archiving is available on the older addon editor at `/events/edit/addons/`, which you have to reach by typing the URL. *** ## Vouchers Vouchers are per-event discount codes, listed under **Vouchers** on the Tickets page. Buyers enter the code at checkout under **Have a voucher code?**. | Setting | What it does | | ----------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | | **Voucher code** | Stored and matched in upper case, and unique within the event. | | **Active** | Turns the code off without deleting it. Shown when editing. | | **Discount type** | **Percentage** or **Fixed amount**. | | **Discount value** | The percentage (max 100) or the fixed amount. | | **Currency** | Fixed-amount vouchers only. Defaults to your organisation currency. | | **Max uses** | Number of separate checkouts that may use the code. Each checkout counts once whatever the ticket quantity. Empty means unlimited. | | **Max tickets per use** | Percentage vouchers only. Caps how many tickets in one order the percentage applies to. | | **Max discount amount** | Percentage vouchers only. A ceiling on the money taken off. | | **Restrict to ticket types** | Empty applies the code to every ticket type. | | **Valid from** / **Valid to** | Optional date window. | The list shows each voucher's status (**Active**, **Upcoming**, **Expired**, **Limit reached** or **Inactive**) and its usage count. A voucher that takes the order to zero completes without a card payment. Deleting a voucher does not change discounts already applied to past orders, and a refund does not give a use back. ### How the discount is worked out A fixed-amount voucher comes off the order total once, not off each ticket. A percentage voucher is the one that surprises people, because the percentage is applied to the order's **average** ticket price, multiplied by the number of tickets it is allowed to cover. **Example.** An order of two Regular tickets at 80 and one Student ticket at 25 totals 185. | Voucher | Discount taken | Why | | ---------------------------------------------------------- | -------------- | ---------------------------------------------------------------------------------------------------- | | 20%, no other limits | 37.00 | 20% of the whole 185. | | 20%, **Max tickets per use** 2 | 24.67 | The average ticket is 61.67; two of them is 123.34; 20% of that. Not 20% of the two dearest tickets. | | 20%, **Max tickets per use** 2, **Max discount amount** 20 | 20.00 | The cap wins. | | 20%, **Restrict to ticket types** Regular | 32.00 | Only the two Regular lines count, so the average is 80. | If you want a percentage to apply to specific tickets, set **Restrict to ticket types**. **Max tickets per use** limits how many tickets are covered but does not choose which ones. *** ## Seat holds When a buyer starts selecting tickets, the seats are held so two people cannot buy the last one at the same time. * A hold lasts **8 minutes**, reset to a fresh 8 minutes when the buyer adds more of the same ticket. * One browser session can hold at most **10 tickets** per event, counted across ticket types. Beyond that the buyer is told how many more they can hold. * Holds are released when the buyer leaves the page, when the purchase completes, or by the `app:cleanup-expired-holds` job once they expire. * Held seats are unavailable to everyone else, so a ticket can read "Sold Out" while carts are open and free up again when they expire. *** ## What a buyer sees Event checkout with the registration form on the left (email, full name) and an order summary on the right showing the ticket, total, the newsletter and company invoice options, and Pay with Card Listed cheapest first. Sold out, upcoming and expired tickets are shown but not selectable. One card per ticket, collecting every attendee's details; logged-in members arrive prefilled. See [Registration Forms](/docs/platform/events/registration-forms). Addons appear under **Extras** in the order summary. A voucher code can be applied and removed before paying. The buyer confirms your GDPR policy and terms, then pays inline through Stripe without leaving the page. A paid order sends the buyer one confirmation email with every ticket attached as its own PDF, including tickets created by addons. On a free order each attendee registered under a different email address gets their own confirmation too. With the **Invoices** module on, the checkout also offers **I want company invoice**. Ticking it adds a billing step for company details, after which the buyer can still pay by card or choose **Pay via bank transfer**, which issues an invoice and confirms the tickets once payment arrives. Hide the option with **Settings → Events → Disable Company Invoice in Checkout**. *** ## Orders The **Payments** entry in the event sidebar opens the order list, headed **Orders**. Event orders table with order id, status, buyer name, amount and created date columns, and a Generate Invoice action per paid order Each row shows the order id, status, the buyer (member or contact), amount, the voucher code if one was used, and the payment date. Filter by name, email, or status (**open**, **paid**, **refunded**); rows can also read **on-hold** or **canceled**. Where a Stripe account is connected, an arrow link opens the payment or invoice in the Stripe dashboard. The **Ticket type** column stays empty for event ticket orders. It reads a product *option*, which is a fee-product concept; event ticket purchases record the ticket tier as the product *price* instead. To see which tier someone bought, use the Ticket column on [the participant list](/docs/platform/events/attendance) or the Revenue by ticket table in [Analytics](/docs/platform/events/analytics). **Refund** appears on paid orders that were paid by card and requires `FINANCIAL_LOCAL` or higher. It refunds the full amount, with no partial refund in the interface, and on success cancels every attendee record created by that order, returns their seats to the ticket type, and returns any addon quantities to stock. Voucher usage is not returned. Orders paid by bank transfer have no Refund button: handle those in Stripe or through [invoice cancellation](/docs/platform/fees/cancelling-invoices). With the Invoices module on, an `ADMIN_TENANT` user gets a **Generate Invoice** button on paid orders that have no invoice yet, and a **View Invoice** link once one exists. *** ## Tickets and check-in Every attendee record carries a random token that becomes their QR code, delivered in the confirmation email and shown on the event page. Scanning it at the door opens the check-in screen with the attendee's name, ticket type, payment status and addons. Attendee view of a confirmed registration on the public event page, with the Registration confirmed badge and the QR code to show at the entrance Scanning requires `HR_TENANT` or `EVENT_TENANT`. A local event admin with only `EVENT_LOCAL` cannot scan. The full flow, walk-ins and manual check-in are covered in [Check-in](/docs/platform/events/check-in). A member can download their own ticket as a PDF from the internal event page, and an administrator can download someone else's only with `HR_LOCAL` over that person. The public event page above has no download button: it renders the status badge and the QR code only. *** ## Common scenarios Use a [voucher](#vouchers). It is the only discount mechanism in Orgo: there is no automatic group or bulk pricing. There is no self-service transfer. An administrator cancels and refunds the original registration, then invites the replacement as a complimentary attendee or has them buy a ticket. Prices are locked after creation because payments reference them. Add a corrected ticket type and set the wrong one's **Available until** to now, or delete it if nobody has bought it. Seats in other people's carts count as taken. Wait for the 8 minute hold to clear before raising **Max Seats**. Check that their membership fee is active and on a matching level, then whether they already hold another membership-restricted ticket for this event: only one is allowed. Turn on **Close registrations** on the event form. No new registrations or ticket purchases are accepted, and existing attendees keep their tickets. *** ## Troubleshooting Deletion is blocked as soon as the ticket type has history, and the message names the reason: payments taken against it, attendees registered on it, or use by a ticket bundle. The records that point at it have to keep pointing at something. Set its **Available until** to now instead: it stops selling, keeps its history, and shows as **Expired** in the list. The purchase window has to sit inside the event's own lifetime: **Available from** cannot be earlier than the date the event was created, and **Available until** cannot be later than the event's end (its start, if no end is set). The form also nudges the two dates apart by an hour if you set them so that the end falls before the start. One browser session can hold at most 10 tickets per event across all ticket types, and the message tells the buyer how many more they may take. This is a cap on a single cart, not on the event: they complete that checkout and start another one for the rest. "Invalid voucher code" covers four cases at once: the code does not exist on **this** event (vouchers are per event, so a code created on last year's event will not carry over), it is switched off with **Active**, it is outside its **Valid from** / **Valid to** window, or it has reached **Max uses**. Codes are stored and matched in upper case, so capitalisation in the email you sent does not matter. See [How the discount is worked out](#how-the-discount-is-worked-out). The usual causes are **Max discount amount** capping the money, **Max tickets per use** limiting how many tickets the percentage covers, or the percentage landing on the order's average ticket price rather than on the dearest tickets. "Name can only contain letters, spaces, hyphens, apostrophes and periods." Something that is not a name went into a name box, most often a phone number. Orgo checks every buyer, attendee and addon-attendee name before the card is charged rather than after, so the money is never taken. One order cannot mix currencies. This only happens when ticket types on the same event were saved with different currencies; rebuild the odd one out in the event's currency. Three separate limits produce three different messages: **Max per ticket** ("Maximum N of X per ticket allowed"), **Total inventory** ("Only N X available"), and an archived addon ("no longer available"). Inventory counts sales across all buyers, so it can run out mid-event. There is no resend button. A signed-in member can open the event page and download their own ticket as a PDF; an administrator with `HR_LOCAL` over that member can download the same PDF and forward it. The QR code is fixed when the attendee record is created and never regenerated, so a re-downloaded ticket scans exactly like the original, and an attendee who shows the QR from the original email is equally valid. They count differently, and both are right. The **Sold Out** and **Only N left!** tags on the admin ticket list subtract only tickets already sold. The public page also subtracts seats currently held in other people's carts, so it can warn buyers, or refuse them outright, while your list still looks comfortable. The two converge once the open carts are paid for or their 8 minute holds expire. Refunding returns seats and addon stock but never a voucher use. On a limited-use code, raise **Max uses** by the number of orders you refunded, otherwise the code retires early. *** ## Related * [Create Event](/docs/platform/events/create-event) - the event form and its Access setting * [Registration Forms](/docs/platform/events/registration-forms) - what buyers are asked * [Public Event Pages](/docs/platform/events/public-page) - where tickets are sold * [Check-in](/docs/platform/events/check-in) - QR scanning and walk-ins * [Stripe Setup](/docs/platform/fees/stripe-integration) - connecting the payment account # Cancelling & Correcting Invoices Source: https://orgo.space/docs/platform/fees/cancelling-invoices Void an invoice raised in error, mark a paid one as refunded, and return money through Stripe Invoices get raised in error. Someone books twice because the first confirmation never arrived, an administrator creates a test registration to check the payment flow, or a member is invoiced on the wrong plan. Which action you need depends entirely on whether money changed hands. | Situation | Action | Where | | --------------------------------------------------------------------- | -------------------- | ------------ | | The invoice is unpaid and should not exist | **Void** | The invoice | | The invoice was paid and you have already returned the money yourself | **Mark as refunded** | The invoice | | The customer paid by card and you need Stripe to send the money back | **Refund** | **Payments** | All three need administrator rights: voiding and marking refunded need `ADMIN_TENANT`, and the Stripe refund needs `FINANCIAL_LOCAL` for the payment's local centre, or `FINANCIAL_TENANT` when the payment has no local centre on it. *** ## Voiding an unpaid invoice **Invoices**, open the invoice, then **Void**. The button only appears while the invoice is unpaid, and the action cannot be undone. Voiding sets the invoice to **voided** and leaves it in the list. That is the point: an invoice that vanishes leaves an unexplained gap in your numbering and no answer to the question "what happened to invoice 214?". A voided one answers it. For an **event registration** invoice, voiding also unwinds the booking. Every registration still waiting on that invoice is cancelled and the seats it held are released back to the ticket, along with any add-ons. The payment record attached to the invoice is cancelled too. You do not need to remove the attendee separately. A plain unpaid invoice has no payment record to cancel. One is only created when the invoice is marked as paid, so voiding an unpaid manual invoice touches nothing but the invoice itself. *** ## Duplicate bookings When someone registers twice, void the duplicate rather than removing the person. Keep the invoice the member has already paid or already sent to their finance department. Ask if you are unsure, because the reference they quoted internally is the one that must survive. If it is unpaid, **Void** removes it from your totals and, for an event invoice, frees the seat. Voiding releases seats held by registrations that were still awaiting payment. A registration that was already confirmed is not touched by a void, because a confirmed registration means the invoice was paid, and a paid invoice cannot be voided. Do not use a real member's account to test a payment flow. If you later mark that invoice paid while tidying up, the member is emailed a paid invoice for something they never bought. *** ## Marking a paid invoice as refunded A paid invoice cannot be voided. The action offered instead is **Mark as refunded**, and it is exactly what it says: **it does not move any money.** Use it after you have already returned the money yourself, by bank transfer or in Stripe. Confirmation dialog asking the administrator to confirm the customer was already refunded externally before marking the invoice as refunded What it does do is unwind everything the payment set off: * The invoice becomes **refunded**, with your name and the date recorded, and a **REFUNDED** badge added to the document. * The linked payment record is marked refunded, so it drops out of your totals. * On a **membership** invoice, the member's fee validity date is recalculated from the payments that survive, and a company's membership is rolled back to what its remaining payments justify. * On an **event registration** invoice, the confirmed registrations are cancelled and their seats and add-on places are released. A refunded invoice reports nothing as settled and its full total as still outstanding, rather than continuing to read as paid in full. Marking as refunded does not email the customer. Tell them yourself. A paid manual or membership invoice with no payment record behind it cannot be marked refunded: the action stops with an error rather than changing the invoice and leaving the payment untouched. An event registration invoice is more forgiving: if no payment or registration can be resolved it is still marked refunded, on the assumption the money was handled in Stripe. *** ## Returning money through Stripe If the customer paid by card and you want Stripe to send the money back, do it from **Payments**. Open the row menu on the payment and choose **Refund**. The option only appears on a successful payment that has a Stripe charge behind it. The refund covers that payment row in full. There is no partial-amount option in the interface, and where one charge produced several payment rows (a membership fee and its separate joining fee, for example) only the row you acted on is refunded. Refunding through Stripe also cancels any event registrations paid for by that payment, releasing their seats and add-on places, and recalculates the member's fee validity if the payment was for a membership fee. Do not mark an invoice as refunded and expect the customer to get their money. The invoice will read refunded while the money stays where it is, and nobody will notice until they ask. *** ## Related * [Recording a payment](/docs/platform/fees/record-payment) marking an invoice paid * [Invoices](/docs/platform/fees/invoices) creating invoices, numbering and templates * [VAT and invoice templates](/docs/platform/fees/vat) tax details on the document * [Stripe integration](/docs/platform/fees/stripe-integration) card payments and payouts * [Membership fees](/docs/platform/fees/fees) how fee validity is calculated # Donation Pages & Widgets Source: https://orgo.space/docs/platform/fees/donation-pages The public donation page and its editor, donor messages, the donor wall, and embeddable donation widgets Everything a donor sees. Setting up the campaign itself, its suggested amounts, currencies and payment tracking is covered in [Donations](/docs/platform/fees/donations). Public donation page with hero image, progress bar toward the campaign goal, campaign story, and the donation form with suggested amounts *** ## Page addresses Campaigns live at `https:///pay/`. The slug is generated from the campaign title and editable on the campaign form; without one the page falls back to `/pay/i/`. Your **default donation product** also answers on the short paths `/donate`, `/doneaza` and `/presedinte`. Pick which campaign that is under **Settings → Online Payments → Donation Product**; the first donation campaign you create claims it automatically. **Copy link** on the campaign header publishes the landing page and copies a short URL, `https:///share/product/`, which the in-page **Share** button and the social preview also use. The page needs no login to give, and no publish step beyond saving. *** ## The landing page editor The **Landing page** tab edits the public page against a live preview you can flip between mobile and desktop framing. Nothing applies until **Save**. Landing page tab with hero media image and video tabs, appearance controls, campaign content editor, and a live preview of the public page ### Hero media **Image** uploads a campaign photo, shown full width at the top. **Video** takes a YouTube URL and embeds the player in the hero slot instead. ### Appearance | Setting | What it controls | | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Logo header bar** | Your organization logo above the page. Separate desktop and mobile switches | | **Title** | The campaign name printed on the page. Separate desktop and mobile switches | | **Primary color** | Accent for the donate button, progress bar and selected amounts: a hex value or one of nine presets (Forest, Green, Teal, Blue, Navy, Purple, Burgundy, Slate, Red) | | **Hero border radius** | Hero image corner rounding: 0, 8, 14 or 24 pixels. Desktop only | ### Content **Description** is the campaign story, in a rich text editor. It sits under **About this campaign** when the campaign has a goal, under the title when it does not, and truncates behind a **Show more** control. **Thank you message** overrides the default confirmation text shown after a successful donation. The editor prints the default underneath so you can see what you are replacing. ### Social share preview Upload the image used when the link is pasted into a chat or posted socially. The editor previews the card with your payment host and campaign name. Recommended size is 1200 x 630 pixels, under 1 MB. *** ## What a donor sees * Hero image or video, the campaign title and, with a goal set, a progress bar reading "X raised of Y goal", the donation count, and either the target date or the completion percentage. On mobile that becomes a progress ring. * The campaign story. * **Words of support** from other donors, if messages are enabled. * The donation form: a **Give once / Monthly** toggle when both frequencies are enabled, suggested amount buttons, a custom amount field, **Cover the processing fee** with the amount spelled out, and a **Designate to** dropdown when the campaign has options or a chapter picker. * Name, email, optional phone, a full address when **Require full address** is on, and optional checkboxes to leave a message, stay confidential, subscribe to the newsletter, or create an account. * The donor wall and a **Share** button in the sidebar. * Stripe takes payment inline. The donor then sees your thank-you message, a share prompt, and gets a thank-you email. A campaign that is archived still loads, but the form is replaced with a notice that payments are disabled. Archive rather than delete: a campaign with any payment on it cannot be deleted. ### Confidentiality **Enable payment confidentiality** gives the donor a checkbox that keeps their name off the public page. The gift still counts toward the goal and the donation count, but the donor wall and their message show "anonymous". With **Confidentiality Agreement Mandatory** on, the donor must accept the confidentiality notice before the donate button unlocks. *** ## Donor messages With **Messages of support from donors** enabled, a donor can attach a message to their gift. Approved ones appear in **Words of support** on the public page, 30 at a time, newest first, names shortened to a first name and a surname initial, or "anonymous" for confidential gifts. Donor message moderation list showing every message on the campaign, each row with the date, donor, amount, message, an approved status, and a Delete button in the Actions column Messages are published immediately, not held for review. A message attached to a payment that is successful or on hold is stored as **approved**, so moderation is after the fact: you review the list and take down anything you do not want. There is no pending queue to work through. Moderation lives on the campaign under **Comments**. Filter by donor name, message text or status (approved, rejected), and press **Refresh** to pull new ones. The **Status** column carries each message's own state, and the **Actions** column beside it holds the buttons: **Delete** rejects a message and pulls it off the public page, **Approve** puts a rejected one back and appears only on the rejected ones. Both need FINANCIAL\_LOCAL on the chapter the gift was designated to, or FINANCIAL\_TENANT when it carries no chapter designation, which is every gift on a campaign without a chapter picker. ADMIN\_TENANT covers both. Every message on the campaign above is approved, which is the normal state, so none of the rows offers **Approve**. *** ## The donor wall **Display top 50 recent donations** adds a live panel to the page sidebar: the running count, the five most recent gifts with initial, amount and relative date, and a "N persons just made a donation" flash when several arrive at once. **See all** opens a paginated list of every donation, 50 at a time; **See top** opens the largest gifts. Confidential donors show as "anonymous" throughout. Donations dialog opened from the donor wall, with All and Top tabs over the full list of gifts showing donor initials, amounts and relative dates, above the public page and its recent donations panel *** ## Donation widgets Widgets put the donation form on a website you already run. The **Widgets** tab creates and manages them; each carries its own configuration and statistics. Create one by choosing its type and giving it a name and a title. Widgets tab showing two donation widget cards, one popup and one embed, each with its widget ID, creation date and its total, one-time and recurring donation counts and amounts A full donation form rendered inline in a container you place on your page. A floating button that opens the donation form in an overlay. Good for sidebars, footers, and blog posts. ### Configuration **Configure Widget** opens a full-screen editor with a live preview, grouped as follows. | Group | What it holds | | ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | **Basic Information** | Widget title, description, hero image | | **Button Appearance** (popup) | Button text, button color, position: bottom right, bottom left, top right, top left | | **Embed Appearance** (embed) | Primary, background, text, button text, unselected button and CTA colors, border radius | | **Content Settings** | Show title, subtitle, link text and link URL (validated as a real http or https address) | | **Donation Settings** | Default currency (13 options), widget language (Romanian, English, German, French, Spanish, Italian), default donation type (one-time or monthly), and, for popup widgets only, show monthly upsell and require address details; preset amounts for one-time and for monthly, initial suggested amount | | **Button Text Customization** | Overrides for the monthly, one-time, continue, payment and donate button labels, and for the details, payment, success and thank-you headings | Leave a text override empty and the widget uses the translation for its configured language. Donation widget configuration screen with basic information, appearance and donation settings on the left and a live widget preview on the right ### Embedding **Copy Embed Code** gives a ready-to-paste snippet: a popup widget is one script tag carrying the widget id; an embed widget is a container div carrying the widget id and the color settings, plus the script tag. Both load from Orgo's CDN and handle the whole flow through to the Stripe payment. The widget id is public by design and the widget config endpoint is open, so anyone with the id can render your donation form. Delete a widget you no longer want live rather than just removing the snippet from your page. ### Widget statistics Each widget card reports **Total**, **One-time** and **Recurring** donation counts with the amounts behind them, so you can compare placements. The campaign's **Stats** tab also splits views and donations between widget traffic and the public page. *** ## Goal tracking | Setting | What it does | | ---------------- | ---------------------------------------------------------------------------- | | **Total goal** | Target for cumulative one-off donations | | **Monthly goal** | Target for recurring monthly revenue | | **Goal value** | The amount to reach, in your organization's currency | | **Target date** | Optional deadline, printed under the progress bar in place of the percentage | The bar fills to the share of the goal raised and caps its display at 100%. Passing the goal does not stop donations. Goals are not available on multi-currency campaigns, since there is no single number to total toward. *** ## Related * [Donations](/docs/platform/fees/donations) - creating a campaign, prices, payments, refunds * [Products](/docs/platform/fees/products) - product types and pricing * [Stripe Integration](/docs/platform/fees/stripe-integration) - connecting payment processing * [Newsletter widgets](/docs/platform/newsletter-widgets) - the same widget system for email signups * [Permissions](/docs/platform/permissions) - who can edit campaigns and moderate messages # Donations Source: https://orgo.space/docs/platform/fees/donations Run fundraising campaigns with suggested amounts, goals, price A/B testing, donor messages, and embeddable widgets A donation campaign in Orgo is a product of type **Donation**. It gets a public payment page, suggested amounts, an optional goal, donor messages, and embeddable widgets, and every gift lands in the same payments ledger as your fees and ticket sales. **Built for** membership organizations and nonprofits that fundraise from supporters alongside membership dues: youth organizations, faith communities, alumni networks, advocacy groups. **Replaces** standalone donation-page tools for goal-based campaigns, suggested-amount A/B testing, and embeddable widgets. It is not a peer-to-peer or team fundraising tool. Donation product detail on the Prices and Options tab, showing the suggested amount tiers with their amounts, descriptions and a default marker, recurring tiers tagged Recurring, and the start of the Product options card *** ## Before you start * **Online Payments** must be on (**Settings → Modules → Online Payments**). It is on by default. * A **Stripe account must be connected**, or the one-off payment option cannot be enabled at all; a campaign owned by a local center needs that chapter's own account. See [Stripe Integration](/docs/platform/fees/stripe-integration). * **FINANCIAL\_TENANT**, or **FINANCIAL\_LOCAL** for a local-center campaign, to create, edit or delete one. The same permission gates the payments list, widgets, and message moderation. *** ## Donations vs fees | Use **Donations** when | Use **[Fees](/docs/platform/fees/fees)** when | | ----------------------------------------- | ---------------------------------------- | | Contributions are voluntary | Payment is required for membership | | The donor chooses the amount | The amount is fixed per tier | | Anyone can give, members and non-members | Only existing members pay | | Goal-based (raise a target for a project) | Period-based (annual dues) | Both are products, so both share prices, payments, invoices, and Stripe. Only donations get goals, donor messages, the donor wall, and widgets. *** ## Creating a campaign **Finance → Products → Create Product**, then pick the **Donation** card. Donation product form showing the Donation and Membership Fee type cards, the title with its generated URL slug and public address preview, the Recurring and One-off frequency cards, the custom amount minimum and maximum, and the start of the Campaign block | Step | What to set | | ------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Name it and check the URL | The **URL Slug** is generated from the title as you type, and the form previews the public address `https:///pay/`. Slugs are unique per organization. | | Choose the frequency | **Recurring** (a monthly subscription) and **One-off** are independent toggles; turn on either or both. Once a campaign has been saved with only one of them, you cannot switch it off without turning the other on first. | | Allow a custom amount | **Enable custom amount** is on by default for donations. Set an optional **Minimum** and **Maximum** in your organization's currency; with multiple currencies, the same limits apply to all of them. | | Add a campaign goal (optional) | Under **Campaign**, pick **Total goal** (cumulative one-off donations) or **Monthly goal** (recurring revenue per month), enter the **Goal value**, and optionally a **Target date**. The goal type selector appears only when both frequencies are enabled, and goals are not available for multi-currency campaigns. | ### Campaign settings Donation products only, on the create and edit form: | Setting | What it does | | --------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ | | **Disable newsletter subscription** | Hides the newsletter checkbox on the payment page | | **Messages of support from donors** | Lets donors leave a message with their gift | | **Display top 50 recent donations** | Shows the anonymized donor wall on the public page | | **Disable register checkbox for non-members** | Hides the "create an account" option (only shown when **Create Accounts for External Buyers** is enabled for the organization) | | **Require full address** | Asks for full name, address, and postal code before payment | | **Enable payment confidentiality** | Gives the donor a checkbox to keep their name off the donor wall and comments | | **Has local center option** | Lets the donor pick a chapter to designate the gift to (needs **Products with Local Center Option** enabled) | | **Belongs to a local center** | Scopes the whole campaign to one chapter | The first **organisation-level** donation product you create is registered as the organization's default donation product. A campaign scoped to a chapter never claims it. That default is what the shortcut URLs `/donate`, `/doneaza`, and `/presedinte` resolve to. You can change it later under **Settings → Online Payments → Donation Product**. *** ## Suggested amounts and options The **Prices & Options** tab holds everything the donor picks from. **Prices** are the suggested amount buttons: name, amount, currency, description, tagged **One-time** or **Recurring**. Mark one as the **default** (pre-selected on load), and archive retired ones rather than deleting them so past payments keep resolving. A new campaign arrives with six suggested amounts already created (50, 100, 200, 300, 500 and 1000 in your organisation currency, with 100 pre-selected), plus a matching recurring set when **Recurring** is on. Edit or archive them to suit your campaign. **Generate** only appears while a campaign has no prices at all, so you have to clear the seeded ones first. It reads your organization's country and currency and the campaign title and description, then creates three A/B variations of three amounts each, registers the prices in Stripe, and switches A/B testing on. **Product options** are the designations a donor chooses from, such as which program the gift funds. Add them inline, drag to reorder, rename in place, and archive when a designation closes; each has its own shareable link that pre-selects it on the public page. They appear under **Designate to** at checkout, and when **Has local center option** is on a **Support chapter** entry is appended to the same dropdown and opens a chapter picker. ### A/B testing suggested amounts Turn on **Pricing A/B Testing** to run more than one set of suggested amounts side by side. Add a variation, drop prices into it, and enable it. Traffic is split evenly between the enabled variations, and the split percentage is shown on each row. Pricing A/B Testing card with two enabled variations, each showing its assigned suggested amounts, traffic share, and total, average, and transaction count Each variation reports **total** raised, **average** donation, and **transaction** count, and one that has already collected money cannot be deleted. While A/B testing is on, "Make default" on individual prices is hidden: the variation decides what a donor sees. *** ## Tracking the money **Payments** lists every donation with its status, donor, location, designation, amount, date, confidentiality flag, and type (one-time or recurring). Everyone who can open the list can filter by payment ID, payer name, user ID, date range, type and status. The email, designation and chapter filters, and the **Record payment** button, are shown only to FINANCIAL\_TENANT. Donation payments list with filter pills for payer name, payment ID, user ID, email, status, type and date, and rows showing the amount, status, donor, chapter, date and whether the gift was one-time or a subscription **Refund**, from the row actions, returns the full amount through Stripe and moves the payment to `refunded`; only a payment already in `success` can be refunded, and one still on hold is cancelled instead. Both actions need FINANCIAL\_LOCAL on the chapter the donation was designated to, or FINANCIAL\_TENANT when it was not designated to one. ADMIN\_TENANT covers both. A chapter treasurer cannot refund an undesignated gift. **Subscribers** lists the recurring donors on the campaign: name, status, chapter, designation, amount, and identity-validation state where that is required. Statuses are Active, Canceled, Canceling, No identity upload, Identity validation pending, Waiting for subscription, and Pending. An admin can cancel a subscription from here with **Unsubscribe**. Subscribers list for a donation campaign with filters for ID, name, email and status, and rows showing recurring donors with their amount and subscription status **Stats** is page analytics rather than a payments chart: all-time **Views**, **Clicked**, and **Shared**, views over time (daily or monthly), device distribution, sessions, a widget-versus-public-page comparison for both views and donations, and UTM source, medium, and campaign breakdowns for both views and donations. Charts can be downloaded as images. Stats tab for a donation campaign showing all-time views, clicked and shared counters above a views-over-time chart *** ## What the donor pays **Cover the processing fee** lets the donor add the payment processing cost on top, so the full intended amount reaches you. The fee shown is 2.9% of the amount plus a fixed per-currency component, for example 0.30 USD, 0.25 EUR, 0.20 GBP, or 1.20 RON. Donations are supported in 19 currencies: USD, EUR, GBP, CAD, AUD, CHF, DKK, NOK, SEK, PLN, CZK, HUF, BGN, RON, HRK, JPY, MXN, SGD, HKD. Each carries its own minimum charge (0.50 USD and EUR, 0.30 GBP, 2.00 RON), so a very small custom amount can be rejected even when your own minimum allows it. After a successful one-off donation the donor sees your thank-you message on the page and, as soon as Stripe confirms, gets a **donation thank-you email** with the amount and the campaign name, customizable under **Email Templates**. Your version has no language of its own: it is sent to every donor as written. See [Email templates](/docs/platform/emails/email-templates). Offline gifts (cash, cheque, bank transfer) are not handled by the public page. Record them from the member's payments view instead, which requires FINANCIAL\_TENANT. See [Recording payments](/docs/platform/fees/record-payment). *** ## Two other places donations show up **Supporters.** Nominate one campaign as the **Recurring Donation Product** under **Settings → Online Payments**. A member with an active, non-confidential subscription to it is flagged as a supporter on their profile and in the member directory. Cancelling clears the flag; a subscription the donor marked confidential never sets it. **Donation ask at fee checkout.** A membership fee product can carry an optional donation prompt on its own checkout, configured under **Settings → Modules → Membership Fees** with its own prompt text, minimum and maximum. Separate from a donation campaign; see [Membership Fees](/docs/platform/fees/fees). *** ## Common questions Set a **Target date**. When a goal is set, the public progress bar shows that date instead of the completion percentage, which is what creates the deadline pressure. The date does not stop payments by itself; archive the campaign to close it, which replaces the form with a "payments disabled" notice. Enable both frequencies. The public page then shows a **Give once / Monthly** toggle with a "Boost your impact by giving monthly" prompt. In widgets, set **Default Donation Type** to monthly and leave **Show Monthly Upsell** on. Yes, if **Enable payment confidentiality** is on. The donor ticks the box and their name becomes "anonymous" on the donor wall and on their message; their identity is still recorded on the payment for your records. A campaign with any recorded payment cannot be deleted. Archive it instead, which keeps the history and stops new donations. *** ## Related * [Donation pages and widgets](/docs/platform/fees/donation-pages) - the public page, donor messages, embeds * [Products](/docs/platform/fees/products) - product types, prices, and payment settings * [Stripe Integration](/docs/platform/fees/stripe-integration) - connecting payment processing * [Membership Fees](/docs/platform/fees/fees) - required, non-voluntary payments * [Local Center Fees](/docs/platform/local-group-fees/create-local-fees) - chapter-level collection # Membership Fees Source: https://orgo.space/docs/platform/fees/fees Collect membership dues, track who has paid, send reminders, and manage subscriptions Orgo Membership Fees is the dues collection and billing module that charges, tracks and reconciles member payments. **Built for** membership organisations collecting dues from a distributed member base: professional associations, alumni networks, youth organisations, faith communities and federated nonprofits. **Replaces** the spreadsheet that tracks who has paid. It is not accounting software; payment data feeds into that. *** ## How the pieces fit A membership fee is a product of type **Membership Fee** with one price per membership level. Each member is assigned one of those prices. A successful payment stamps a billing period on the member, and the end of that period becomes their **valid fee date**, which reminders, mandatory-fee gating and chapter statistics all read. *** ## Setting up Payments and Fees module settings with Membership Fees, All Members Fee Eligible and Event Ticket Sales toggles All three steps require `ADMIN_TENANT`. **Settings** → **Payments & Fees** → **Payment Gateway**. Without it you can still record payments by hand, but members cannot pay online. See [Stripe Integration](/docs/platform/fees/stripe-integration). **Finance** → **Products** → **Create Product** → **Membership Fee**. Set **Period** and **Cycle beginning**, then add one price per membership level. See [Products](/docs/platform/fees/products). **Settings** → **Payments & Fees** → **Membership fees** → **Enable Membership Fees**, then pick the **Membership Fee Product** and its **Default Price**. Nothing charges until it is selected here. *** ## Membership fee settings Membership fees settings showing Enable Membership Fees, the Membership Fee Product and Default Price selectors, and the Payment Options and Local Center Configuration sections | Setting | Section | Default | What it does | | ------------------------------------------------ | -------------------------- | -------- | -------------------------------------------------------------------------- | | **Membership Fee Product** / **Default Price** | Product Configuration | none | The fee product members are billed against and the price new members get. | | **Allow Bank Transfer Payments** | Payment Options | off | Shows your IBAN as a payment option. | | **Enable Membership Payments via Bank Transfer** | Payment Options | off | Extends bank transfer to membership fees specifically. | | **Allow Mark as Paid** | Payment Options | on | Lets HR record a fee as paid without a card charge. | | **Local Center Fees Enabled** | Local Center Configuration | off | Turns on a second, chapter-level fee. | | **Minimum Members per Local Center** | Local Center Configuration | 25 | Below this paid count, a chapter is flagged on the Stats table. | | **Minimum Active Members Percentage** | Local Center Configuration | 100% | Same flag, expressed as a share of the chapter's active members. | | **Lifetime Membership Available** | Validity Period | off | Allows a price to be marked lifetime. | | **Fee Valid Days** / **Fee Valid Months** | Validity Period | 0 / 0 | Grace kept after expiry. Zero means no grace. | | **Fixed Starting Date for Fees** | Validity Period | off | Anchors periods to the product's cycle month instead of the payment date. | | **Allow Next Year Payment** | Eligibility Rules | on | Lets members pay the next period before the current one ends. | | **Advance Payment Window (Months)** | Eligibility Rules | 1 month | How early a multi-month fee may be paid. | | **Advance Payment Window (Days)** | Eligibility Rules | 7 days | How early a monthly fee may be paid. | | **Minimum Cycles to Pay** | Eligibility Rules | none | Forces members with arrears to settle several cycles at once. | | **Who Can See User Fee Status** | Eligibility Rules | Any User | Any User, Local HR, Tenant HR or Tenant Admin. | | **Enable Age Restrictions on Prices** | Pricing Options | off | Adds age-conditioned prices. | | **Enable VAT on Fees** | Pricing Options | off | While off, no VAT is charged, even on prices that store a rate. | | **Enable One-time Registration Fee** | Pricing Options | off | While off, no registration fee is charged. | | **Fee Payment Mandatory** | Membership Requirements | off | Restricts the platform for members whose fee has expired. | | **Continuity Mandatory** | Membership Requirements | off | Requires an unbroken payment history. | | **Require Contract for Membership** | Membership Requirements | off | Members must sign the membership contract before paying. | | **Company Fee Payment Mandatory** | Membership Requirements | off | Gates company members on the company's fee instead of their own. | | **Auto-deactivate on Fee Expiry** | Membership Requirements | off | Sets members inactive after expiry. Requires **Fee Payment Mandatory**. | | **Days Until Deactivation** | Membership Requirements | none | Grace before deactivation, 1 to 365 days. The job runs daily at 07:00 UTC. | A **Checkout donation** section adds an optional gift to the membership checkout, with an optional custom amount and prompt. *** ## What a payment buys **Fixed Starting Date for Fees** decides the period: * **Off (anniversary):** the period runs from the payment date for the product's number of months, ending the day before the anniversary. An annual fee paid on 1 September covers to 31 August. * **On (fixed cycle):** the period is anchored to the product's **Cycle beginning** month, so a September-anchored annual fee always runs 1 September to 31 August and a January payment buys only the remainder. Proration decides the price, not the end date. With **Enable pro-ratio for shorter first cycle** off, a mid-cycle payer still ends on the cycle boundary and pays in full; with it on the amount is reduced for the remaining months, unless **Number of months after cycle begining to start pro-rate** vetoes it for members who join in the opening months of the cycle. ### Worked example: joining mid-cycle **An example, not a default.** An annual membership priced at 120, **Period** 12 months, **Cycle beginning** September, with **Fixed Starting Date for Fees** and **Enable pro-ratio for shorter first cycle** both on. | The member joins | The period on offer | Charged | | ---------------- | ------------------------- | -------------------------- | | September 2025 | 1 Sep 2025 to 31 Aug 2026 | 120, the whole cycle | | January 2026 | 1 Jan 2026 to 31 Aug 2026 | 80, eight months of twelve | | June 2026 | 1 Jun 2026 to 31 Aug 2026 | 30, three months of twelve | Every partial period still ends on the cycle boundary, so everyone renews together on 1 September. Now set **Number of months after cycle begining to start pro-rate** to 3. Anyone joining in the first three months of the cycle (September, October, November) is charged the full 120 instead, and proration only starts with a December join. The setting exists so that a member joining a few weeks late does not get a discount for it. Proration is measured from the member's join date, not from the day they pay: a member who joined in January but only settles in June still buys the January to August period at 80. *** ## Which price a member pays Each member carries an assigned membership price, per level, plus an optional local one. For a given date Orgo resolves the amount in this order: 1. The effective-dated assignment covering that date. 2. The member's current assigned price. 3. The version of that price that was valid on the date. 4. The organisation **Default Price** (age-appropriate, when age restrictions are on). Raising a price therefore never reprices history: a 2024 payment still resolves against the 2024 version. On **Finance** → **Local members fees** the fee column is a per-member dropdown, and the change is recorded against the fee year on screen, so a member can sit on one level this year and another next. The first future-dated change pins the member's current level to the current cycle, so promoting the new level later cannot reprice earlier periods. The change is refused with a conflict once a successful payment covers the target cycle or any later one; the lock icon marks the rows the server would refuse. **Example.** With **Cycle beginning** September, the fee year labelled 2026 means 1 September 2026 to 31 August 2027, and in July 2026 the current fee year is still 2025. So in July 2026 you can move a member from Student to Standard for 2026 even though they have paid 2025 in full: the earliest period the change touches is 1 September 2026, and no payment reaches it yet. Once that member pays 2026, the 2026 dropdown locks and only 2027 onwards remains editable. *** ## The valid fee date Fee validity is not hand-set. It is the furthest period end among the member's successful, unrefunded payments for the fee product, recomputed whenever a payment is recorded, approved or refunded. Recording an older period never pulls the date backwards. Local fees keep a separate date. Two prices bypass payment: a **lifetime** price with no amount sets validity 100 years out, and a price marked **Is only assignable by admins (hidden for members)** with no amount sets validity to today plus the product period each time it is applied. That covers honorary and free memberships. The admin-only price does not add to whatever the member already had, so re-applying it to a member with longer remaining validity shortens it. Exemption comes from the user type, not the individual: a user type with **Not eligible for fee** on, the organisation's designated non-eligible user type, or an active user-type role carrying that flag. Exempt members are never assigned a fee and see "You are not eligible for paying fees" on their profile. *** ## Collecting payments | Method | How it works | | ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Online** | Members pay from their profile's fee tab or a payment link, but only once their fee has expired or the advance-payment window has opened. | | **Bank transfer** | With **Allow Bank Transfer Payments** and **Enable Membership Payments via Bank Transfer** on, and the Invoices module configured, a member raises an unpaid membership invoice and gets your account details plus its series as the reference to quote. It is settled with **Mark as paid** on that invoice, and never appears on **Fee payments**. | | **Mark as paid** | With **Allow Mark as Paid** on, an admin picks the periods to settle on the member's fee tab. If part of the period is already covered, Orgo charges only the remainder. | | **By someone else** | A parent listed as managing a member can pay for them, and companies can cover their members. A company-covered member sees "Membership managed by" instead of a pay button. | On the **Local members fees** table an admin may only record a payment for a member they manage: chapter and organisation finance admins for their whole scope, unit admins only for members in their own units. **Mark as paid** is a finance-admin action and is not offered to unit admins at all. ### Worked example: recording a part-paid year **An example, not a default.** A member on a 120 level with a September cycle already paid 30 by card for 1 June to 31 August 2026. An administrator now ticks the whole 1 September 2025 to 31 August 2026 cycle under **Mark as paid**. Orgo works out what the cycle costs (120), subtracts the overlapping part of what is already paid (the 30), and records a single 90 row. The member's periods do not double up and the totals still add up to what was actually collected. If the selection turns out to be fully covered, nothing is recorded for that member at all and they simply do not appear in the batch. An early renewal is stacked the same way. When a member pays while their membership is still valid, the new period starts at their current validity date rather than at the payment date, so paying two weeks early costs them nothing in days. *** ## Approving recorded payments **Finance** → **Fee payments** (route `/fee/payments`) is the queue of recorded fee batches. It requires `FINANCIAL_LOCAL`; unit fee admins also reach it, scoped to their own chapter. Fee payments queue with Organisation and Local toggles, a chapter filter, status filters and columns for ID, date, value, payer, chapter, method and status Filter by **Organisation** or **Local**, by chapter, and by **All Statuses**, **Pending** or **Approved**. Each row shows the batch total, payer, chapter, method (card, check or IBAN) and status. What arrives approved is decided by how the batch was written, not by how the member paid. A card batch arrives approved, and only Stripe fulfilment ever writes one. A **Mark as paid** batch, method **check**, arrives approved too. What arrives pending is the batch written by **Pay** on **Finance** → **Local members fees**, stamped as a bank transfer (`iban`), for organisation and chapter fees alike. Approving marks every payment in the batch successful and recalculates each affected member's valid fee date, the chapter date for a chapter fee product and the organisation date otherwise. Until then the periods show as paid-but-pending on the fee tables and no validity date moves. **Approve** is shown only to `ADMIN_TENANT`. A chapter administrator with `ADMIN_LOCAL` sees **Cancel** instead, which deletes the batch and every payment row in it. *** ## Watching collection **Finance** → **Local members fees** shows one row per member and one column per fee period: which periods each member has settled, a switch between the organisation and local fee, filters for year, member status and unit, and recording payment for the selection. Requires `FINANCIAL_LOCAL` and the **Local Center Members Table** setting. **Finance** → **Stats** shows fees by chapter for a chosen period: chapter, status, active member count and fees paid, with a total. Requires `FINANCIAL_TENANT`; for `ADMIN_TENANT` it also highlights chapters below **Minimum Members per Local Center** or **Minimum Active Members Percentage**. Local groups fees table listing chapters with status, active member count and paid fee count, with under-target rows highlighted Per-member history lives on **Members** → open a member → **Fee**: the organisation and local fee side by side with every period. Fee tab on a member profile with the status and total fee summary above the organisation fee and local fee cards, each showing its plan and its paid periods The payment screens have no built-in CSV export. To pull payment data out, build a payments report (**Reports** in the sidebar, `ADMIN_TENANT` only): **Payments** is one of the report builder's starting points, with columns from the product, the price, the payer, the company, the invoice and five other related records, and the download holds every matching row rather than one page. See [Reports](/docs/platform/reports). For a one-off question rather than a repeatable file, the Ask Orgo assistant (**Ask Orgo** in the sidebar, `ADMIN_TENANT` only) also exports query results as CSV. *** ## Reminders and renewal Renewal reminders run automatically once a day; there is no "send reminder" button on a member list. Company-covered members are excluded from the personal ladder. See [Renewals](/docs/platform/fees/renewals). *** ## When fees are mandatory With **Fee Payment Mandatory** on, a member whose valid fee date has passed is redirected to the payment page and cannot use the rest of the platform until they pay. Organisation HR and finance administrators are never gated, and neither are fee-exempt user types. With **Company Fee Payment Mandatory** on, a member who belongs to a company is gated on the company's fee instead of their own. Making fees mandatory degrades the experience for every unpaid member. Pair it with **Days Until Deactivation** rather than **Auto-deactivate on Fee Expiry** alone, so members get a grace window before their account is deactivated. *** ## Refunds Open the payment on **Finance** → **Payments** and choose **Refund**. Orgo refunds exactly that payment row through Stripe, so refunding a membership charge does not claw back the registration fee booked alongside it. The member's valid fee date is then recalculated from what remains, and any event attendance paid by that charge is cancelled. Refunds are always the full row amount; there is no partial-amount field. *** ## Troubleshooting Validity is the end of the paid period, not the payment date, so a payment recorded against last year's period will not clear this year. Also check the batch was approved on **Finance** → **Fee payments**; pending batches do not count. Payment opens when the fee expires or the advance-payment window opens, one month before expiry for multi-month fees and seven days for monthly ones unless you changed it under **Eligibility Rules**. The level locks once a successful payment covers that cycle or a later one. Change it for a later year instead. Both are opt-in: **Enable VAT on Fees** and **Enable One-time Registration Fee** under **Pricing Options**. While either is off it is never charged, whatever the price row stores. See [VAT](/docs/platform/fees/vat). Do not delete their price. Mark their user type **Not eligible for fee**, or assign an admin-only price with no amount to keep an active membership without paying. Turn on **Local Center Fees Enabled** and configure each chapter's fee product. Members then hold two independent validity dates. See [Local Center Fees](/docs/platform/local-group-fees/create-local-fees). Working as designed: the online payment buttons only ever appear to the member looking at their own fee tab. An administrator settles someone else's fee with **Mark as paid**, or sends them the payment link to pay themselves. Before digging further, confirm whether it is you or the member who cannot see the button, because the two have completely different causes. Three conditions close the member's own payment route regardless of dates. An active, uncancelled subscription on the fee product, because they are already being charged automatically. A bank transfer already in progress, because Orgo is waiting for that money to land. And, with **Require Contract for Membership** on, an unsigned or lapsed membership contract, which also fails on the server with "Please sign the mandatory membership contract before any payments". The last two block **Mark as paid** as well, so an administrator cannot work around them; an active subscription does not, which is how you settle a period for a subscriber whose charge went astray. Two arrears settings do this. **Minimum Cycles to Pay** produces "You must select at least N cycles to pay", and only bites when the member actually has that many unpaid periods. **Continuity Mandatory** produces "Your account has unpaid balances from previous fee periods": the selection has to start at the oldest unpaid period and run without gaps, so a member cannot pay this year while last year is open. One checkout also covers at most 12 periods; a member further behind than that pays in two goes. **Approve** is shown only to `ADMIN_TENANT`, and only while the batch is still pending. A chapter administrator with `ADMIN_LOCAL` sees **Cancel** instead, which deletes the batch rather than approving it. A finance-only administrator, `FINANCIAL_LOCAL` or `FINANCIAL_TENANT` without an admin permission, sees the queue and the batch details but neither button, so the batch stays pending and the members it covers stay unpaid. The one-time registration fee is due only to a member who has never had a membership validity date. Any date at all in their history exempts them, including one that came from a lapsed membership, a level switch, or a free or lifetime price an administrator assigned. There is no way to charge it a second time. *** ## Related * [Products](/docs/platform/fees/products): fee products, prices and price versions * [Renewals](/docs/platform/fees/renewals): the reminder schedule and what expiry does * [VAT](/docs/platform/fees/vat): VAT and the one-time registration fee * [Record a payment](/docs/platform/fees/record-payment): recording offline payments * [Local Center Fees](/docs/platform/local-group-fees/create-local-fees): chapter-level dues # Invoices Source: https://orgo.space/docs/platform/fees/invoices Create invoices, understand numbering and series, apply templates, and get the document to the customer An invoice in Orgo is a document plus a state machine. The document is a PDF you can download, email and re-send. The state (unpaid, paid, voided, refunded) is what drives membership validity, event attendance and your financial totals. **Built for** membership organisations that need to bill members, companies and external contacts for dues, event places and one-off services, and to show a proper document for each. **Replaces** hand-made invoice spreadsheets and separate invoicing tools for member billing, not a full accounting ledger. Invoices are a module. Switch **Invoices** on in **Settings** → **All Modules**. While it is off, **Invoices** does not appear in the sidebar, opening the list sends you back to the dashboard, and the **Invoice Templates** settings tab is hidden. Every administrator action described here needs `ADMIN_TENANT`. *** ## Before you can create an invoice Set **Manual Invoice Product** in **Settings** → **Modules** → **Payments & Fees** → **Invoice Product**. Without it, invoice creation fails with a message telling you to review that screen. The same screen holds the rest of the invoicing behaviour: | Setting | What it does | | ------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | | **Send invoice emails automatically** | On by default. Sends the invoice to the customer when it is created and again when it is marked as paid. Turn it off to send only by hand. | | **Invoice membership fee payments** | Off by default. When a member pays a membership or registration fee online, create a paid invoice and email it to them. | | **Invoice template** | Only appears when the setting above is on. Which template those automatic invoices use. Leave on **Default template** to follow the tenant default. | | **Manual Invoice Product** | The product every manual invoice is booked against. Required. | Invoice Product settings showing the automatic email switch, the membership fee invoicing switch and the manual invoice product picker *** ## Creating an invoice **Invoices** → **create invoice**. The form is on the left, a live preview of the document on the right. Invoice creation form with customer, line item and date sections beside a live preview of the invoice document Search for a member, a contact or a company. Exactly one of the three: an invoice cannot be split across two payers. Selecting one loads its billing block (**Billing Name**, **Address**, **VAT Number**, **Registration Number**, **Email**, **Phone**), which you can edit for this invoice only. Leave **Also update customer record with these details** ticked to write your edits back to the member, contact or company as well. The **Membership** switch turns the invoice into a membership invoice: pick a membership level (or **Custom**), a start date and an end date. This is what makes marking it paid extend the member's or company's membership. Contacts cannot be given membership invoices. A manual invoice carries one line: description, quantity and unit price. Multi-line invoices exist, but only on invoices Orgo generates itself for membership payments, where the joining fee is a second line. **Invoice Date**, then a **Due Date** chip: Today, Tomorrow, 7, 14, 30, 45, 60 or 90 days, or Custom. 30 days is the default. **Additional Options** holds the tax name and rate, a **Memo** (visible to the customer), a **Footer**, and **Custom Fields** (label and value pairs printed on the document). **Internal Notes** at the bottom are never shown to the customer. Saving creates the invoice as **unpaid**, gives it a number and a series, renders the PDF, and (unless you turned automatic emails off) sends it to the customer straight away. *** ## Numbering and series Every invoice gets two identifiers. * **Invoice number**: the highest number already used in your organisation, plus one. It starts at 1, is unique to your organisation, and does not reset at the start of a year. * **Series**: five random characters drawn from `ABCDEFGHJKMNOPQRSTUVWXYZ` and `123456789`, retried until it is unique. The characters I, L and 0 are left out so the code cannot be misread. The printed document shows the series when there is one, and falls back to the number. The list lets you search on either, plus the customer name and the internal Orgo ID. Invoice list with filter pills for customer name, invoice number, series, Orgo ID and status, and a table of invoices with paid and unpaid tags Voided and refunded invoices keep their number. That is the point: a missing number would be unexplainable, a voided one is not. *** ## Templates Templates pre-fill the parts of an invoice that are the same every time. **Settings** → **Modules** → **Payments & Fees** → **Invoice Templates**, or **Manage Templates** from the invoices list. | Field | What it does | | ------------------------ | -------------------------------------------------------------------------------- | | **Template Name** | How the template appears in the picker. | | **Default Template** | Applied automatically to new invoices. Setting a new default clears the old one. | | **Tax** | A **Tax Name** (for example VAT, GST) and a **Tax Rate** in percent. | | **Memo** | A note printed on the invoice, visible to the customer. | | **Footer** | Footer text at the bottom of the document. | | **Custom Fields** | Label and value pairs printed on the invoice, with optional default values. | | **Template Description** | Internal reminder of when to use this template. Not printed. | Invoice template editor with template name, default template switch, tax name and rate, memo, footer and custom field rows Applying a template overwrites the tax, memo, footer and custom fields on the invoice you are editing, so apply it first and type your overrides afterwards. The default template is applied automatically when the form opens. On invoices Orgo generates for membership payments the template's flat tax rate is ignored, because each line carries the VAT rate from its own price. The invoice layout itself is fixed. There is no place to write your own placeholders into a memo or footer: the organisation and customer details, line table, totals and VAT breakdown are filled in by Orgo from your organisation profile and the customer record. *** ## Getting the invoice to the customer Open an invoice and you get three actions under the document. * **Download PDF** saves it as `Invoice - {your short name} - {number}.pdf`. * **Send via email** sends it now, even when automatic emails are switched off. The email carries the PDF as an attachment and lands in your [email log](/docs/platform/emails/email-log). * **Copy payment link** copies a public link that opens Stripe Checkout for this invoice. The link works only while the invoice is unpaid. The email goes to the member's address, or the company's contact address (with the company's CC addresses copied in), or the contact's address. If none of them has an email, nothing is sent. Automatic invoice emails need the **Send invoice emails automatically** switch. **Send via email** ignores it, so you can keep automatic sending off and still send individual invoices by hand. *** ## What language the invoice is in The document and the email that carries it are written in your organisation's default language, the one set at **Settings** → **Customization** → **Languages**. Not the customer's own language: everyone billed by the same organisation gets the same wording. All 14 interface languages are covered, and a default outside them falls back to English. A Czech organisation gets **Faktura**, Czech column headings and totals, **IČ** and **DIČ** where an English document says Reg and VAT, dates written the Czech way and comma decimals. The email follows the same language: subject line, the paid or due-on line, the labels and the **Pay this invoice** button. What you typed is never translated. Line descriptions, the memo, the footer and your custom fields print exactly as entered, which is worth remembering if you write them in a different language from your organisation default. The one line Orgo writes itself, the joining fee on a membership invoice, follows the organisation language like the rest of the document. *** ## Where invoices come from Not every invoice is typed by hand. | Type | Created by | Shown as | | ------------------ | ----------------------------------------------------------------------------------------------------------------------------------- | -------------- | | Manual invoice | An administrator using **create invoice** | **Invoice** | | Membership renewal | A member or company choosing bank transfer for a membership fee, or **Invoice membership fee payments** after an online fee payment | **Membership** | | Event registration | An attendee choosing to pay an event registration by invoice | **Event** | You can also raise an invoice after the fact for a membership fee that was already paid: **Payments**, open the row menu on a successful fee payment that has no invoice yet, then **Generate Invoice**. It opens the new invoice for editing and does not email the payer, so you can check it first and send it yourself. *** ## Related * [Recording a payment](/docs/platform/fees/record-payment) marking an invoice paid and logging offline payments * [Cancelling and correcting invoices](/docs/platform/fees/cancelling-invoices) voiding and refunding * [VAT and invoice templates](/docs/platform/fees/vat) tax on the document * [Membership fees](/docs/platform/fees/fees) what members are billed for * [Stripe integration](/docs/platform/fees/stripe-integration) online payment setup # Products Source: https://orgo.space/docs/platform/fees/products Create fee products, donation campaigns, and payment pages A product is what Orgo charges for. Membership dues, donation campaigns, event tickets and manual invoices all resolve to a product with one or more prices. Products are mirrored into Stripe when you save them, so a product is also the unit that Stripe reports on. **Built for** organisations that collect more than one kind of payment and need each one tracked separately. Products list showing an organisation membership fee, a donation product and several local group fee products, with Active and Archived tabs *** ## Where products live **Finance** → **Products** (route `/products/tenant`). The Finance section appears when the Payments or Fees module is active, and the screen requires `FINANCIAL_LOCAL`. Creating or editing an organisation-level product requires `FINANCIAL_TENANT`; a local center finance admin with `FINANCIAL_LOCAL` sees **Finance** → **Local products** instead, and anything they create is stamped with their own local center. The list has **Active** and **Archived** tabs and a **Display totals(slower)** checkbox that adds collected amounts per product. Event ticket products are excluded, being managed inside the event. *** ## Product types | Type | Where it is created | What it is for | | ------------------------------------- | -------------------------------------------------- | --------------------------------------------- | | **Membership Fee** (`fee`) | Products → Create Product | Membership dues, billed on a cycle | | **Donation** (`donation`) | Products → Create Product | Fundraising campaigns with a public page | | **Event** (`event`) | Inside an event, on the Ticketing tab | Event tickets | | **Manual Invoice** (`manual_invoice`) | Created for you when the Invoices module is set up | The line item behind manually issued invoices | Two further types exist in data, `commerce` and `digital_asset`, but the create form only offers Donation and Membership Fee, so neither can be created from the interface. The first organisation-level donation product you create also becomes the tenant default donation product. Set the membership fee product explicitly under **Settings** → **Payments & Fees** → **Membership fees**; do not rely on it being picked up automatically. *** ## Creating a product **Products** → **Create Product**. Create Product form with the Donation and Membership Fee type cards, Title, Frequency, Custom amount and Campaign sections | Field | What it does | | ----------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | | **Product type** | **Donation** or **Membership Fee**. Shown only while creating; the type cannot be switched afterwards. | | **Title** | Required. A blank title is rejected, because Stripe refuses a product with no name. | | **URL Slug** | The public payment page address, `https://{your-payment-host}/pay/{slug}`. Not shown for fee products: those get an internal random slug and no public page. | | **Frequency** | **Recurring** (ongoing fee) and **One-off**. Both can be on. Recurring needs a connected Stripe account. | | **Period** | Fee products only: monthly, 3 months, 6 months or annually. Locked once saved. | | **Cycle beginning** | Fee products only: a fixed calendar month, or "The month user subscribes". | | **Enable pro-ratio for shorter first cycle** | Fee products with a period longer than one month: charge a partial amount for a mid-cycle join. | | **Number of months after cycle begining to start pro-rate** | Suppresses proration for members joining within the first N months of the cycle. | | **Enable custom amount** | Donations: lets the payer type an amount, with optional **Minimum** and **Maximum**. | | **Campaign (optional)** | Donations: **Goal type** (Total goal or Monthly goal), **Goal value** and a **Target date**, drawn as a progress bar on the public page. | | **Belongs to a local center** | Donations: restricts the product to one chapter. | | **Has local center option** | Donations: lets the payer choose a chapter at checkout. Requires **Products with Local Center Option** in the Payments module. | | **Starting date** | Fee products only: the date membership fees start counting for all members. | Donation products also carry page toggles here: **Disable newsletter subscription**, **Messages of support from donors**, **Display top 50 recent donations**, **Disable register checkbox for non-members**, **Require full address** and **Enable payment confidentiality**. See [Donation pages](/docs/platform/fees/donation-pages). *** ## Prices Open a product and use the **Prices & Options** tab. Every purchasable amount is a price row; there is no separate concept of a "tier". Prices and Options tab of a membership fee product listing six prices with names, amounts and descriptions: three individual tiers where the cheapest carries a default badge, and three corporate tiers each tagged Company price with the number of named representatives they include | Field | Applies to | What it does | | ----------------------------------------------------- | ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | | **name** | all | Shown to the payer and on the payment record. | | **price** | all | The amount, in your organisation currency. | | **Payment type** | all | **One-time**, **Is recurring**, or both. At least one is required. | | **description** | all | Longer text shown with the price. | | **VAT** | fee | **VAT exempt (not taxable)** or a percentage rate. Needs **Enable VAT on Fees**. | | **Registration fee (one-time)** | fee | Charged once, on the member's first membership payment. Needs **Enable One-time Registration Fee**, and never appears on local center fee products. | | **Is only assignable by admins (hidden for members)** | fee | Members never see this price; an admin assigns it. The organisation default price cannot be hidden. | | **Company only** / **Company slots** | fee | Reserves the price for company memberships. `0` slots means unlimited. | | **Age conditioning** (**Age under** / **Age over**) | fee | Needs **Enable Age Restrictions on Prices**. | | **Is lifetime membership** | fee | Needs **Lifetime Membership Available**. Saving it sets the cycle to 1200 months. | | **Cycle period (in months)** | fee | Overrides the product period for this price alone. | | **Is bundle** | fee | Groups a paying member with linked member slots. Hidden when fixed-date fee cycles are on. | | **Display name on payment page** | non-fee | Prints the price name on the public page. | | **Availability** | event | **Members & external** or **Members only**, optionally restricted to specific membership levels. | Each row's menu offers **modify**, **Go to Price in Stripe**, **Make default**, **Archive** and **delete**. Members only ever see prices that are not archived, not hidden, and inside their valid dates; `HR_TENANT` sees all of them. ### Worked example: a membership fee product **An example, not a default.** One fee product, **Period** annually, **Cycle beginning** September, holding five prices. Nothing here is preconfigured; each row is one price you add on **Prices & Options**. | Price | Amount | What makes it behave that way | | --------- | ---------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Standard | 120 | **Payment type** One-time. This is also the price you point **Default Price** at under **Settings** → **Payments & Fees** → **Membership fees**, which is what decides the level a new member starts on. | | Student | 60 | **Age under** 26. Needs **Enable Age Restrictions on Prices**. | | Senior | 60 | **Age over** 65. A member has to be under the first value or over the second, so one price can carry both. | | Honorary | left empty | **Is only assignable by admins (hidden for members)**. Members never see it, and applying it extends validity without a payment. See [Membership Fees](/docs/platform/fees/fees). | | Corporate | 900 | **Company only** with **Company slots** 10. | `HR_TENANT` is what puts the **Is only assignable by admins** and **Is bundle** switches on the form; a finance admin without it will not see either. Once any payment has been taken against a price, its amount is frozen. Saving a different amount returns "You cannot edit the price of this product." Use a new price version instead. *** ## Price versions A fee price carries **Valid from** and **Valid to** dates, and each version points back at the one it replaced. That chain lets a payment recorded for 2024 still resolve at the 2024 amount after you raise the price for 2026. To raise a price, open it, choose **New price version**, then fill in **New price**, **Valid from** and optionally **Valid to**. Orgo closes the old version by setting its **Valid to** to the day before the new one starts, so the two never overlap. To work out what a member owed on a given date, the version whose validity window contains that date wins; if none does, Orgo falls back to the organisation default price. The Prices table gains **Valid From** and **Valid To** columns and an expandable **Previous Version** row as soon as any history exists. ### Worked example: taking a level from 120 to 135 You charge 120 a year and want 135 from the 2026 membership year, which starts on 1 September 2026. Open the 120 price, choose **New price version**, enter **New price** 135 and **Valid from** 1 September 2026. Leave **Valid to** empty so the new amount runs until you version it again. The 120 row is stamped **Valid to** 31 August 2026 and linked to the new row. You do not set that date yourself, and you should not: setting both by hand is how gaps and overlaps appear. A payment recorded in March 2026 against the 2025 period still resolves at 120, because the date it covers falls inside the old window. Anything covering 1 September 2026 onwards resolves at 135. Members carry on pointing at the same level; there is nothing to reassign. A 2027 rise is a new version of the 135 row, not a second version of the 120 one. Versions form a chain, and the chain has to stay in order. Two dates with no version between them fall through to the organisation **Default Price**, so leave no gap. Deleting a version that a newer one points back at is refused until you delete the newer one first. Versioning is acted on for membership fee products only. On a donation or event product, retire a price by archiving it and adding its replacement. *** ## Options Donation products, and only donation products, can carry **Product options**: a designation the donor picks on the payment page, for example which programme the gift supports. Add them inline under the prices table, drag to reorder, archive the ones you retire. Each active option has its own deep link into the payment page, so you can send donors straight to one designation. *** ## The rest of a product | Tab or page | What it shows | | -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Prices & Options** | Prices, version history, and donation options. | | **Landing page** | The public page editor: hero media, colours, text. Not shown for fee products. | | **Widgets** | Embeddable donation widgets. Donation products only. | | **Stats** | Payment totals and a trend chart over 7 days, 30 days, 90 days or 12 months. | | **Payments** | Every payment for the product, filterable by payer name, payment ID, user ID, email, status, type, option, local center and date, with **Record payment** and **Refund** actions. | | **Subscribers** | Active recurring subscriptions for the product. | | **Comments** | Donor messages awaiting approval. | Product Stats tab showing payments total for the last 90 days with an amount line and a seven-day moving median Archiving takes a product out of circulation while keeping its payment history: it moves to the **Archived** tab and, if it exists in Stripe, is archived there too. Deleting works only while a product has no payments at all; otherwise Orgo refuses and tells you the product already has payments against it. *** ## Troubleshooting No connected Stripe account: the organisation account for organisation products, the chapter's own for local center products. See [Stripe Integration](/docs/platform/fees/stripe-integration). The price already has payments against it. Create a new price version instead, so past payments keep resolving at the old amount. It is archived, hidden from members, or outside its **Valid from** / **Valid to** window. Both are opt-in per organisation: **Enable VAT on Fees** and **Enable One-time Registration Fee**, under **Settings** → **Payments & Fees** → **Membership fees**. While they are off, no VAT and no registration fee are charged, whatever a price row stores. Create it from **Finance** → **Local products** and configure it per chapter. See [Local Center Fees](/docs/platform/local-group-fees/create-local-fees). Four different things block it, and the message says which: payments already taken against it, event attendees registered on it, use by a ticket bundle, or a newer price version pointing back at it. The last one is the only one you can clear, by deleting the newer version first. Otherwise archive the price: it disappears from checkout and keeps its history. Deletion is only for products that have never taken money; anything with payments against it is refused, and the message tells you so. Archive it instead, which also archives it in Stripe when it exists there. A title made only of spaces counts as blank and is rejected with "Product name is required.", because Stripe will not accept a product without a name. Type a real title rather than a placeholder space. A saved product must keep at least one of **Recurring** and **One-off**, so whichever one is currently alone cannot be cleared. **One-off** is also unavailable while no Stripe account is connected, the organisation's for organisation products and the chapter's own for local center products. Organisation products need `FINANCIAL_TENANT`. `FINANCIAL_LOCAL` reaches only products belonging to a chapter the holder is attached to, which is why a chapter finance admin can open **Local products** but not the organisation membership fee. Event ticket products are the exception: they are gated on `EVENT_TENANT` instead. Two combinations are refused outright. "The default price cannot be set as admin assignable only" means the price you selected as **Default Price** under **Settings** → **Payments & Fees** → **Membership fees** cannot also be **Is only assignable by admins (hidden for members)**: point **Default Price** at another price first. And a price created as a bundle cannot be turned back into an ordinary price once its bundle has been sold, has event attendees, or has members assigned to it. Prices are only pushed to Stripe when an account is connected at the time you save them, so anything created before you connected Stripe stays local, and **Go to Price in Stripe** has nothing to open. The product itself is created in Stripe on the first checkout that needs it, and saving the price again after that pushes it across. *** ## Related * [Membership Fees](/docs/platform/fees/fees): turning a fee product into collected dues * [VAT](/docs/platform/fees/vat): when VAT applies and how it is stored * [Stripe Integration](/docs/platform/fees/stripe-integration): connecting payment processing * [Donations](/docs/platform/fees/donations): running fundraising campaigns * [Local Center Fees](/docs/platform/local-group-fees/create-local-fees): chapter-level fee collection # Recording a Payment Made Outside Orgo Source: https://orgo.space/docs/platform/fees/record-payment Mark an invoice as paid, record a membership fee period, and log a one-off payment taken by bank transfer, cash or cheque Not every payment goes through the platform. Members pay by bank transfer, hand over cash at a meeting, or send a cheque. Recording those payments keeps membership status, payment history and reporting correct. There are three places to do it, and they are not interchangeable. Pick by what was paid for. | What was paid | Where to record it | Permission | | -------------------------------------------------------------- | ------------------------------------------------- | ------------------------------------------------------------------------------ | | An invoice you raised | The invoice, **Mark as paid** | `ADMIN_TENANT` | | A membership fee period | The member's **Fee** tab, **Mark as paid** | `FINANCIAL_TENANT` for the organisation fee, `FINANCIAL_LOCAL` for a local fee | | Anything else (a course place, merchandise, a one-off service) | The member's **Payments** tab, **Record payment** | `FINANCIAL_TENANT` | *** ## Marking an invoice as paid **Invoices**, open the invoice, then **Mark as paid**. The button is only there while the invoice is unpaid. Four things happen. 1. The invoice becomes **paid** and Orgo records which administrator marked it, so the action stays attributable. 2. A **PAID** badge is added to the stored document, the amount due line changes to read as paid, and the "Pay online" link is removed from it. 3. A payment record is created for the gross total (net plus VAT) and linked to the invoice. That record is what updates membership status and shows in payment history. 4. The paid invoice is emailed to the customer. Step 4 catches people out. Marking an invoice as paid emails the customer. If you are tidying historical records, they still get the email. Switch off **Send invoice emails automatically** in **Settings** → **Modules** → **Payments & Fees** → **Invoice Product** first if you are doing a batch of corrections. Unpaid invoice detail page showing the Mark as paid, Edit and Void buttons above the amount and billing summary ### Membership invoices If the invoice has the **Membership** switch on, marking it paid also books the membership period on the invoice and moves the member's fee validity date forward. For a company, it updates the company membership end date, applies the member slots that come with the chosen level, and pushes the new validity date out to everyone the company covers. This is why the membership level and the start and end dates matter on the invoice form: they are the period being bought. ### Event registration invoices Marking an event registration invoice as paid confirms the registrations attached to it. The attendees move from awaiting payment to confirmed, the linked payment is marked successful, and ticket confirmation emails go out. Always record an event payment against the event's own invoice rather than raising a separate one, otherwise the attendance is never confirmed and check-in and attendee reports stay wrong. *** ## Recording a membership fee period An invoice is not required to record a membership fee. On the member's profile, open the **Fee** tab and use **Mark as paid**. Orgo asks which period you are recording, shows the period end it works out from your fee configuration, and records the payment against that period using the price that was valid at the period start, not today's price. The action needs **Allow Mark as Paid** switched on in **Settings** → **Modules** → **Payments & Fees** → **Membership fees**. With it off, nobody can record a fee manually and members must pay online. An **Enter different amount** switch appears only if your organisation uses fixed starting dates for fees. Without that setting the amount is locked to the member's price, and a different figure is rejected. Manual fee payments are recorded with the payment method **check** and count immediately: the member's validity date moves forward as soon as you confirm. Recording a batch that resolves to nothing (every period deselected, or a member with no fee price for that period) is refused with an explanatory error rather than saved half-formed. Local centre fees have their own **Mark as paid** on the same profile, needing `FINANCIAL_LOCAL` for that member's local centre. Both behave the same way: what an administrator marks as paid counts straight away, because a mark-as-paid batch is written as already approved and carries the method **check**. The pending state you see on **Fee payments** in the sidebar comes from somewhere else. It is the batch written by **Pay** on the [Member fees table](/docs/platform/local-group-fees/member-fees), stamped as a bank transfer (`iban`) and left pending, for organisation and chapter fees alike. **Approve** there is shown only to `ADMIN_TENANT`; a chapter administrator with `ADMIN_LOCAL` sees **Cancel**, which deletes the batch instead. Members never submit a fee payment for approval: a member paying their own fee by bank transfer raises an unpaid invoice, which is settled with **Mark as paid** on the invoice. *** ## Recording any other payment For everything that is not membership, use the member's **Payments** tab and the **Record payment** button. It needs `FINANCIAL_TENANT`. Either pick an existing product, or switch on **Custom item** and type an **Item name**. A custom item creates a hidden one-off product so the payment has something to hang from without cluttering your product list. Products with active prices require you to pick one, and the **Amount** is then locked to it. Only products configured to accept a custom amount let you type a figure. Defaults to today. Set it to the day the money actually arrived so reporting lines up with your bank statement. Record payment modal with the custom item switch, the product picker, the amount field and the payment date picker The payment is saved as successful, stamped with your name as the administrator who recorded it, and carries no Stripe charge. The amount you enter is treated as the net figure, with VAT derived on top of it. Membership fee products are deliberately not offered here, and are rejected if you try. A fee payment also has to carry the period it buys, which this form does not collect. Use the **Fee** tab instead. *** ## Getting it wrong If you mark the wrong invoice as paid, do not delete it. See [cancelling and correcting invoices](/docs/platform/fees/cancelling-invoices): the trail of what happened is worth more than a tidy list. *** ## Related * [Invoices](/docs/platform/fees/invoices) creating invoices, numbering and templates * [Cancelling and correcting invoices](/docs/platform/fees/cancelling-invoices) voiding and refunding * [Membership fees](/docs/platform/fees/fees) how fee periods and prices are configured * [Local group fees](/docs/platform/local-group-fees/create-local-fees) fees collected by a local centre * [Stripe integration](/docs/platform/fees/stripe-integration) taking payment online instead # Renewals & Reminders Source: https://orgo.space/docs/platform/fees/renewals The exact renewal reminder schedule, what a member with an expired fee can and cannot do, and how they renew Every member with a paid membership has a validity date. This page covers what Orgo does as that date approaches and passes: which emails go out and when, what changes for the member once it is in the past, and how they put it right. *** ## Recurring or one-time A membership level is sold as a one-time price, as a recurring subscription, or as both. That distinction decides everything else here. **On a subscription**, the card is charged automatically at the end of each period. The member gets no renewal reminders, because the reminder job skips anyone with an active subscription on that fee product; they get a **Renewal Confirmed** or **Renewal Failed** email after each charge instead. **On a one-time payment**, nothing is charged automatically and the membership lapses on the validity date unless the member pays again. That is what the ladder below exists for. A payment recorded by hand, a bank transfer entered by an administrator for example, is a one-time payment even when the level also supports subscriptions, because there is no card on file to charge next time. That is the usual reason a member you expected to renew automatically did not. *** ## The reminder schedule One job runs daily at 18:00 UTC and sends at most one email per member per day, to members whose validity date falls exactly on a milestone: | When | Email | | --------------------------- | --------------------------- | | About a month before expiry | **1 Month Reminder** | | 7 days before expiry | **7 Days Reminder** | | On the expiry date | **Renewal Day Notice** | | The day after expiry | **Lapsed Reminder** | | 7 days after expiry | **Lapsed Reminder** (again) | | 14 days after expiry | **14 Days After Reminder** | | 30 days after expiry | **30 Days After Reminder** | Nothing is sent between the rungs or after 30 days past expiry: a member who lapses and never returns hears from Orgo seven times, then stops. ### Worked example: a membership expiring on 30 June Each rung is matched against the validity date exactly, so the whole ladder for one member is fixed the moment their validity date is known. For a membership valid to **30 June 2026**, and taking that date as an **example**: | Sent at 18:00 UTC on | Email | | -------------------- | ---------------------- | | 30 May 2026 | 1 Month Reminder | | 23 June 2026 | 7 Days Reminder | | 30 June 2026 | Renewal Day Notice | | 1 July 2026 | Lapsed Reminder | | 7 July 2026 | Lapsed Reminder again | | 14 July 2026 | 14 Days After Reminder | | 30 July 2026 | 30 Days After Reminder | Nothing arrives on any other day, and the moment they pay, their validity date moves and the remaining rungs no longer match. Because the match is on the exact date, a rung the job misses is not sent late: it is skipped. Membership renewal reminder templates listed with their send timing, from 1 Month Reminder through 30 Days After Reminder The **1 Day Reminder** template appears in the template list and can be edited, but the daily job has no milestone that reaches it, so it is not currently sent to individual members. The company version of that reminder is sent normally. A member is skipped entirely when they have an active subscription on that fee product, their user type is marked as not eligible for a fee, their membership is covered by a company with its own validity date (the company is chased instead, not the member who cannot pay), or the fee period is under two months. Monthly fees get no ladder. **Company memberships.** A second job runs daily at 18:30 UTC on its own seven rungs. They are the same milestones with one swap: a company is chased the day before expiry rather than the day after, so the company version of the **1 Day Reminder** is the one that is actually sent, and nothing goes out on the day after expiry. Each email goes to the company's contact email address, or the first primary contact if none is set, copying the remaining primary contacts and any additional company addresses, so whoever can pay is always on the mail. The job chases companies that are **Active** or **Pending**, and only those with a membership plan and a renewal date. A company set to Inactive or deleted gets nothing: no reminder, and no renewal invoice raised for it either, since with the Invoices module on each reminder carries the company's unpaid renewal invoice as a PDF. The status is checked again at the moment of sending, so deactivating a company also stops a reminder already queued for that day. **Wording and switches.** All fourteen templates (seven individual, seven company) are editable at **Settings** → **Emails & Notifications** → **Email Templates**, under membership renewal reminders. **Settings** → **Emails & Notifications** → **System Emails** → **Membership Renewal Reminders** switches the category off, and a per-template override beats it, so you can silence one rung and keep the rest. *** ## What an expired membership actually changes Two different things are tracked, and the difference explains most support questions. **The validity date has passed** the moment the date is behind you, and for anyone who never paid. **The fee is no longer active** only after grace: **Fee Valid Months** and **Fee Valid Days**, under **Settings** → **Payments & Fees** → **Membership fees** → **Validity Period**, extend the window in which a member still counts as paid, and a lifetime level stays active forever when **Lifetime Membership Available** is on. Without grace the two coincide. Once the fee is no longer active: * their status shows unpaid on their profile and in the member directory, and **My Membership Fee** in their own menu carries a **Due** tag; * member-only ticket prices stop: events return an empty member-price list, so they see the public price; * they cannot create a referral for someone else, and get "You cannot create referrals at the moment" if they try; * with **Require Contract for Membership** on, their signed membership contract is cancelled, so they must sign again before buying a new membership. Fee status is not part of the permission system, so on its own it does not stop a member logging in, reading discussions or attending events. Making fees mandatory does. ### When fees are mandatory **Settings** → **Payments & Fees** → **Membership fees** → **Membership Requirements** → **Fee Payment Mandatory** redirects a member whose validity date has passed to their own fee page on every navigation until they pay. It keys on the validity date, not the grace window. Still reachable, so the payment can be completed: the profile fee and payments tabs, product payment pages, onboarding, document previews, donation pages and the payment confirmation page. The mandatory-course gate stands down while a fee is owed. The redirect never applies to `HR_TENANT` or `FINANCIAL_TENANT` holders, to user types not eligible for a fee, or inside the event app. With **Company Fee Payment Mandatory** on, a member of a company follows the company fee instead: primary contacts and financial representatives go to a company payment page, everyone else to a page explaining that the company fee is outstanding. `ADMIN_TENANT` holders are exempt. ### Automatic deactivation Off by default, available only when fees are mandatory: **Auto-deactivate on Fee Expiry** plus **Days Until Deactivation** (1 to 365; a tenant with a delay outside that range is skipped rather than deactivated). A daily 07:00 UTC job sets any active member whose validity date is older than the delay to inactive, skipping user types not eligible for a fee and lifetime levels when lifetime membership is enabled. The delay counts from the validity date itself, not from the end of the **Fee Valid Days** or **Fee Valid Months** grace window. If you set both, the deactivation delay is the number that decides when the account is switched off. *** ## How a member renews From the user menu, **My Membership Fee**, or from their profile's fee tab: Member fee card showing an unpaid membership with its status, amount, membership level and Pay button, above a history list with the current year unpaid and the two previous years paid | Option | Offered when | | ------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Pay once** | The level is sold as a one-time price, there is no active subscription, no bank transfer is in progress, and either the membership has expired or the member is inside the advance-payment window. | | **Set up automatic renewal** | The level is sold as recurring, the membership has already expired, the member is paying for themselves, and the level's own period override, if it has one, is 12 months or less. Paying by card this way creates the subscription; an administrator recording a payment by hand does not, because there is no card on file. | | **Pay by bank transfer** | **Enable Membership Payments via Bank Transfer** is on and the invoices module has an invoice product configured. The membership is flagged as having a transfer in progress until the payment is confirmed. | | **Ask an administrator to record it** | **Allow Mark as Paid** is on. A `FINANCIAL_TENANT` holder records the organisation fee, a `FINANCIAL_LOCAL` holder the local center fee. | Members can switch membership level only while expired, and only when more than one level is available to them. A `FINANCIAL_LOCAL` holder can change someone's level at any time. **Renewing early.** Paying is always allowed once the membership has expired or was never paid. Before expiry it is allowed only inside the advance-payment window, at **Settings** → **Payments & Fees** → **Membership fees** → **Eligibility Rules**: | Setting | Applies to | Default | | ----------------------------------- | -------------------------------------- | ------- | | **Advance Payment Window (Months)** | Fees with a period of 2 months or more | 1 month | | **Advance Payment Window (Days)** | Monthly fees | 7 days | After any payment the validity date is set to the end of the last period paid for, so an early renewal extends the membership rather than restarting it from the payment date. **Example.** An annual membership valid to 30 June 2026, with the default one month advance window and **Fixed Starting Date for Fees** off, so periods follow the member rather than the calendar. The member pays on 12 June 2026. The new period does not start on 12 June: it starts where the old one ended, so the membership now runs to 30 June 2027 and the renewal date stays put year after year. The same holds inside a grace window: with **Fee Valid Months** set to 1, a member who pays on 15 July 2026 still counts as active at that moment, so they too resume from 30 June and lose nothing for being late. *** ## Stopping an automatic renewal A subscriber's fee card reads "Auto-renewing membership" with an action to cancel it, then "Auto-renewal ending" with the last day they are covered. Only the member themselves or a `FINANCIAL_TENANT` holder can cancel. Cancelling stops future charges. It does not refund anything already paid and it does not end the current period early: the member stays active until the period they paid for runs out, and from that point counts as a one-time payer, reminders included. *** ## Troubleshooting Work down the list. Do they have an active subscription on the fee product (subscribers are skipped by design)? Is their membership covered by a company (the company is chased instead)? Is their user type marked as not eligible for a fee? Is the fee period shorter than two months? Then check that **Membership Renewal Reminders** is on under **Settings** → **Emails & Notifications** → **System Emails**, and that the individual template has not been overridden off. Finally, look at their validity date: the ladder matches it against the exact milestone dates, so a validity date that was edited or recalculated in between can step over a rung entirely. Expected. The under-two-months rule is read from whichever period applies to that member, so a level with a one-month **Cycle period (in months)** override is skipped even on an annual product, and selling the level as a subscription does not put it back in. Monthly subscribers still get their per charge **Renewal Confirmed** or **Renewal Failed** email, which is the only mail they should be getting. Either the card was declined, in which case Stripe's failure notice reaches Orgo and the member is sent **Renewal Failed**, or there was never a subscription in the first place. The second case is the common one: a payment an administrator recorded by hand, or a bank transfer, leaves no card on file, so a level being sold as recurring does not by itself make the member a subscriber. Check the **Subscribers** tab of the fee product before assuming a member is on automatic renewal. The level chooser only offers prices that are not archived, not company only, not hidden from members, and it only appears to the member while their membership has expired and more than one level is open to them. A price marked **Is only assignable by admins (hidden for members)** is invisible to them by definition: a `FINANCIAL_LOCAL` holder has to assign it, and can do so at any time rather than only at expiry. The job only looks at members who have a validity date. Someone who never paid at all has no date, so they are never deactivated by it, however long they have been on the books. Also skipped: user types not eligible for a fee, and lifetime levels while **Lifetime Membership Available** is on. If nothing at all happened, check that **Fee Payment Mandatory** and **Auto-deactivate on Fee Expiry** are both on and that **Days Until Deactivation** is between 1 and 365, since a value outside that range skips the whole organisation. With **Fee Payment Mandatory** on, the redirect keys on the validity date, so it starts the day the date passes even when a grace window is still running. The pages needed to complete a payment stay reachable, so if the member is truly stuck it is worth checking the blockers on the fee itself: an unsigned membership contract when **Require Contract for Membership** is on, a bank transfer already in progress, or an active subscription. See [Membership Fees](/docs/platform/fees/fees). *** ## Related * [Membership Fees](/docs/platform/fees/fees) for collecting and tracking dues * [VAT & Registration Fees](/docs/platform/fees/vat) for what is added on top of the price * [Products](/docs/platform/fees/products) for membership levels and periods * [Recording a payment](/docs/platform/fees/record-payment) for offline payments * [Stripe Integration](/docs/platform/fees/stripe-integration) for subscriptions and card charges # Stripe Integration Source: https://orgo.space/docs/platform/fees/stripe-integration Connect Stripe to accept online payments for fees, donations, tickets, and merchandise Stripe is the payment processor behind every card payment in Orgo. You connect your own Stripe account, money lands in your own bank account, and Orgo records each payment against the right member, ticket, or donation. **Built for** organisations that collect membership fees, event tickets, donations, or product payments online. **Works alongside** Stripe: Orgo never handles card data, it only tells Stripe what to charge and reads back what happened. *** ## Where it lives | Screen | How to reach it | Permission | | --------------------------- | ---------------------------------------------------------- | -------------- | | Organisation Stripe account | **Settings → Modules → Payments & Fees → Payment Gateway** | `ADMIN_TENANT` | | Chapter Stripe account | **Chapter settings → Local online payments settings** | `ADMIN_LOCAL` | Both open the same screen, titled **Online payments** followed by the organisation or chapter name. Its direct addresses are `/tenant/settings/online-payments` and `/local/settings/online-payments`, which is also where Stripe returns you after authorisation. The chapter screen is only listed in the sidebar when the **Online Payments** module is on, **Local Center Payments** is on, and the chapter is eligible (either **All Local Centers Eligible** is on, or that chapter is individually flagged). Online payments settings showing a connected Stripe account id, Fully connected status, Complete account status, and buttons for View Stripe Dashboard and Change Stripe account *** ## Before you connect Your organisation must have a **country** set in **Settings → Organisation info**. Without it the connect buttons are disabled and the API refuses to create or authorise an account, because Stripe needs the country at account creation time and it cannot be changed afterwards. *** ## Connecting Stripe Two buttons appear while no account is linked: Sends you to Stripe's authorisation page (`connect.stripe.com`). Log in, pick the account, and approve. Orgo stores the resulting account id and returns you to the settings page with a confirmation. Creates a Stripe Standard account in your organisation's country with card payments and transfers requested, then sends you straight into Stripe's onboarding form. Online payments settings with no Stripe account linked, showing the Connect existing Stripe account and Generate Stripe Account buttons The authorisation round trip is protected by a signed, single-use token that expires after **1 hour**. If you leave the Stripe tab open too long, or reload the return URL, you get an error toast and simply start again. A tenant admin can complete onboarding on behalf of a chapter by opening the chapter, then **Local online payments settings**. The chapter is carried through the Stripe round trip and back. *** ## Reading the status Once an account is linked the page shows three things. **Connection status with Orgo** | Badge | Meaning | | ----------------------- | ------------------------------------------------------------- | | **Fully connected** | Stripe reports `charges_enabled`, the account can take money | | **Partially connected** | The account is linked but Stripe is not letting it charge yet | **Stripe account status** | Badge | Meaning | | ------------------------ | ----------------------------------------------------- | | **Complete** | Details submitted, charges and payouts both enabled | | **Charges enabled** | Can take payments, payouts still blocked | | **Pending verification** | Details submitted, Stripe has not enabled charges yet | | **Incomplete** | Onboarding was never finished | | **Unknown** | Stripe returned a combination Orgo does not map | **Requirements needed** lists whatever Stripe currently asks of you (identity documents, bank details, business information). Clear them in Stripe and the badges update on the next page load. The buttons change with the status: **Add Stripe details** while onboarding is unfinished, **View Stripe Dashboard** once it is done, and **Change Stripe account** at any time to re-authorise a different account. There is no disconnect action. To stop using an account, connect a different one with **Change Stripe account**, or switch off the Online Payments module. *** ## What breaks if onboarding is incomplete * **No account at all:** product, ticket, and donation checkouts refuse to start. The products list shows "Stripe account is not configured in organisation settings" with a link to the settings page, and the membership payment modal redirects there. * **Account linked but charges disabled:** members see "Payments are temporarily unavailable for this account. Please try again later or contact support." * **Open requirement with a future deadline:** payments keep working. Stripe only blocks charges once the deadline passes. *** ## Payment methods Orgo pins no list. Checkouts use Stripe's automatic payment methods, so members are offered exactly what your Stripe account has enabled for that currency and country (cards, wallets, local methods). Turn methods on or off in the Stripe Dashboard, not in Orgo. Bank transfer is separate: an offline method you record by hand. See [Recording payments](/docs/platform/fees/record-payment). *** ## Chapter accounts A chapter (local center) can connect its **own** Stripe account. When it has one, local fees charged to that chapter settle there. When it does not, the charge falls back to the organisation's account, so the chapter is never blocked, its money simply lands centrally. A chapter's own Stripe account is used by any product the chapter owns, not just fees: a donation campaign or ticket product with **Belongs to a local center** set charges the chapter's account. The fall-back differs, though. Fee payments fall back to the organisation account when the chapter has none. Donation and ticket checkouts do not: connect the chapter's account before selling anything the chapter owns. Donation widgets are the exception and always charge the organisation account. A chapter can only be given its own currency once it has its own Stripe account, and that currency is immutable afterwards. Both rules exist to prevent double currency conversion. *** ## Commission, fees and payouts Orgo takes **no commission**. The platform application fee is present in code but forced to zero on every charge, and the per-organisation rate defaults to 0. What you pay is Stripe's own processing fee, deducted before payout: see [stripe.com/pricing](https://stripe.com/pricing). The settings page also links Stripe's discounted pricing for qualifying non-profits. Payouts are between Stripe and your bank. Orgo does not set the schedule, does not hold funds, and does not display payout history: use the Stripe Dashboard. *** ## Refunds Refund from the payment's row in the payments list. Orgo refunds exactly that row's amount, which matters when one card charge produced several records (a membership payment plus its registration fee, for example). A refund also cancels any linked event attendance, releases the seat, and recalculates the member's fee validity date. Refunds issued in the Stripe Dashboard are picked up and marked in Orgo too. Refunding requires `FINANCIAL_LOCAL` on the payment's chapter, and `FINANCIAL_TENANT` when the payment carries no chapter, which is the case for every organisation-level payment. `ADMIN_TENANT` qualifies either way. It only works on a payment that succeeded. *** ## Staying in sync You configure no webhook. Orgo listens on a single platform endpoint and updates records when Stripe reports a successful payment, a failed or action-required invoice, a subscription created, updated or cancelled, a cancelled payment intent, or a refunded charge. Two settings control receipts, under **Settings → Modules → Payments & Fees**: | Setting | What it does | | ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | | **PDF Receipts/Proofs** | Orgo generates its own PDF receipt for payments | | **Stripe Email Receipts** | Lets Stripe send its own receipt email. Needs customer emails enabled on your Stripe account, and Stripe never sends receipts in test mode | *** ## Test mode Test mode is not a switch in your settings. Orgo runs against live Stripe keys; only demo organisations provisioned by Orgo are wired to Stripe's test mode. Switching your own Stripe Dashboard to test mode changes nothing about what Orgo charges, so ask Orgo for a demo organisation if you want to rehearse a checkout. *** ## Troubleshooting Your organisation has no country set. Fill it in under **Settings → Organisation info** and reload. The one-hour authorisation token expired, was already used, or the return landed on an unexpected domain. Start the connection again from the settings page. Stripe has disabled charges on the account. Open **Requirements needed** on the settings page, or the Stripe Dashboard, and clear the outstanding items. That chapter has not connected its own Stripe account. Until it does, its charges fall back to the organisation account by design. *** ## Related * [Products](/docs/platform/fees/products) - what you sell through Stripe * [Membership Fees](/docs/platform/fees/fees) - fee collection and validity * [Donations](/docs/platform/fees/donations) - one-off and recurring giving * [Recording payments](/docs/platform/fees/record-payment) - offline and manual payments * [Local Center Fees](/docs/platform/local-group-fees/create-local-fees) - chapter-level fee setup * [Usage & Billing](/docs/platform/usage-billing) - paying Orgo, not your members # VAT & Registration Fees Source: https://orgo.space/docs/platform/fees/vat Turn VAT on for membership fees, set a rate per membership level, charge a one-time joining fee, and control the tax shown on invoices Two optional charges sit on top of a membership price: VAT, and a one-time registration fee paid when someone first joins. Both are off until you turn them on, and both are configured per membership level rather than once for the whole organisation. Tax on manual invoices is separate and is set on the invoice template. *** ## Turning them on **Settings** → **Payments & Fees** → **Membership fees** → **Pricing Options**. Requires `ADMIN_TENANT`. | Setting | What it does | | ------------------------------------ | ----------------------------------------------------------------------------------------------------------------- | | **Enable VAT on Fees** | Shows the VAT fields on membership prices and adds VAT on top at checkout and on invoices | | **Enable One-time Registration Fee** | Shows the registration fee field on membership prices and charges it once, on a member's first membership payment | These two switches are authoritative. With **Enable VAT on Fees** off, a price that already holds a VAT rate is charged and invoiced with no VAT at all, and every invoice line is issued as non-taxable. Turning the switch on later starts applying the stored rates immediately, so check your prices before you flip it. Pricing Options section of the membership fee settings with Enable VAT on Fees and Enable One-time Registration Fee switches *** ## Setting a rate per membership level Once VAT is on, each membership price on a fee product gains a **VAT** block: * **VAT exempt (not taxable)**: the level carries no VAT and is excluded from the taxable base. * **VAT rate (%)**: used when the level is not exempt. Decimal rates are stored as written, so 13.5 or 19.6 are fine. That is how one organisation charges VAT on a standard membership and none on a reduced or honorary level: they are separate prices, so they carry separate treatments. Donation options on a fee product never show the VAT fields, and neither does any product that is not a fee product. *** ## VAT is added on top Orgo uses the exclusive model everywhere. The price you type is the net amount, and VAT is calculated on top of it: ``` VAT = net × rate / 100 Gross = net + VAT ``` A level priced at 100 with a 19% rate charges 119. Nothing in the product is VAT-inclusive, so do not enter a gross figure and expect Orgo to work backwards from it. *** ## The one-time registration fee The registration fee is a joining fee: it is a field on the membership level, and it is charged once per member, on their first membership payment. The field carries the note "Charged once, on the member's first membership payment. Leave empty for no registration fee." "First payment" means the member has never had a membership validity date. A member who paid once and then lapsed for years counts as a returning member and is never charged the registration fee again. There is no way to re-arm it for an individual short of clearing their membership history. Other things worth knowing: * It is only available on organisation-level fee products. A local center fee product does not show the field. * It has its own VAT treatment, set independently of the price VAT. Those controls appear only once you have entered a registration fee amount, and only when **Enable VAT on Fees** is also on. * It is recorded as its own payment row and appears as its own invoice line, so reports separate joining income from recurring dues. It rides on the same card charge as the first membership payment, but it stays a separate row: **Refund** in Orgo returns only the row you act on, so refunding the membership does not return the joining fee. Refund both rows, or refund the whole charge in the Stripe Dashboard, which marks both refunded in Orgo. * It buys no membership time. Only the membership portion extends the member's validity date. *** ## What the member is charged At checkout the member sees one total built from up to five parts: | Part | When it applies | | ----------------------- | --------------------------------------------------------------- | | Membership (net) | Always | | VAT on membership | VAT on, level not exempt, rate above zero | | Registration fee | Registration fee on, level has an amount, member has never paid | | VAT on registration fee | VAT on, registration fee not exempt, rate above zero | | Donation | Only if the member adds one at checkout | The membership summary card, the fee cards and the card payment panel all compute this the same way, so the amount on the button matches the amount on the card form. *** ## VAT on an invoice Membership invoices carry VAT per line, not once for the document. Each line stores either a rate or an exempt flag at the moment the invoice is created, so a historical invoice keeps the treatment that was correct on the day it was raised. Changing a price or a template later never rewrites an issued invoice. The invoice shows a VAT column per line, then a totals block with **Subtotal**, one **VAT** row per distinct rate (labelled with the rate and the base it was applied to), **Total** and **Amount due**. Line amounts and VAT are rounded to two decimals. When at least one line is exempt, the invoice prints the VAT exemption note, which is the free-text wording that states the legal basis for the exemption. The exemption note is stored on the invoice template and copied onto invoices Orgo generates itself for membership fee payments. It is not copied onto invoices you raise by hand, and there is no field for it in the invoice template form or the invoice form. It can only be set through the API, on the template (for automatic invoices) or on the individual invoice. If you need it on your documents, ask support to set it for you. *** ## Tax on manual invoices Manual invoices take their tax from the invoice template rather than from a membership price. **Settings** → **Payments & Fees** → **Invoice templates**, `ADMIN_TENANT`. | Field | What it is for | | -------------------- | -------------------------------------------------------------- | | **Tax** | Switch that reveals the two fields below | | **Tax Name** | What the tax is called on the document, for example VAT or GST | | **Tax Rate (%)** | A whole percentage between 0 and 100 | | **Memo**, **Footer** | Standing text on every invoice from this template | The template's tax name and rate are copied onto an invoice when it is created from that template. Create one template per tax treatment and issue each invoice from the one that matches it. *** ## Your organisation's VAT number The VAT identification number printed in the issuer block of every invoice comes from **Settings** → **Organisation info** → **VAT Number**. It is a display field: Orgo does not validate it and does not use it to decide whether VAT applies. *** ## Related * [Membership Fees](/docs/platform/fees/fees) for collecting and tracking dues * [Products](/docs/platform/fees/products) for the fee products and price levels these settings live on * [Renewals](/docs/platform/fees/renewals) for what happens when a membership expires * [Invoices](/docs/platform/fees/invoices) for numbering, templates and delivery * [Stripe Integration](/docs/platform/fees/stripe-integration) for card payments and payouts # Files & Documents Source: https://orgo.space/docs/platform/files Shared drives for your organisation, groups and members, with public share links you can revoke Orgo Files (the Drive) gives your organisation one place for documents: an organisation-wide drive, a drive inside every group and local center, and an optional private drive per member. You can also write documents directly in Orgo and publish any file or folder as a public link. **Built for** membership organisations that need policies, minutes, templates and forms in the same place as their members, events and groups. **Replaces** an unstructured shared folder in Google Drive or Dropbox for member-facing documents, because access follows your existing group membership instead of a separate list of email addresses. The Files home showing drive cards for the organisation, two group drives and the personal drive with file counts and storage size, next to a Latest files table with name, owner, date and size *** ## Turning it on Files is a module. An **ADMIN\_TENANT** turns it on at **Settings → Modules → Files & eDocuments → Drive**: | Setting | What it does | | -------------------------- | -------------------------------------------------------------------------------------------- | | **Enable Drive Module** | Shows **Files** in the sidebar and the **Files** tab on groups. Off hides the whole surface. | | **Enable Personal Drives** | Gives every member a private drive, and lets HR and admins add files to it. | Drive module settings with the Enable Drive Module toggle and the Enable Personal Drives toggle, both switched on Two behaviours are off by default and not exposed on this screen: embedding external media (YouTube and Spotify) in a drive, and showing your logo on the public video player. Each group has its own controls in its settings: a **Files** feature toggle that shows or hides the group's Files tab, and **Who can post?**, set to **Everyone in the group** or **Only admins**. **Only admins** is one choice covering posts, events and file uploads together, so it hides the upload, document and folder buttons from ordinary members of that group. *** ## Where files live **Files** shows one card per drive you can reach, with its file count and total size. | Drive | Who can see it | Who can add to it | | ------------------------------------------------------- | ---------------------------------------------------------------------------------- | ----------------------------------------------------------------- | | **Organisation drive** | Every member of the organisation | **HR\_TENANT** and above by default | | **Group drive** (any group, local center or role group) | Members of that group | Members of that group, unless the group is set to **Only admins** | | **Personal Drive** | The member, **HR\_LOCAL** of their local center, **HR\_TENANT**, **ADMIN\_TENANT** | The same people | Renaming, moving, deleting an item, and publishing or revoking its public link all need the same thing: you own it, you administer its group, or you are **ADMIN\_TENANT**. Local admins get no rights over the organisation drive; their authority is scoped to the groups and local centers they administer. Group drives are how you restrict who sees what. There is no per-file permission: a file inherits the audience of its drive, so leadership documents go in a leadership group. The organisation drive is the drive with no group attached. Uploading there is restricted to **HR\_TENANT** and **ADMIN\_TENANT** by default, which is why an ordinary member sees the organisation card but no upload button on it. Group drives are open to their members unless the group sets **Who can post?** to **Only admins**. A personal drive is also reachable from the member's profile, on the **Personal Drive** tab, which appears only when personal drives are enabled. *** ## What you can put in a drive | **+** menu | What it does | | --------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Upload** | Or drag files anywhere onto the page. Up to 100 files per batch, uploaded one at a time with a progress panel. | | **Document** | Opens Orgo's own editor. Autosaves five seconds after you stop typing, counts words and characters, and warns you before you leave with unsaved changes. Documents live in the drive like any other item. | | **Folder** | Folders nest. Move an item by dragging it or using **Move**; items can only be moved into folders, and a folder cannot be moved into itself. | | **Embed media** | When enabled, adds a YouTube or Spotify link as a drive entry. Orgo checks the URL against the allowed providers and pulls the title and thumbnail. Nothing is copied into your storage. | ### Upload limits | Limit | Value | | ----------------------------- | ---------------------------------------------------------------------- | | Maximum file size | 5,000 MB (about 5 GB) | | Files per drag-and-drop batch | 100 | | Blocked file types | PHP, HTML and XHTML, SVG, Windows and Linux executables, shell scripts | | Everything else | Allowed, including PDF, Office files, images, video, archives | There is no allowed-types list: any format that is not blocked uploads. The blocked ones can execute code in a browser when opened from a link. Orgo also renames every uploaded file in storage to the original name plus 24 random characters, so the storage address cannot be guessed from the name. The in-app document editor with a rich text toolbar, the document title, a heading and paragraphs, and the word and character count in the header ### Previews Images, PDFs and videos get an automatic thumbnail in the gallery; other formats show an icon. Office files (DOC, DOCX, XLS, XLSX, PPT, PPTX) offer a read-only browser preview through Microsoft Office Online, or a download, and cannot be edited inside Orgo. A video in a format browsers cannot play (MKV or AVI, for example) prompts you to upload it as download-only. *** ## Working with files | Action | Notes | | ------------------------------ | ---------------------------------------------------------------------------------------------------------------- | | **Download** | Single file. | | **Download folder as archive** | Zips the folder in your browser and downloads it. | | **Rename** | Changes the display title only. | | **Move** | Drag, or use **Move** and pick a destination folder. | | **Delete** | Permanent. The stored file is deleted too, and there is no recycle bin. | | **Share** | Opens the share dialog described below. | | **Search** | The box on the Files home searches titles across every drive you can reach. Two characters minimum, ten results. | A drive folder listing with file rows showing name, owner, date and size, and an open row menu with Copy link, Share, Download, Remove, Move and Rename Deleting is not reversible and it removes the underlying file from storage. Deleting a folder removes everything inside it. *** ## Sharing The **Share** dialog offers two links, and they behave differently. The Share dialog with two sections: Only in the community with a copyable 7-day link, and Anyone with the link with a Generate public link button **Only in the community** is a direct link to the file that **expires after 7 days**. Nothing is published and no setting changes. Treat it as a link, not a permission check: it is generated because you have rights on the file, but anyone you send it to can open the file until it expires. For a folder it is an ordinary in-app link instead, so the recipient must log in and already have access to that drive. **Anyone with the link**, via **Generate public link**, publishes a permanent public address of the form `go.orgo.space/d/`. | Question | Answer | | --------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Does the visitor need an account? | No. Anyone on the internet with the link can open the file. | | Can the link be guessed? | No. The code is 10 random characters drawn from a cryptographic random source, roughly 51 bits, so it cannot realistically be enumerated. | | How long does it last? | Until you revoke it. | | How do I take it back? | Open **Share** on the file and click **Revoke public link**. The public address stops working and the file becomes unreadable to visitors again. Copies already downloaded are of course still out there, so rotate anything sensitive. | | Who can publish or revoke it? | The same people who can edit the file: its owner, the admins of the group it sits in, and **ADMIN\_TENANT**. | Publicly shared files show a globe marker in the list, so you can see what is exposed. Video files get a branded viewer page instead of a raw download, with the organisation logo when video branding is enabled, and playable files also give you an **Embed** snippet for an external website. ### Sharing a whole folder Sharing a folder publishes a public folder page. Visitors browse the subfolders and open the files, and cannot navigate above the folder you shared. Public folder shares are inherited. Every file already in the folder becomes public, and any file you upload or move into it afterwards becomes public automatically. Revoking the folder share removes public access from the whole subtree. Publishing and revoking a large folder finishes in the background. The dialog shows **Publishing...** while that runs; the link itself works immediately. Files sit in Orgo's cloud storage, readable without a login only while a public share link exists. There is no automatic expiry or archival, so an uploaded file stays until someone deletes it. *** ## Troubleshooting Check which drive it is in: a group drive is visible only to that group. Groups are the boundary, so leadership documents go in a leadership group and general resources in the organisation drive. There is no per-file permission to set. Files over 5 GB are rejected, and so are HTML, SVG, PHP, executable and script files. The upload panel shows the reason per file. Very large uploads also need the tab to stay open until they finish. No. Office files open read-only. Download, edit locally and upload the new version, or use **+ → Document** for content you want to keep editing inside Orgo. That is by design: a public folder share covers everything inside it, including items added later. If you need one file kept private, move it out of the shared folder. The message is wrong, in every language. The size text shown when Dropzone rejects a file still quotes 50 MB, while the limit the uploader actually enforces is 5,000 MB. Trust the behaviour, not the sentence: anything under about 5 GB uploads. If a file well under 5 GB is refused, the reason is the type, not the size. PHP, HTML, XHTML, SVG, Windows and Linux executables and shell scripts are blocked because they can run code in a visitor's browser when opened from a share link. Zip the file, or convert an SVG to PNG. Yes, and there is no way back. A group drive belongs to its group at the database level, so removing the group removes every file, folder and document that lived in its drive, along with the stored copies. Before you delete or merge a group, download the folder as an archive, or upload anything worth keeping to the organisation drive. Note that this is the one case where **Move** does not help you, because Move never changes which drive an item is in (see the next answer). Deleting a group is refused outright while a newsletter is still attached to it, so a group that survives a delete attempt for that reason has not lost its files. Anything else goes through. You cannot, in one step. **Move** only changes which folder an item sits in inside the drive it already belongs to, and the destination picker only lists folders from that same drive. Dragging behaves the same way. Download the file and upload it again in the destination drive, then delete the original. For a whole folder, use **Download folder as archive** first. Uploading into the organisation drive needs `HR_TENANT` or `ADMIN_TENANT` by default, so an ordinary member who wants a document promoted from their group to the organisation drive has to ask somebody with that permission to do the second half. Expected. Inside a personal drive, editing rights belong to whoever uploaded the item, plus `HR_LOCAL` of that member's local center, `HR_TENANT` and `ADMIN_TENANT`. Being the owner of the drive lets a member see and download everything in it, but not change items somebody else put there. Worked example: HR uploads a signed contract into a member's personal drive. The member opens the Personal Drive tab, downloads the contract, and finds no Rename, Move or Delete on that row. Files the member uploaded themselves show all three. Ask HR to remove it, or upload a corrected copy alongside. Two things put it there. **Enable Personal Drives** has to be on in the Drive module settings, and you have to be the member yourself, `HR_LOCAL` of their local center, `HR_TENANT`, or `ADMIN_TENANT`. Any other viewer, including a local admin from a different local center, sees the profile without the tab. Personal drives are also left out of the normal drive listing on purpose, so they never appear on the Files home as somebody else's card. The search box on the Files home matches file titles only. It does not read inside documents, it needs at least two characters, and it returns at most ten results, ordered exact match first, then titles that start with your term, then titles that contain it. Worked example: type `minutes` in an organisation with forty files whose titles contain that word and you get ten of them, with no "show more". Add the month or the committee to narrow it, or open the drive you expect the file to be in and browse. The search also only reaches drives you can already open: your personal drive, the organisation drive, and the drives of groups and local centers you belong to. A file in a group you are not a member of is not missing, it is out of scope. And because **Rename** changes the display title, search follows the new name, not the name the file had when it was uploaded. Treat it as tidiness, not as access control. Set to **Only admins** it hides the upload, document and folder buttons from ordinary members of that group, which is what you want for an announcements-style group where files come from the committee. It is one choice covering posts, events and files together, so you cannot lock files while leaving posts open. The real boundary is who is in the group. Everyone in a group can read everything in its drive whatever this setting says, and the setting is not what keeps a determined member from adding a file. Put material that a specific audience must not see in a group whose membership is that audience, rather than relying on the posting rule. Both happen, depending on the file. For a file that is not publicly shared, that link is a signed address to the stored file with a seven-day life. After seven days it returns an error from the storage provider rather than an Orgo page. Open **Share** again to get a fresh one. For a file you have already published with **Generate public link**, the same button hands you the permanent public address instead, because the file is already world readable and a signed link would add nothing. That link outlives the seven days, and revoking the public share kills it, which surprises people who thought they had sent an internal link. Check the globe marker in the file list if you are not sure which of the two you sent. *** ## Related * [Groups](/docs/platform/groups/index) - group drives and who belongs to them * [Permissions](/docs/platform/permissions) - what HR\_TENANT, ADMIN\_TENANT and the local roles unlock * [E-Documents](/docs/platform/contracts) - documents members sign electronically * [Discussions](/docs/platform/discussion/index) - attaching files to posts * [Modules](/docs/platform/organisation/modules) - turning the Drive module on # Forms Source: https://orgo.space/docs/platform/forms Build standalone forms and surveys, share them with a public link, and read the responses as charts, single answers, or a table Forms is Orgo's standalone form builder. You write the questions, publish the form, share one link, and read the answers back inside Orgo. Anyone who answers with an email address that Orgo does not already know becomes a contact, so a survey doubles as a way to grow your contact list. **Built for** the one-off questionnaire that is not part of joining your organisation: a satisfaction survey, an interest poll, a call for volunteers, a sign-up sheet for an activity. **Replaces** Google Forms or Typeform for members and the public. It has no conditional logic, no file-upload questions, and no payment collection. Forms list showing status filter pills and a grid of form cards with field counts and Published, Draft and Closed status tags *** ## Turning it on and who can use it Enable the module at **Settings** → **Modules** → **Form Builder** → **Enable Form Builder Module**, which requires `ADMIN_TENANT`. Opening the Forms area requires `ADMIN_TENANT` or `HR_TENANT`. Creating a form requires `HR_TENANT`, `EVENT_TENANT` or `COMMUNICATION_TENANT`; editing or deleting one requires one of those three, or that you own it. `ADMIN_TENANT` covers everything on this page. A form you create belongs to you: its statistics, responses, and publish action are open to you as its owner, and to anyone holding `ADMIN_TENANT`, `COMMUNICATION_TENANT`, or `EVENT_TENANT`. The **Forms** entry in the **Management** section of the sidebar is currently shown to holders of `COMMUNICATION_TENANT` or `EVENT_TENANT`, but the page itself only admits `ADMIN_TENANT` or `HR_TENANT`. If the link is visible and clicking it sends you to the login screen, that is this mismatch, not a broken session. Ask for `HR_TENANT`, or reorder the menu to hide the entry until it is resolved. *** ## Building a form **Create form** makes a draft called "Untitled form" immediately and opens the builder; rename it in the top bar. On the **Questions** tab, the header card holds the title respondents see and an optional rich-text description. Add questions with the **+** button on the right, each with a title, an optional description shown under it, a type, and a **Required** toggle. **Add text** inserts a rich-text block that displays instructions between questions and collects no answer. Drag a question by the handle at the top of its card to reorder. **Save** keeps the form as a draft; **Publish** saves everything and opens the form to responses. Deleting a question inside the builder marks it "Will be deleted" and offers a **Restore** button until you press Save. To copy a question, use the duplicate action in the question editor: questions belong to one form, cannot be reused on another, and never appear on the [Custom Fields](/docs/platform/users/custom-fields) settings page. ### Question types | Type | Answer | | ------------------- | ------------------------------ | | **Short answer** | One line of text | | **Paragraph** | Multi-line text | | **Multiple choice** | One option, all shown at once | | **Checkboxes** | Any number of options | | **Dropdown** | One option, picked from a list | | **Number** | A number | | **True / False** | A switch | | **Date** | A calendar date | There is no file-upload question and no conditional or branching logic. Every respondent sees every question in the order you set. For a file, collect it through a [custom field](/docs/platform/users/custom-fields) on the profile or registration form, or ask for a link to it in a short-answer question. Form builder Questions tab with the header card, a multiple choice question expanded for editing beside collapsed ones, and the floating add-question toolbar *** ## Settings The **Settings** tab holds who may answer and when. | Setting | What it does | | -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | **Only registered users** | Only an email that matches an existing member account is accepted. Anyone else is refused. | | **Anyone with email verification** | An email is required. A known member or contact is accepted straight away; an unknown address creates a new contact and the response stays pending until the confirmation link is clicked. | | **Anyone (Anonymous)** | No email asked. Responses are stored with no submitter and the submitter columns disappear from the responses table. | | **Limit to one submission per device** | A second attempt from the same device shows the thank-you page instead of the form. | | **Schedule auto-close** | A date and time after which the form reports itself closed and stops showing the questions. | | **Thank You Custom Message** | Rich-text page shown after a successful submission, in place of the default "Thank you!" screen. | The device check behind **Limit to one submission per device** is a hash of the respondent's IP address and browser user agent. It deters casual repeat entries but is not an identity check: a different network or browser gets a fresh attempt. Display options live behind the palette button on the **Questions** tab: a header image, whether to show the title and description, whether to show your organisation's logo, and the colour of the submit button. *** ## Publishing and sharing Publishing generates a seven-character short code and builds a shareable page with social-media preview tags. The link button in the top bar copies the responder link, `https:///share/form/`. Respondents do not need an Orgo account to open it unless the form is set to **Only registered users**, and a signed-in member gets their email filled in automatically and skips the verification step. Public form page as a signed-out respondent sees it: the title card, the email address card, and the first questions each in their own card To stop responses without losing the link, open **Published options** in the top bar and turn on **Not accepting responses**, or set a date under **Schedule auto-close**. Either shows a "Form Closed" panel in place of the questions, and turning the switch off reopens the form. Deleting a form from the list does not free the link either: it hides the form everywhere but keeps the record and its responses. *** ## Reading the responses The **Responses** tab counts confirmed responses, and flags separately how many are still pending an email confirmation. It offers three views. * **Summary** draws a chart per choice question and lists the text answers grouped by identical value, each with who submitted it and when. * **Answers** walks through responses one at a time, in the same layout the respondent saw. Covers the 100 most recent confirmed responses. * **Table View** is one row per response, one column per question, paginated 100 rows at a time. **Download CSV** exports up to 10,000 responses with the same columns as the table. On an anonymous form the submitter and email columns are absent from both the table and the export. Response counts are cached and refresh themselves as answers arrive. If the numbers look stale, the refresh button next to **Download CSV** forces a full recalculation. Closing a form freezes its statistics. You can delete a single response from the **Answers** view, permanently. Responses tab Summary view with the response count, Download CSV button, and a chart per choice question with the text answers grouped underneath *** ## What a response creates On a form set to **Anyone with email verification**, an email that matches a member is linked to that member, an email that matches an existing contact is linked to that contact, and an unknown email creates a new [contact](/docs/platform/contacts) with the first and last name given on the form, marked as coming from a form. Unless the respondent is signed in as the owner of that email, the response is held as pending and a confirmation email goes out. Clicking the link inside confirms the response, confirms the contact's email address, and lands the respondent on the thank-you page. **The link is valid for 24 hours**; after that the form has to be submitted again. Pending responses are counted separately and are excluded from the charts, the table, and the export until they are confirmed, which is the usual reason a response someone swears they sent is not visible. *** ## Standalone forms versus the other builders | Use | Builder | Why | | ------------------------------------------- | -------------------------------------------------------------- | ------------------------------------------------------------- | | A survey, poll, or one-off questionnaire | **Forms** (this page) | Public link, no account needed, answers stored as responses | | Collecting data when somebody joins | [Registration form](/docs/platform/users/registration-form) | Writes to the member's profile and creates the account | | Different questions per kind of member | [Per-user-type registration forms](/docs/platform/users/user-types) | One field set per user type | | Data every member keeps up to date | [Profile form](/docs/platform/users/profile-fields) | Fields live on the profile and can be required or filtered on | | A membership application to review and sign | [Adhesion](/docs/platform/users/adhesion) | Has an approval workflow and a generated document | | Extra questions asked when booking a place | [Event registration form](/docs/platform/events/registration-forms) | Answers attach to the event attendance | If the answer belongs on a person's profile forever, use one of the profile-based builders. If it belongs to one question you asked once, use Forms. *** ## Troubleshooting The Responses tab, the statistics, the recalculate button and the **Publish** action all check the same thing: that you created the form, or that you hold `ADMIN_TENANT`, `COMMUNICATION_TENANT`, or `EVENT_TENANT`. `HR_TENANT` is not on that list, and it does not imply any of the three. Worked example: two colleagues both hold `HR_TENANT`. Both reach `/forms`, both create and publish their own forms, and neither can open the other's Responses tab, because for each of them the other's form fails every branch of the check. The requests are refused rather than returning an empty table. Fixes, in order of preference: give the people who read results `COMMUNICATION_TENANT` or `EVENT_TENANT`, keep one shared account as the owner of forms the whole team reads, or ask the owner to send the CSV. Note the asymmetry: `HR_TENANT` can edit and delete a colleague's form, but not read its answers. Reading results is deliberately the narrower right. Not from the app. Deleting sets the form's status to `DELETED`, and every signed-in read of forms filters that status out: the form disappears from the list, and so do its Responses tab, its statistics and its CSV export. The public link stops working too, because the public page only serves forms that are published or closed. Nothing is destroyed. The submissions, the answers and the contacts created from them all stay in the database. But there is no undelete button, so **Download CSV** before you delete anything you might want to read again. To take a form out of circulation without losing access to the answers, use **Not accepting responses** instead of Delete. They work differently and only one of them is a hard stop. **Not accepting responses** changes the stored status of the form to closed. The submit endpoint accepts nothing but a published form, so responses stop at the source, and closing the form also computes its final statistics. **Schedule auto-close** is evaluated when the form is read. Once the date has passed, the form reports itself as closed and the public page shows the "Form Closed" panel in place of the questions, but the stored status is still published. For an audited cut-off (a vote, a deadline with money attached) set the switch when the deadline arrives rather than relying on the date alone. One detail worth knowing: turning **Not accepting responses** on clears the scheduled date, so reopening the form later does not silently re-arm an old schedule. Reopening also queues a fresh recalculation of the statistics. That is **Limit to one submission per device**. The device is a hash of the respondent's IP address and browser user agent, so it is really "one answer per network plus browser build", not one answer per person. Worked example: five colleagues answer from the same office router. The first two use different browsers and both get through. The next three are all on the same version of the same browser, so they produce the same hash as one of the first two and see the thank-you page without their answers being saved. The same person on a phone that switches from office wifi to mobile data counts as a new device and can answer again. Two more details. Only confirmed responses block a device, so on a form set to **Anyone with email verification** a first respondent who never clicks the confirmation link leaves the device open. And nothing deduplicates by email or by member account: the device hash is the only repeat guard there is, on every submission mode. They read different sources. **Table View** counts confirmed submission rows live. **Summary** reads a stored statistics record that Orgo maintains in the background as answers arrive. When the background update falls behind, Orgo forces a full recalculation only once 50 or more responses have landed since the last one. Below that it serves what it has, which is why a form collecting a handful of answers a day can show a Summary that trails the table by a few responses for a while. The refresh button next to **Download CSV** forces the recalculation immediately. On a closed form the stored record is final by design: the refresh button will not move it, and that is what "closing a form freezes its statistics" means in practice. The export stops at 10,000 rows and takes the newest ones, ordered by submission date, with no warning in the file or on screen. Worked example: a form with 12,300 confirmed responses exports a CSV with the most recent 10,000 in it. The 2,300 oldest are simply absent, and the row count in the file is the only clue. Below 10,000 the export is complete. Above it, read the older responses in **Table View**, which pages through everything 100 rows at a time, or split long-running collection across more than one form. *** ## Related * [Contacts](/docs/platform/contacts) for the records created by public responses * [Custom Fields](/docs/platform/users/custom-fields) for fields that live on member profiles * [Registration Form](/docs/platform/users/registration-form) for collecting data at sign-up * [Event Registration Forms](/docs/platform/events/registration-forms) for questions asked at booking * [Permissions](/docs/platform/permissions) for the permission names used above # Gamification Source: https://orgo.space/docs/platform/gamification Points members earn for taking part, tier badges those points unlock, and the leaderboard that ranks them Gamification adds a points ledger on top of [badges](/docs/platform/badges). Members earn points for things they already do (buying, attending, referring, posting), those points feed a leaderboard, and badges with a points threshold act as tiers members climb. **Built for** organizations with a large, quiet membership where the goal is to surface and reward the people who actually turn up. **Replaces** the engagement spreadsheet and the manual "member of the month" shortlist. It is not a loyalty scheme with redeemable rewards: Orgo counts points, it does not spend them. Everything on this page sits behind one switch: **Enable tiers/levels by points**. Without it, badges still work but no points are recorded anywhere. *** ## Turning it on **Settings** → **Modules** → **Gamification & Courses** → **Gamification**, which needs `ADMIN_TENANT`. Changes save as you flip each switch. | Switch | What it turns on | | --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | | **Enable Gamification Module** | Badges, the Badges tab on member profiles, and the Badges entry in the sidebar | | **Enable badge categories** | Grouping badges into categories | | **Enable hours tracking** | Volunteering hours and hours-threshold badges | | **Enable badge per event** | The per-event badge field. Also needs the tiers switch below, because the event form's Gamification section only appears with tiers on | | **Enable tiers/levels by points** | Points, the point rules panel, tier badges, and the leaderboard | Gamification module settings showing the Enable Gamification Module switch and the badge categories, hours tracking, badge per event, and tiers feature switches *** ## How members earn points Turning tiers on reveals **Point Rules** and **Engagement Points**. Set a rule to 0 and that source stops awarding. | Setting | Awards points when | How much | | ---------------------------------- | -------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- | | **Purchase points (per ...)** | A product payment is recorded | Payment amount multiplied by the rate, rounded down to whole points. The label ends with your organisation's currency symbol | | **Event attending default points** | A participant's RSVP becomes attending or attended | The event's own **Points** field when it is filled in, otherwise this default | | **Referral points (per user)** | A referred signup completes | Awarded to the referrer, not the new member | | **Create discussion** | A member starts a discussion | Flat amount. Help desk issues are excluded | | **Create comment** | A member comments or replies | Flat amount | | **Receive reaction** | Someone reacts to a member's post | Awarded to the post's author. Reacting to your own post awards nothing | Every rule ships with a fallback that applies only until you save the panel for the first time: 1 point per currency unit, 100 for an event, 100 for a referral, 50 for a discussion, 10 for a comment, 2 for a reaction. After the first save, the numbers on screen are the numbers in force. Event points are recorded once per attendance record, and they are taken back if the attendance is deleted or the RSVP moves away from attending. Points are for members only: [contacts](/docs/platform/contacts) never accumulate them. *** ## Tiers A tier is a badge with **Points required** set on it. On a member's profile, the overview card is retitled **Membership level** and shows the member's total points, their current tier, and every tier as a card marked **Achieved** or **Locked** against that total. Tier cards on the profile light up from the points threshold alone, but the automatic promotion that actually writes the badge onto the member also needs an ordering number (`level`) on each tier badge. The settings screen does not expose that field today, so set it through the API (`PATCH /badges/{id}`) or award tier badges by hand. When automatic promotion does run, it grants the highest tier the member qualifies for and removes their lower tier badges, so a member holds one tier at a time. *** ## The points ledger Every point movement is a dated row: how many points, which activity type (purchase, event, engagement, referral, manual), a description, and a reference to the record that caused it. The member's total is the sum of those rows. Open a member, go to the **Badges** tab, and the ledger sits below their badges and volunteering hours. `HR_TENANT` can correct the point value on a row or delete a row outright; the activity type, description, and reference are fixed. There is no button to add points by hand, so a correction means editing or removing an existing row. *** ## The leaderboard **Analytics** (`/stats`) → **Leaderboards** → **Points** ranks the top 50 members by points, over the last 7 days, the last 30 days, or all time. It uses the same filters as the rest of the analytics page: member status, user type, and local center. The card only appears when both the module and tiers are on. Who can open the Leaderboards tab at all is set by the **Leaderboards** permission under Analytics on the **Permissions setup** page (**Settings** → **Modules** → **Users & Profiles** → **Security & Permissions**). It defaults to every member, so raise it if rankings should stay with staff. The same tab carries leaderboards that do not depend on gamification at all: events attended, posts written, reactions received, and referrers. Those stay visible whether or not points are switched on. *** ## Common questions Check that **Enable tiers/levels by points** is on, then check the rules themselves: a rule left at 0 awards nothing. Points also start from the moment the switch goes on, so nothing is backfilled for past activity. No. The ledger is permanent, and the 7 and 30 day buttons only narrow the leaderboard window, not the member's total. Recording stops and the leaderboard card disappears, but nothing already earned is deleted. Turn it back on and the old totals are still there. Not from the interface: there is no add-points button. Award a badge by hand instead, or adjust an existing ledger row. Purchase points are awarded when the payment is recorded and are not reversed by a refund. Edit the ledger row down as `HR_TENANT`. *** ## Related * [Badges](/docs/platform/badges) - The catalogue tiers are built from * [Products](/docs/platform/fees/products) - Purchases that award points * [Event attendance](/docs/platform/events/attendance) - Attendance that awards points and event badges * [Referral program](/docs/platform/users/referral) - Referrals that award points * [Discussions](/docs/platform/discussion) - Posts, comments, and reactions that award points # Groups & Teams Source: https://orgo.space/docs/platform/groups/index Organize members into collaborative spaces with discussions, files and events **Built for** organizations that need more than one shared feed: committees, project teams, interest communities and audience segments that each need their own space. **Replaces** ad hoc WhatsApp groups, Slack channels and shared drive folders that nobody can find later. A group is a space with its own discussions, files and events, plus a member list. Every group is created from the same form; what makes them different is the **Access** mode you pick and, for role groups, the criteria you set. Groups page showing the organization card, the member's chapter, a Teams section for role groups, and Programs and activities grouped by category, each row with its member count *** ## The four access modes | Option | Description in the app | Who ends up in it | Listed under | Use it for | | ---------------------------------------------- | ------------------------------------- | ------------------------------------------------------------------ | ---------------- | -------------------------------------------------------------------------- | | **Auto-enroll all members** | Add all members automatically | Every active member of the organization, with no way to leave | Community groups | Announcements everyone receives, with **Who can post?** set to Only admins | | **Open to join** | Anyone in community can join | Members who join themselves, plus anyone an admin adds | Community groups | An interest community members opt into | | **Private** | Only invited members have access | Only members a group admin adds | Private groups | A committee, board or project team | | **[Role group](/docs/platform/groups/role-groups)** | Aggregate members by roles or profile | Everyone matching the criteria you set, recalculated automatically | Teams | Everyone with a given role, age or chapter | Only organization admins (`ADMIN_TENANT`) can create **Auto-enroll all members**, **Open to join** and **Role group** groups. A member without that permission who creates a group gets a **Private** group. You can change the Access mode later by editing the group. A group filed under a [category](#group-categories) is listed under **Programs and activities** instead of Community groups or Private groups. For a geographic branch with its own admins and fees, use a [local center](/docs/platform/groups/local-groups) rather than a group. Local centers chain to any depth, so a national body, its regions and their branches are three layers of the same structure rather than three kinds of group. *** ## What a group gives you Each group carries three optional features, chosen with the **Features** selector when you create or edit it: | Feature | What it adds | Also requires | | --------------- | ---------------------------------------------- | ------------------------------------- | | **Discussions** | A discussion feed inside the group | The Discussions module enabled | | **Files** | A file area scoped to the group | The Files & eDocuments module enabled | | **Events** | An event list and calendar scoped to the group | The Events module enabled | At least one feature must stay switched on. Every group also has a **Members** tab and, once you write a description, an **About** tab; auto-enroll groups have no Members tab, because the membership is simply everyone. A group can also carry a logo, a **Menu emoji** shown next to its name in the sidebar, and a rich text description. ### Who can post A single **Who can post?** control covers discussions, files and events together; there is no separate switch per feature. | Option | Effect | | ------------------------- | ---------------------------------------------------------------------------------------------------------------------------- | | **Everyone in the group** | Any member can start discussions, upload files and create events | | **Only admins** | Only group admins can. Organization moderators keep access: `HR_TENANT` for discussions and files, `EVENT_TENANT` for events | *** ## Enabling the module **Settings** → **Groups & Teams** → **Configuration** Groups and Teams module settings showing the master toggle plus Group Types and Group Features sections | Setting | What it does | | -------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | | **Enable Groups & Teams Module** | Master switch. With it off, the group form does not render. | | **Enable Group Categories** | Adds a category picker to the group form and a **Group Categories** page in settings | | **Enable Role Groups** | Adds the **Role group** access mode, the **Create role group** action and the **Role groups** tab | | **Enable Organizational Units** | Adds a **Unit Types** page for sub-units inside chapters | | **Group Tasks** | Reserved for group task tracking. It has no effect on the current interface. | | **All Members Group** | Reserved for the all-members space. It has no effect on the current interface; use the **Auto-enroll all members** access mode instead. | **Group Tasks** and **All Members Group** are stored on the tenant but nothing reads them. Switching them does not change what members see. *** ## Who can create a group Two checks apply, in this order. **Settings** → **Users & Profiles** → **Permissions setup** → **Groups Module** → **Who can create**. The default is `USER`, so any signed-in member can create a group. Raise it to `ADMIN_LOCAL`, `HR_TENANT` or `ADMIN_TENANT` to restrict creation. A group filed under a category must also satisfy that category's **Who can create group in this category** permission. Separately, the **Auto-enroll all members**, **Open to join** and **Role group** modes always require `ADMIN_TENANT`. Members who fail the check do not see the **Create group** button on the Groups page or in the sidebar; guest accounts never see it unless they also hold `ADMIN_TENANT`. *** ## Group categories Categories group related spaces together on the Groups page and in the sidebar, and let you delegate creation rights per category. Enable **Enable Group Categories**, then go to **Settings** → **Groups & Teams** → **Group Categories**. Managing categories requires `HR_TENANT`, and members only see the categories they are allowed to create in. Group Categories settings page listing categories with their colour and the permission required to create groups in each | Field | What it does | | ----------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Name** | The section heading members see on the Groups page | | **Color** | A preset colour or a custom hex value. Tints the category label and the group's bullet. | | **Who can create group in this category** | The permission a member needs to file a new group here. The picker offers `USER`, `HR_LOCAL`, `ADMIN_LOCAL`, `HR_TENANT` and `ADMIN_TENANT`. The list column shortens these to the labels **USER**, **HR** and **Admin**, so the tenant and local variants of a permission read the same there. | The category picker only appears on the group form for **Auto-enroll all members** and **Open to join** groups. Private groups cannot be categorized. *** ## The Groups page **Groups** in the sidebar, or `/groups/browse`. Tabs filter the list: | Tab | Shows | | ------------------ | ------------------------------------------------------------------------------ | | **All** | Everything you can see | | **Subscribed** | Spaces you get notifications from | | **Not subscribed** | Spaces you have muted or never subscribed to | | **Archived** | Closed groups and role groups | | **Role groups** | Role groups only. Visible to `ADMIN_TENANT` when **Enable Role Groups** is on. | Below the tabs, the page lists your organization space and your chapter first, then **Teams** (role groups), **Programs and activities** (groups with a category), **Community groups**, **Private groups** and **Archived groups**. A search box filters by name. Every row except the organization space carries a member count. For a group or a team it is the active members in it; for your chapter it is the active members filed against that chapter itself, and nobody from the chapters underneath it. The [chapters list](/docs/platform/groups/local-groups) counts the same members but adds the branch, so a parent chapter's number there is the larger one. The **Create group** button opens a menu with **Create group** and, for organization admins with role groups enabled, **Create role group**. Organization admins also get a **Settings** shortcut to the module configuration. *** ## Archiving and deleting | Action | Who | What happens | | ------------- | ------------------------------------------- | ----------------------------------------------------------------------------------------------- | | **Archive** | The owner, a group admin, or `ADMIN_TENANT` | The group moves to the Archived tab. Members, discussions, files and events are kept untouched. | | **Unarchive** | `ADMIN_TENANT` | Restores the group from the Archived tab | | **Delete** | The owner or `ADMIN_TENANT` | Removes the group permanently | Archiving is reversible and loses nothing, so prefer it over deleting. A group with a newsletter attached cannot be deleted until the newsletter is removed. *** ## Common scenarios Yes, with no limit. Members are in every auto-enroll group, their chapter, every chapter above their chapter in the chapter tree, every role group they match, and any open or private groups they joined or were added to. Their own chapter and every chapter above it, all the way to the top of the tree. Membership travels up; it never travels down, so somebody filed against the national body is not placed in the branches beneath it. **Isolate Local Center Access** narrows this one layer at a time: a chapter above them is shown only when their own `HR_PARENT_LOCAL` reach covers that particular chapter, and role groups scoped to a chapter they cannot see are hidden with it. Private groups are invisible to non-members. Opening one you are not in returns an access error unless you are the owner, a member, or hold `ADMIN_TENANT`. *** ## Related * [Main Group](/docs/platform/groups/main-group) - the organization-wide space * [Role Groups](/docs/platform/groups/role-groups) - criteria-based automatic membership * [Private Groups](/docs/platform/groups/private-groups) - committees, project teams and open communities * [Local Centers](/docs/platform/groups/local-groups) - geographic branches * [Discussions](/docs/platform/discussion) - the discussion feed inside a group # Local Centers Source: https://orgo.space/docs/platform/groups/local-groups Geographic chapters and branches with their own admins, events, fees, and member communities **Built for** organizations with local branches or regional structure: professional associations, alumni networks, trade unions, youth organizations, and federated nonprofits. **Replaces** the spreadsheet of branch contacts and the separate tools each branch bought for itself. A local center is a geographic branch: a city, chapter, district, or council. Each one has its own members, discussions, events, files, fees, and its own administrators, while staying inside your organization. Chapters chain to any depth. A national office can hold regions, a region can hold districts, and a district can hold branches, with no limit on how many layers you use. See [How deep the chapter tree goes](#how-deep-the-chapter-tree-goes). The app says **Chapters**. **Local center** is the platform term used by the data model, the API, and the permission names, so both appear here. Chapters list with the map panel open, showing pins, a status filter, a town filter, and one row per chapter indented by its depth in the chapter tree with member counts *** ## Before you start | Requirement | Where | | ------------------------------------------- | ------------------------------------------------------------------- | | **Enable Local Centers Module** switched on | **Settings** → **Modules** → **Groups & Teams** → **Local Centers** | | `ADMIN_TENANT` to create a chapter | The **Create chapter** button only appears for organization admins | | `ADMIN_LOCAL` to edit one | Scoped to the chapter being edited | *** ## Creating a chapter **Chapters** → **Create chapter**, six sections: | Section | Fields | | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **General information** | **status** (Active, Pending close, Suspended, Closed), **name**, **Alias**, **Who can create events in this chapter**, **founded**. Status and founded are `ADMIN_TENANT` only. | | **Location** | **town**, **Map location** (address lookup), **Map description** (free text shown in the map pin popup) | | **Organization** | **Belongs to parent chapter**, **It's a parent chapter**, **Region**, **isInitiative**, each shown only when its setting is on. The two structural fields are `HR_TENANT` only. | | **Payments** | Online payments through an independent local Stripe account; chapter members paying membership fees online | | **Contact and Online** | **contactName**, **contactEmail**, **contactPhone**, **officeAddress**, **postalAddress**, **website**, Facebook, Instagram, X | | **Legal and Banking** | **legalNumber**, **localCenterCurrency**, one IBAN per enabled currency (native, USD, EUR, CHF) | A chapter currency can be set once and never changed, because past payments and the connected Stripe account are bound to it. A chapter currency also requires the chapter to have its own Stripe account, otherwise charges land in the organization account and get converted twice. **Who can create events in this chapter** sets the bar for this chapter alone: **Event managers (default)** (`EVENT_LOCAL`), **Any member of this chapter** (any signed-in member), or **Chapter admins only** (`ADMIN_LOCAL`). Organization admins clear all three. An organization-wide event manager (`EVENT_TENANT`) clears the first two but is refused by **Chapter admins only**, which only chapter admins and organization admins satisfy. Any chapter admin can change the setting, since editing the chapter is already theirs. The setting does not travel down the chapter tree, so opening one chapter to all its members never opens the chapters beneath it. Somebody below the bar can still open the event form and pick the chapter; the refusal comes when they save. See [Create Event](/docs/platform/events/create-event). Chapter form showing the General information, Location and Organization sections with status, name, Alias, the who can create events selector, founded, town, map location, map description, the parent chapter selector, the parent chapter checkbox and the Region field *** ## The chapters list Filter by status (**All statuses**, active, pending close, suspended, closed; defaults to active) and by **town** (searchable). **Remove sorting** appears once you sort a column. Sortable columns: name, **Region** (when regions are on), status, **members**, **Full members**, town, county, **founded**, **Stripe**, **Online fee activated**. The last two appear only when the matching payment settings are active. Member counts link to a filtered member list for `HR_TENANT`. With parent chapters on, the list arrives in tree order: each top-level chapter is followed by its whole branch, parents before the chapters under them, siblings alphabetical, and chapters with no family last. A chapter's row is indented by how deep it sits, so the third layer is indented further than the second. A member count followed by `(+N)` is a branch total: the figure is that chapter plus everything under it, and `N` is how much of it came from the chapters beneath, counted through the whole branch rather than one layer down. Subtract `N` for the chapter's own members, which is the number the [Groups page](/docs/platform/groups) shows on the chapter row. Sorting a column with the header still flat-sorts the rows on the page you are looking at and breaks the tree grouping. **Remove sorting** restores it. That is unchanged, and it is why the tree order is the default. The **...** row action opens Members, Events, Discussions, Edit, one entry per local unit type, plus **fees** for organization admins when fees are active. It shows for `ADMIN_TENANT`, `ADMIN_LOCAL` on that chapter, and members of that chapter. **map** plots every active chapter that has coordinates on an OpenStreetMap panel above the table; chapters with missing coordinates, or coordinates that are not valid numbers, are skipped rather than breaking the map. With the map open, `ADMIN_LOCAL` also gets **Iframe URL**, an embed link for your own website that renders the map alone and needs no login. *** ## Parent chapters and regions Two independent grouping mechanisms, both off by default, both in **Settings** → **Modules** → **Groups & Teams** → **Local Centers**: | Setting | What it does | | ------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Enable Parent Centers** | A chapter points at another chapter as its parent, forming a tree of any depth. Names then carry an LC or LP prefix, ordering becomes parent-then-descendants, and a parent's member count carries a `(+N)` figure for the members in the chapters beneath it. | | **Enable Regions** | A flat **Region** label you assign to each chapter, used for grouping, filtering, and role group eligibility. | Regions themselves are managed at **Settings** → **Modules** → **Groups & Teams** → **Regions** (`ROLE_ADMIN_TENANT`): add, rename, remove. A region cannot be deleted while any chapter or role group still points at it; Orgo says how many of each and asks you to reassign them first. Parent chapters and regions are not the same thing. Parent chapters affect permissions: the `*_PARENT_LOCAL` roles apply across a parent chapter and everything beneath it, at any depth. Regions do not grant anything on their own, and a region is a flat label rather than a layer of the tree. ### How deep the chapter tree goes There is no two-level limit. A chapter that has a parent can itself be a parent, so National → Region → District → Branch is a supported structure, and so is anything deeper. Two fields on the chapter form drive it: | Field | What it means | | ----------------------------- | ------------------------------------------------------------------------------------------------------------ | | **It's a parent chapter** | This chapter is allowed to have chapters under it. It says nothing about whether it has a parent of its own. | | **Belongs to parent chapter** | The chapter directly above this one. The picker offers only chapters flagged **It's a parent chapter**. | Tick both on the same chapter and it sits in the middle of the chain: a child of the one above and a parent of the ones below. Such a chapter appears under the **Parent chapters** bucket of the chapters list, because it is one. Four rules are checked when you save, and a refused save says which one you hit: * The chosen parent must be flagged **It's a parent chapter**. * A chapter cannot be its own parent. * A chapter cannot be placed under one of its own descendants. * The parent must belong to the same organization. Separately, you cannot untick **It's a parent chapter** while chapters still point at it. Move or detach them first; Orgo does not detach them for you. Changing where a chapter sits requires `HR_TENANT`. The **Belongs to parent chapter** selector and the **It's a parent chapter** checkbox are shown to chapter administrators but greyed out, so they can see their place in the structure without being able to change it. Everything else on the chapter form stays editable with `ADMIN_LOCAL`. The reason is that the parent link decides who administers whom: moving a chapter hands its whole branch to a different set of administrators. The check only fires when one of those two fields actually changes, so ordinary edits to a chapter are unaffected. A depth ceiling of 20 exists as a guard against a loop in the data, not as a structural limit you are expected to reach. *** ## What a chapter owns The chapter header carries tabs, each scoped to that chapter: | Tab | Requires | | ---------------- | ------------------------------------------------------------------------------------------- | | **discussions** | Discussions module active | | **events** | Events module active | | **files** | Drive module active | | **members** | Members view rights | | Local unit types | `HR_LOCAL` and at least one unit type marked as local (see [Units](/docs/platform/groups/units)) | | **analytics** | Analytics module active and a matching grant | Chapter page showing the status and Chapter badges, the shortcut card, Contact and Address cards, and the Team panel grouping officers by role The page opens with a card of shortcuts into the chapter (Members, Events, Discussions, and conditionally Chapters, Teams, Fees and **Annual report**). The card carries no heading of its own. Below it sit the Contact, Address, Legal details and Online cards, and beside them a **Team** panel grouping officers by role, with a count on any role held by more than one person. Admins add a member to a role, drag members between roles, and remove them; adding someone from another chapter asks you to confirm the transfer. The Team panel only lists roles marked as chapter roles in **Settings** → **Users & Profiles** → **Roles**, and a parent chapter reads a different flag from an ordinary one. A top-level parent chapter shows only roles flagged for parent chapters, so a role that appears on a branch page can be absent from its parent. A chapter that is both a parent and a child shows both sets, because it holds both kinds of post. **analytics** reuses the organization dashboards scoped to the chapter: Platform, Members, geography, Leaderboards, Finance. Each appears only if you hold the local counterpart of the role that grants it organization-wide, so Members analytics granted to `HR_TENANT` shows here with `HR_LOCAL`. Finance also needs online payments active. Chapter-level tasks do not exist, and the **issues** tab is limited to project groups. *** ## Local administration Local permissions sit on a member's profile, in the **Permissions** panel, under three headings that show each checkbox's scope: **Organization** (your org name), **Chapter** (the member's chapter), and **Parent chapter**. | Permission | Scope | | ------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- | | `ADMIN_LOCAL` | Full control of one chapter, including editing it | | `HR_LOCAL` | Member management inside the chapter | | `FINANCIAL_LOCAL` | Fees and payments for the chapter | | `EVENT_LOCAL` | Events for the chapter | | `COMMUNICATION_LOCAL` | Communications for the chapter | | `HR_ASSISTANT_LOCAL` | Reduced member management | | `ADMIN_PARENT_LOCAL` | Every local permission across a parent chapter and every chapter beneath it, at any depth | | `HR_PARENT_LOCAL` | Member management across a parent chapter and every chapter beneath it | | `FINANCIAL_PARENT_LOCAL` | Fees across a parent chapter and every chapter beneath it | | `EVENT_PARENT_LOCAL`, `COMMUNICATION_PARENT_LOCAL`, `HR_ASSISTANT_PARENT_LOCAL` | The same widening for those areas | The `_PARENT_LOCAL` variants only mean something when **Enable Parent Centers** is on, and local permissions are hidden entirely when the Local Centers module is off. ### What a parent-scope permission reaches A `_PARENT_LOCAL` permission is anchored to one chapter, and the anchor is worked out from the holder's own primary chapter. You do not choose it. | The holder's own chapter | The anchor | | ------------------------------------- | ----------------------------- | | Flagged **It's a parent chapter** | That chapter itself | | Has no parent at all | That chapter itself | | An ordinary chapter that has a parent | The chapter directly above it | The permission then covers the anchor **and every chapter below the anchor, however many layers down**. It never reaches upward or sideways: not the chapter above the anchor, and not another branch of the tree. Worked example. National holds North Region; North Region holds Riverside and Hillside; Riverside is itself flagged as a parent and holds Riverside East. | The holder's chapter | `HR_PARENT_LOCAL` covers | | ----------------------------------- | ----------------------------------------------------- | | National | National and every chapter beneath it | | North Region | North Region, Riverside, Hillside, Riverside East | | Riverside, flagged as a parent | Riverside and Riverside East only, never North Region | | Riverside East, an ordinary chapter | Riverside and Riverside East | | Hillside, an ordinary chapter | North Region, Riverside, Hillside, Riverside East | Hillside surprises people: an ordinary chapter anchors to the chapter above it, so the grant reads as "everything under the same parent as this person", and at three layers that includes cousins further down. Flagging a chapter as a parent is what pins the anchor to the chapter itself and stops the grant climbing. `ADMIN_LOCAL` and the other `_LOCAL` permissions are unchanged: exactly the holder's own chapter, never a chapter beneath it. Wherever a parent chapter is the filter, the results now cover its whole branch rather than one layer: members, fee and product payments, subscriptions, adhesions, transfer requests, resignation requests, waitlist entries, chapter analytics, and the member counts on the chapters list. Filtering payments or subscriptions by a chapter now requires `FINANCIAL_LOCAL` over that chapter and refuses with an access error otherwise. The check existed before but its result was not applied, so the filter answered for anyone who could open the screen. Every member has exactly one primary chapter. **Multi local center access** lets `HR_TENANT` and `ADMIN_TENANT` grant additional chapters from the profile, each with its own permission level and optional end date; without that setting, extra chapters are unavailable. These are access grants, not a second home chapter, so for cross-chapter work use a [Private Group](/docs/platform/groups/private-groups) or a [Role Group](/docs/platform/groups/role-groups), and to move someone for good raise a [transfer request](/docs/platform/groups/transfers). *** ## Statuses and closing a chapter | Status | Effect | | ----------------- | --------------------------------------------------------------- | | **Active** | Normal operation | | **Pending close** | Still counted as active; signals a wind-down | | **Suspended** | Still counted as active | | **Closed** | The only inactive status; the chapter drops out of active lists | Deleting a chapter (`ADMIN_TENANT`) first checks for local Stripe customers, pending invitations, and transfer requests still pointing at it. If any exist, Orgo sets the status to **Closed** and stamps an end date instead; if none exist, the record is removed outright. *** ## Chapter settings A chapter has its own settings sidebar, shown to `FINANCIAL_LOCAL` and, for the first entry, to `HR_LOCAL`: | Entry | Appears when | | ---------------------------------- | ------------------------------------------------------------------------------------------ | | **Chapter** | Always, for chapter admins; this is the chapter edit form | | **feeSettings** | Fees are active and local fees are enabled | | **Local online payments settings** | Online payments are active with local payments enabled, and the chapter is Stripe eligible | | **Fee product** | As above, and the chapter has a fee product assigned | | **Waitlist settings** | The waitlist module is active | A chapter can carry its own fee product, default price, and connected Stripe account, so local dues are collected and reported separately from national ones. See [Local Group Fees](/docs/platform/local-group-fees/create-local-fees). **Waitlist settings** applies per member type, not per chapter: enable each type and give it a **Maximum Capacity** (blank means unlimited). The panel shows **Current Count** and **Available Spots** per type, and warns before you disable a type that still has registered members. *** ## Public chapter finder `/local-center-map/` is a separate, member-facing finder built on Google Maps, and it opens without a login. Visitors search by postal code or address, filter by age group, cost range, meeting nights and languages, sort by cost, save favorites, and go from a result card into registration. The filter is labelled **Night(s) available** and reads the chapter's days of the week. Chapters supply the data through their coordinates, map description, languages, days of the week, and fee price. Public chapter finder with a postal code search box, age group, cost, night and language filters, a results list, and pins on a Google map The finder opens on the visitor's own location. If the browser refuses to share it, the map falls back to the centre of your own chapters and the results panel lists the ones nearest to that point. A chapter with no coordinates is invisible to both the pins and the results, so give every chapter coordinates; if none of them has any, the map has nothing to centre on and the panel reports no chapters within 200km until the visitor searches an address or presses **All local centers**. With the website builder, chapters also publish to `/chapters` and `/chapter/:id` as public pages. *** ## Troubleshooting Three ways: a `_PARENT_LOCAL` permission covers the holder's anchor chapter and every chapter beneath it at any depth, **Multi local center access** grants them named chapters on their profile, or a tenant-level role covers everything. Turn on **Open Access Local Centers**. Every member then sees content from every chapter and receives its notifications, and can mute individual chapters from the chapter header. The opposite setting, **Isolate Local Center Access**, hides the chapters above a member. It is applied one layer at a time: a chapter higher up the chain is visible to them only when their own `HR_PARENT_LOCAL` reach covers that particular chapter, and the same test now hides role groups scoped to a chapter they cannot see. Previously those role groups slipped through the isolation setting. The two settings are mutually exclusive. Their own chapter and every chapter above it in the chain, subject to **Isolate Local Center Access** above. Membership travels up the tree and administration travels down: being a member of a branch puts you in the spaces of the region and the national body above it, while being a member of the national body does not put you in the branches below it. Ancestor chapters appear in the sidebar as ordinary entries alongside the member's own chapter. They are not drawn as a nested tree and carry no label saying which layer they belong to. That is **Center Name Format** under **Settings** → **Modules** → **Groups & Teams** → **Local Centers**, which defaults to `%town% - %name%`. The LC and LP prefixes come from a separate switch, **Show LC/LP prefix**, and apply only when parent chapters are enabled. Check its status. The list opens on the active filter, and that filter means the exact **Active** status, not the three statuses that count as active. A chapter set to **Pending close** or **Suspended** drops out of the default view while still being counted as active in member counts and reports. Switch the status filter to **All statuses** to see it, which is also the only setting under which the status column itself appears. The same rule reaches past the list. The map, the destination picker on a transfer request and the extra-chapter picker under **Multi local center access** all read the unfiltered chapter feed, which serves exactly-Active chapters. So suspending a chapter also stops anyone transferring a member into it, which is usually more than was intended. Lists that filter on "active" rather than reading that feed, such as the chapter filters on member and fee screens, do include Pending close and Suspended. Use **Pending close** to signal a wind-down you still need to work with, and **Closed** when you mean the chapter to leave. That is the designed fallback and it is silent: both outcomes report success the same way, so the list is the only place you find out which one happened. Orgo hard-deletes a chapter only when nothing points at it. Three things block that: a member with a local Stripe customer record for the chapter, a pending invitation, and any transfer request naming it as the origin or the destination. Transfer requests are kept as history rather than cleared, so a chapter that has ever exchanged a member, or ever taken one local online payment, can only ever be closed and not removed. In practice that is most chapters that have run for a season. When a hard delete does go through, the members are not deleted with it. Their chapter field is emptied, which leaves them with no chapter until somebody reassigns them. A member in that state fails any check that compares their chapter with the chapter of the thing they are looking at, so local fees and local permissions stop resolving for them. Move the members first, then delete. The reach of a `_PARENT_LOCAL` permission is worked out from the holder's own primary chapter, and it only ever travels downward. You are not choosing which branch it covers when you tick the box. The full rule is in [What a parent-scope permission reaches](#what-a-parent-scope-permission-reaches). Worked example: Riverside and Hillside are both children of North Region. Give `ADMIN_PARENT_LOCAL` to a member whose primary chapter is Riverside and they administer North Region, Riverside, Hillside and anything below those. Give the same permission to a member of a chapter under South Region and it covers South Region instead. Nothing you do on the permissions panel points it at another branch. Two rules catch people out: * With **Enable Parent Centers** on, a chapter that has no parent of its own is treated as its own anchor. So `ADMIN_PARENT_LOCAL` on a member of a stand-alone top-level chapter is effectively `ADMIN_LOCAL` over that chapter, widening only as chapters appear beneath it. * A chapter flagged **It's a parent chapter** is also its own anchor, even when it sits in the middle of the chain. A district officer therefore administers the district and its branches but never the region above it. That is deliberate: it stops a mid-level grant climbing to the top of the organization. To give somebody authority over a branch that is not theirs, either move their primary chapter with a [transfer](/docs/platform/groups/transfers), or use **Multi local center access** and name the chapters. That was a real defect and it is fixed. Filtering the member directory by a parent chapter returned only the members filed directly against that chapter, silently dropping everyone in the chapters below it, from December 2025 until this release. The filter now returns the whole branch. If you built reports or saved links against the old behaviour, the numbers they produce will be larger now, and the larger figure is the correct one. To get only a chapter's own members, filter on that chapter without its parent flag, or take the member count on the chapters list and subtract the `(+N)` beside it, which is the part contributed by the branch below. Check whether **Multi local center access** is still on. Every extra chapter grant is stored on the member's profile, but permission checks only consult those rows while the setting is enabled. Turn it off and the grants stop counting immediately, the panel disappears from the profile, and nothing reports that anything was withdrawn. Turn it back on and every grant returns exactly as it was, because the rows were never deleted. Two quieter reasons for the same symptom: a grant with an end date in the past no longer appears or applies, and a grant pointing at a chapter that is no longer Active drops out of the panel, since it lists Active chapters only. A pin is drawn from **Map location** when it is set, and from the chapter's **town** coordinates when it is not, so a chapter with a town usually appears without anyone entering coordinates. It is skipped only when it has neither, or when what is stored is not a pair of numbers, which happens when a name lands in the latitude box. Only exactly-Active chapters are plotted, so a suspended chapter has no pin either. Where the map opens is a separate setting. It uses **International Map Center** and **International Map Zoom Level** if they are filled in, then the coordinates of your organisation's country. With neither, it centres on latitude 0, longitude 0, which is open water in the Gulf of Guinea and looks like a broken map. Setting the two international values fixes it, and they are the right place to control the opening view for an organisation that spans several countries. Two different refusals, with two different causes. "Changing chapter hierarchy requires tenant-level permission" means you hold `ADMIN_LOCAL` rather than `HR_TENANT`. Only organization-level HR can move a chapter in the tree. Nothing else on the form is affected: save the same edit without touching the parent selector or the **It's a parent chapter** checkbox and it goes through. A message about the parent being invalid, a chapter being its own parent, a descendant being chosen, or parent status not being removable means one of the structural rules under [How deep the chapter tree goes](#how-deep-the-chapter-tree-goes) was broken. The most common one is picking a chapter that is not itself flagged **It's a parent chapter**: flag it first, then set the link. Two checks disagree, and the failure lands between them. The route asks only whether you hold `ADMIN_LOCAL` somewhere, without looking at which chapter is in the address, so the page loads. The form then renders only for `ADMIN_TENANT` or for your own primary chapter, so for anyone else the page stays empty. No permission message is shown. So a chapter admin who follows a link to a different chapter's edit page gets a blank screen rather than "you cannot edit this". This includes somebody holding **Multi local center access** on that chapter, even where the save itself would be accepted, because the form checks the primary chapter only. A member who holds no `ADMIN_LOCAL` at all fails the route check instead and is sent to the login screen, which looks like a session that has expired and is not one. That behaviour is the same on any page they lack the role for. *** ## Related * [Groups Overview](/docs/platform/groups) - all group types and when to use each * [Units](/docs/platform/groups/units) - smaller teams inside a chapter * [Member Transfers](/docs/platform/groups/transfers) - moving a member between chapters * [Local Group Fees](/docs/platform/local-group-fees/create-local-fees) - collecting dues at chapter level * [Permissions](/docs/platform/permissions) - how the local and parent-local roles are evaluated # Main Group Source: https://orgo.space/docs/platform/groups/main-group The organization-wide space every member can reach, and how to build an all-members group **Built for** organizations that need one place to reach everyone. **Replaces** the "all staff" mailing list nobody can search. Orgo gives you two ways to reach the whole organization, and they work differently: | | Organization space | Auto-enroll group | | ------------------ | ------------------------------------------------------------ | ---------------------------------------------------------------- | | What it is | The top-level space named after your organization | An ordinary group with Access set to **Auto-enroll all members** | | Where it sits | First card on the Groups page, and at the top of the sidebar | Under **Community groups** on the Groups page | | How many | Exactly one, always present | As many as you want | | Membership | Everyone, implicitly | Everyone, implicitly | | Can members leave? | No, they can only mute it | No, they can only mute it | | Members tab | Yes, if permitted | No | | Can it be deleted? | No | Yes | Use the organization space for the default feed. Create auto-enroll groups when you want more than one all-hands channel, for example a locked-down **Announcements** group alongside an open **General Discussion** group. Organization-wide discussion feed with the organization name in the header and the Discussions, Events, Files and Members tabs *** ## The organization space ### How to reach it Click your organization's name at the top of the sidebar, or open the first card on the **Groups** page. The sidebar keeps it visible even when the Groups section is collapsed. ### What it contains The same tabs as any other space, subject to which modules are on: | Tab | Shows | | --------------- | ------------------------------------- | | **Discussions** | The organization-wide discussion feed | | **Events** | Events not tied to a group or chapter | | **Files** | The organization-level file area | | **Members** | The full member directory | Unlike a group, the organization space does not turn [discussion categories](/docs/platform/discussion/discussion-namespaces) into extra tabs. Organization-wide categories still apply here: they appear as a filter list beside the feed, with a gear icon for managing them. ### Who can see the member directory **Settings** → **Users & Profiles** → **Permissions setup** → **Users Module** → **Who can see members in general unit group**. Set it to the minimum permission a member needs to open the **Members** tab here. Members holding `HR_TENANT` or `FINANCIAL_TENANT` always see it. ### Notifications Each member controls their own subscription with the **Subscribe** / **Subscribed** button on the organization card. Turning it off stops notifications; it does not remove them from the space, and nothing about their access changes. The organization space is not a group record. It cannot be renamed, archived, deleted, or given its own posting rules. To control who can post organization-wide, use an auto-enroll group instead. *** ## Building an all-members group An auto-enroll group behaves like the organization space but is a real group, so you can name it, give it a logo and emoji, restrict posting and archive it later. **Groups** → **Create group**. You need `ADMIN_TENANT`. The description under the option reads "Add all members automatically". Every active member of your organization is included, and none of them can leave. Turn on **Discussions**, **Files** and **Events** as needed. At least one has to stay on. **Only admins** turns the group into an announcement channel. **Everyone in the group** keeps it open. The group appears immediately under **Community groups** for every member. A common setup: an **Announcements** group on **Only admins**, plus a **General Discussion** group on **Everyone in the group**. Members get a clean announcement feed and a separate place to talk. Auto-enroll groups have no **Members** tab, because their membership is defined as "everyone" rather than stored per member. To browse people, use the organization space's Members tab or the Members page. *** ## Common scenarios You cannot restrict posting on the organization space itself. Create an auto-enroll group with **Who can post?** set to **Only admins** and direct announcements there, leaving the organization space for open conversation. Open the organization space, go to **Files**, and upload it there. Every member has access. For a curated document set, use an auto-enroll group with only **Files** enabled and posting set to **Only admins**. No. The **All Members Group** switch in **Settings** → **Groups & Teams** → **Configuration** looks like it does this, but nothing reads that setting and toggling it changes nothing. Check the **Subscribe** button on the organization card on their Groups page. Anyone can unsubscribe themselves, which silences notifications without affecting access. Enable [discussion categories](/docs/platform/discussion/discussion-namespaces). Created on a group, they render as extra tabs inside that group. Created organization-wide, they apply to the organization space, where they appear as a filter list beside the feed rather than as tabs. *** ## Related * [Groups & Teams](/docs/platform/groups) - all access modes and when to use each * [Private Groups](/docs/platform/groups/private-groups) - committees and project teams * [Role Groups](/docs/platform/groups/role-groups) - criteria-based automatic membership * [Local Centers](/docs/platform/groups/local-groups) - geographic branches * [Discussions](/docs/platform/discussion) - the discussion feed # Private Groups Source: https://orgo.space/docs/platform/groups/private-groups Invite-only spaces for committees, boards and project teams, and the open alternative **Built for** committees, boards, working groups and project teams that need a space nobody else can see. **Replaces** the private Slack channel that lives outside your member records. A private group is a group whose **Access** is set to **Private**, described in the app as "Only invited members have access". Members who are not in it cannot open it, cannot see its discussions and do not see it listed. It is the default a member gets when they create a group without organization admin rights. Private groups are listed under **Private groups** on the Groups page. Bottom of the Groups page showing the Community groups section and the Private groups section, each group listed with its member count *** ## Private or open to join These are the two member-run access modes. Pick deliberately, because they behave very differently. | | **Private** | **Open to join** | | ----------------------------- | -------------------------------- | ------------------------------------------- | | Description in the app | Only invited members have access | Anyone in community can join | | Who can create it | Anyone allowed to create groups | `ADMIN_TENANT` only | | Visible to non-members | No | Yes, under **Community groups** | | How people get in | A group admin adds them | They join themselves, or an admin adds them | | Approval step | None, adding is immediate | None, joining is immediate | | Can be filed under a category | No | Yes | | Shareable join link | No | Yes | Joining an open group never waits for approval. Any member who follows the link or clicks **Join** is in straight away. If you need to vet people, use **Private** and add them yourself. You can switch a group between the two modes later by editing it, provided you have `ADMIN_TENANT` for the open modes. Starting private and opening up later is safer than the reverse. *** ## Creating a group **Groups** → **Create group**, or the **+** in the sidebar's Groups section. A name that explains the purpose. "Q4 Marketing Campaign" beats "Marketing Group". Optionally pick a **Menu emoji** that shows beside it in the sidebar. **Private** for invite-only. Organization admins also see **Open to join**, **Auto-enroll all members** and **Role group**. Members without `ADMIN_TENANT` do not see the Access selector at all and get a private group. Only offered on open and auto-enroll groups, and only when **Enable Group Categories** is on. You only see the categories you are allowed to create in. **Discussions**, **Files** and **Events**. At least one must stay on. Each one also needs its module enabled organization-wide to appear. **Everyone in the group** or **Only admins**. This one control covers discussions, files and events together. Rich text, with images. Once set, it becomes the group's **About** tab. You become the group's owner and its first admin, and you land on the Members tab ready to add people. Turn on only the features you need. A board needs Discussions and Files. A hiking club needs Discussions and Events. Fewer tabs means less clutter. *** ## Managing members Open the group and go to the **Members** tab. ### Adding people Group admins get a search box on the Members tab. Type a name, pick the member, and they are added immediately. There is no email invitation and no pending state, so the person must already have an account in your organization. For an **Open to join** group, the **Join group link** button copies a URL you can paste into an email or chat. Anyone in your organization who opens it is joined on the spot and taken to the group's discussions. ### Roles inside a group | Role | What it is | What it can do | | ---------- | ------------------------------------- | ----------------------------------------------------------------------------------- | | **Owner** | The member who created the group | Everything an admin can do, and delete the group. Cannot be removed from the group. | | **Admin** | A member promoted with **Make Admin** | Add and remove members, promote others, edit the group's settings, archive it | | **Member** | Everyone else | Take part according to **Who can post?** | Promote or demote from the row menu on the Members tab: **Make Admin** and **Dismiss as Admin**. Adding someone to a group requires an active admin role inside that group. Removing a member and changing who is an admin is also open to organization moderators (`HR_TENANT`), and `ADMIN_TENANT` can edit, archive and delete any group whether or not they are in it. ### Leaving and removing Members can leave from **Leave group** in the group's header menu. The owner cannot leave their own group, and nobody can leave an auto-enroll group. Admins remove members from the row menu on the Members tab. Removal takes effect immediately and the person loses access to everything in the group. *** ## Who can see what | Situation | Result | | ------------------------------------------------------ | --------------------------------------------------------- | | A non-member opens a private group | Access denied. The group is not listed for them either. | | A non-member opens an open group | They see it and can join | | An organization admin (`ADMIN_TENANT`) opens any group | Full access, including editing and deleting it | | A member is removed | Immediate loss of access to discussions, files and events | *** ## Archiving and deleting Open the group's **Settings** from its header, or edit it from the Groups page. | Action | Who | What happens | | ------------- | ------------------------------------- | ---------------------------------------------------------------------------------------- | | **Archive** | Owner, group admin, or `ADMIN_TENANT` | The group moves to the **Archived** tab. Members stay members and no content is removed. | | **Unarchive** | `ADMIN_TENANT` | Restores it from the **Archived** tab, exactly as it was | | **Delete** | Owner or `ADMIN_TENANT` | Permanent. Confirm dialog only, no recovery. | Prefer archiving. Archived groups keep their discussions, decisions and files, and an organization admin can bring them back at any time. A group with a newsletter attached refuses to delete until you remove the newsletter, so archive it instead. *** ## Common scenarios Members can already create groups if **Who can create** is left at its `USER` default, but what they get is a **Private** group only they can see until they add people. To let members discover and self-join interest communities, an organization admin has to create the group as **Open to join**. Archive it. It leaves the main list but everything is preserved, and it can be unarchived later. Not by editing it. The **Role group** option in the Access selector is a different kind of space with criteria-based membership. Create a [role group](/docs/platform/groups/role-groups) and archive the private one. Any member with `ADMIN_TENANT` can open the group's settings and manage it, including archiving or deleting it. Ownership itself stays with the original account and is not reassignable from the interface. Create it as **Open to join** and set **Who can post?** to **Only admins**. Members find it, join it and read it; only group admins and organization moderators post. Remove them from the row menu on the Members tab. Access ends immediately, though anything they already read or downloaded is obviously already out. Either **Discussions** is off in the group's Features, or the Discussions module is off for the whole organization. The same applies to Files and Events. Non-members never see the tabs at all. *** ## Related * [Groups & Teams](/docs/platform/groups) - all access modes and when to use each * [Role Groups](/docs/platform/groups/role-groups) - criteria-based automatic membership * [Main Group](/docs/platform/groups/main-group) - the organization-wide space * [Local Centers](/docs/platform/groups/local-groups) - geographic branches * [Permissions](/docs/platform/permissions) - what `ADMIN_TENANT` and `HR_TENANT` cover # Role Groups Source: https://orgo.space/docs/platform/groups/role-groups Groups that fill themselves from member roles, age, gender, chapter, region or fee tier **Built for** organizations that keep re-sending the same message to "all leaders" or "all under-18s". **Replaces** manually maintained distribution lists that drift out of date the moment someone changes role. A role group is a collaborative space whose membership is a query, not a list. You set the criteria once and Orgo keeps the membership in step with your member data: when someone takes on a role, changes chapter or updates their profile, their role group memberships are recalculated. Role groups appear under **Teams** on the Groups page. Groups page with the Role groups tab selected, listing the organization's role groups with an edit action on each *** ## Before you start Role groups need **Enable Role Groups** on under **Settings** → **Groups & Teams** → **Configuration**, and `ADMIN_TENANT` to create or edit. Without both, the **Role group** access mode, the **Create role group** action and the **Role groups** tab are hidden. *** ## Creating a role group **Groups** → **Create group** → **Create role group**, or pick **Role group** in the **Access** selector on the normal create form. A name that describes the membership, plus an optional **Menu emoji** shown beside it in the sidebar. The **Segmentation type** toggle switches between **Profile** (who the member is) and **Roles** (what they have been assigned). Fill in the fields below. Saving scans your members, populates the group and subscribes them, so they get its notifications. Role groups do not offer the **Features** and **Who can post?** controls that ordinary groups do. *** ## Criteria ### Profile segmentation | Field | Matches | Notes | | ------------------------- | ------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- | | **Min age** / **Max age** | Members whose date of birth falls inside the range | Options run from 16 to 120. A member with no date of birth never matches an age filter. | | **Gender** | Male, female or other | | | **Region** | Members whose chapter belongs to that region | Only shown when the Local Centers module is on and regions exist | | **Only full members** | Members flagged as full members, or holding the user type configured as the adhesion success type | | | **Membership fee tier** | Members on any of the selected fee prices | Only shown when the Fees module is on and a membership fee product is configured. Company prices are never offered. | Role group criteria card with the Segmentation type toggle and the Min age, Max age, Gender, Region, Only full members and Membership fee tier fields ### Roles segmentation Under **Users with any of the following roles**, tick the roles that qualify; a member matching any ticked role is in. Roles are grouped by where they apply: **User type**, **Tenant**, **Parent chapter**, **Chapter**, each unit type, and **Other**. Alongside it, **Chapter** restricts the group to one chapter, and picking a parent chapter covers every chapter beneath it, at any depth: with a three-layer structure, restricting a group to the national chapter includes the regions and their branches. Role groups cannot filter on custom profile fields. If your segment is defined by a custom field, use a [private group](/docs/platform/groups/private-groups) and manage the membership yourself. ### Combining criteria Every field you fill in must match, so criteria narrow the group, and an empty field is not applied. Only members with an active status are ever included. The **Segmentation type** toggle only changes which fields are on screen; it does not clear the other set. Values set under **Profile** stay in effect when you switch to **Roles**, so "leaders over 18" is the leader roles ticked plus **Min age** 18. | Role group | Segmentation | Criteria | | ----------------- | ----------------- | ----------------------------------------------------- | | All leaders | Roles | Tick every leader user type | | Youth 13-17 | Profile | Min age 13, Max age 17 | | Adult leaders | Roles and Profile | Tick the leader roles, then set Min age 18 | | Chapter committee | Roles | Tick the committee roles, Chapter set to that chapter | *** ## When membership is recalculated * when you save the role group itself, which rebuilds it from scratch * when a member's roles are added, changed or removed * when a member's profile is created or edited * when a chapter's region changes, for region-based role groups Recalculation both adds newly matching members and drops those who no longer match, so a promotion needs no manual move. There is also a maintenance command an administrator can run to rebuild every role group in the organization at once. Age boundaries are evaluated when membership is recalculated, not on the member's birthday. A member who crosses an age threshold joins or leaves the group the next time their profile or roles are saved, or the next full rebuild. *** ## Adding people the criteria miss A role group has an **Admins** tab, visible to organization admins. Anyone added there is kept in the group even though they do not match the criteria, and survives the rebuild that a re-save triggers. Use it for the exceptions that always exist; for anything larger, adjust the criteria. Ordinary members cannot leave a role group, because membership is derived from their profile. They can mute it with the **Subscribe** / **Subscribed** button on the Groups page. *** ## What is inside a role group **Discussions**, **Events** and **Files** where the corresponding modules are enabled, plus a **Members** tab and the **Admins** tab for organization admins. *** ## Editing, archiving and deleting Edit a role group from the gear icon on the **Role groups** tab of the Groups page, or from **Settings** in the group's own header. | Action | Permission | Effect | | ------------- | -------------- | -------------------------------------------------------------------------------------------------------------- | | **Edit** | `ADMIN_TENANT` | Saving rebuilds the membership from the new criteria. Manually added members from the Admins tab are re-added. | | **Archive** | `ADMIN_TENANT` | Moves it to the **Archived** tab. Membership is left alone, so a later unarchive restores it as it was. | | **Unarchive** | `ADMIN_TENANT` | Restores it from the **Archived** tab | | **Delete** | `HR_TENANT` | Removes the role group and its role assignments permanently | *** ## Common scenarios The criteria are over-narrowed. Every field you fill in must match, and age criteria exclude members with no date of birth. Clear a field to stop applying it. Yes, set **Chapter** in the Roles segmentation. Each chapter is already its own space with discussions, events and files, so a per-chapter role group is only worth it when you also need a role filter on top. *** ## Related * [Groups & Teams](/docs/platform/groups) - all access modes and when to use each * [Private Groups](/docs/platform/groups/private-groups) - for manually controlled membership * [Main Group](/docs/platform/groups/main-group) - the organization-wide space * [Local Centers](/docs/platform/groups/local-groups) - geographic branches * [Permissions](/docs/platform/permissions) - what `ADMIN_TENANT` and `HR_TENANT` cover # Member Transfers Source: https://orgo.space/docs/platform/groups/transfers Move a member from one chapter to another with a request, a reason, and an approval by the receiving chapter **Built for** organizations where members relocate and the receiving branch expects a say before someone lands on their roll. **Replaces** the email thread between two branch secretaries, and the silent database edit that leaves neither side with a record. A transfer request moves a member's primary chapter. Someone raises it with a written reason, the receiving chapter approves or denies it, and Orgo keeps the whole exchange: who asked, who decided, when, and why. Transfer requests list with All, Pending, Approved and Declined filters and one row per request showing member, requester, both chapters, the date processed and the status *** ## Before you start | Requirement | Where | | ----------------------------------------------------------------- | --------------------------------------------------------------------------- | | **Enable Local Centers Module** switched on | **Settings** → **Modules** → **Groups & Teams** → **Local Centers** | | **Local Center Request Notifications** switched on for the emails | **Settings** → **Modules** → **Emails & Notifications** → **System Emails** | | `HR_LOCAL` to see the requests list and to decide on a request | Scoped to the chapter concerned | *** ## Raising a request Two **Request local transfer** buttons lead to the same form: * On a member's profile, in the **Permissions** panel. This is the admin route, and it opens the form as a panel over the profile. * On the support page, for members who are not part of the support team. This requires the Support module to be active. The form itself needs nothing beyond a signed-in session, so members without a support page can be sent to it directly. The **Current local center** field is filled in and locked. When an admin raises the request, the member's name is shown above it, also locked. **New local center** is a searchable chapter selector and is required. **Reason for transfer request** is a required free text field. It is shown verbatim to whoever decides. The request is created with status **pending** and stamped with the current chapter and the time. Below the form, the requester sees **My transfer requests**: date requested, destination chapter, status, date processed, and a link into each one. Local center transfer request form with locked current chapter, new chapter selector, reason field, and the requester's past requests below ### Who may raise one for someone else | Requester | Allowed | | -------------------------- | ---------------------------------------------------------- | | The member, for themselves | Always | | `ADMIN_TENANT` | For any member in the organization | | Anyone else | Only with `HR_LOCAL` over the member's **current** chapter | Four rules are checked before the request is accepted: * A destination chapter must be selected. * The member and the destination chapter must both belong to your organization. * The destination cannot be the member's current chapter. * The member cannot already have an open request. Decide the existing one first. Once the request is saved, every organization admin with a valid email address is notified, except the member themselves. *** ## Deciding a request Open the request from the transfer requests list. The detail panel shows status, date requested, member, requester, both chapters, and the reason. **Approving requires `HR_LOCAL` over the destination chapter**, not the source. The receiving chapter is the one that decides, so a source-chapter admin can raise a request but cannot wave it through. * **approve** applies immediately. * **Deny** first reveals a **Deny reason** box, which must be filled in, then **Confirm deny** applies it. A request that has already been approved or declined cannot be decided again. ### What actually moves On approval Orgo does exactly three things: 1. Sets the member's primary chapter to the destination. 2. Ends the member's open role assignment for their member type, stamping it to the chapter they are leaving so the history stays correct. 3. Creates a new open role assignment of the same member type in the destination chapter. It also records the approver and the timestamp, and emails the member. Nothing else follows the member. Discussions they wrote, events they attended, files they uploaded, fee payments, invoices, and any additional roles or group memberships all stay attached to where they were created. Treat a transfer as a change of home chapter, not as a data migration. On denial, the member stays where they are. Orgo records who declined it, when, and the deny reason, and emails the member with that reason included. *** ## The transfer requests list Reachable with `HR_LOCAL`; anyone without it is bounced to the dashboard. The list has no menu entry of its own, so bookmark it. Filter buttons across the top: **All**, **Pending**, **Approved**, **Declined**. Thirty rows per page, sorted newest first, with **Date requested** and **Status** sortable. | Column | Shows | | ------------------------ | ------------------------------------------------- | | **Date requested** | When the request was raised | | **member** | Who is being moved | | **Requested by** | Who raised it | | **Current local center** | The chapter being left | | **New local center** | The destination | | **Date processed** | When it was approved or declined, or a dash | | **Status** | Pending (amber), Approved (green), Declined (red) | What you see is scoped to what you administer: | Your permission | Rows shown | | ----------------- | -------------------------------------------------------------------------------------------------- | | `HR_TENANT` | Every request in the organization | | `HR_PARENT_LOCAL` | Requests for your anchor chapter and every chapter beneath it, at any depth, plus your own chapter | | `HR_LOCAL` | Requests for your own chapter | Your anchor is your own chapter when it is flagged **It's a parent chapter** or has no parent, and otherwise the chapter directly above it. See [What a parent-scope permission reaches](/docs/platform/groups/local-groups#what-a-parent-scope-permission-reaches). Everybody also sees their own requests and the ones they raised for somebody else, whatever their permissions. **details** opens the request in a panel with the approve and deny actions, and the panel can be expanded to a full page. *** ## Transfer request or direct reassignment? There are two ways to change someone's chapter, and they are not equivalent. | | Transfer request | Direct reassignment | | -------------------------- | ---------------------------------------------------------------- | -------------------------------------------------------- | | Where | The transfer form or a member's **Permissions** panel | The chapter selector on a member's **Permissions** panel | | Who | The member, `ADMIN_TENANT`, or `HR_LOCAL` on the current chapter | `HR_TENANT` | | Approval | Required, by the destination chapter | None | | Reason recorded | Required | None | | Role assignments rewritten | Yes, closed at the old chapter and reopened at the new one | No | | Audit trail | Full, kept indefinitely | The change alone | Use direct reassignment for corrections (someone was filed under the wrong chapter on import). Use a transfer request whenever the move is a real one that the receiving chapter should know about. *** ## Common questions No. Only the destination chapter decides. The source-side admin can raise the request, but approval sits with `HR_LOCAL` on the receiving chapter. No. A second request is rejected while one is still undecided. Approve or deny the open one first. No. Both the member and the destination chapter must be in the same organization, and the request is refused otherwise. Check **Local Center Request Notifications** under **Settings** → **Modules** → **Emails & Notifications** → **System Emails**, and check that the member has a valid email address on their profile. Orgo skips the send rather than failing the transfer when either is missing, so the transfer itself will still have gone through. They stay as they are. Fee records, payments, and invoices are not rewritten by a transfer, so a debt raised at the old chapter remains recorded against the old chapter. Settle or write off outstanding items before approving if your accounting requires it. Not outright. A chapter named in any transfer request, as either side, is closed rather than deleted, keeping the request history readable. *** ## Related * [Local Centers](/docs/platform/groups/local-groups) - the chapters a member moves between * [Units](/docs/platform/groups/units) - team assignments inside a chapter * [Permissions](/docs/platform/permissions) - how `HR_LOCAL` and `HR_PARENT_LOCAL` are evaluated * [Groups Overview](/docs/platform/groups) - all group types and when to use each # Units Source: https://orgo.space/docs/platform/groups/units Named teams inside a chapter, typed and nested to match your real organizational structure **Built for** organizations whose chapters are themselves subdivided: patrols inside a troop, sections inside a branch, departments inside a council. **Replaces** the naming conventions people invent to fake structure ("Berlin - Team A", "Berlin - Team B") and the side spreadsheet that tracks who is in which one. A unit is a named team that lives inside a chapter. Units are typed, so you name the layers once (Section, Patrol, Department) and then create as many units of each type as you need. Units can nest, one type inside another, to whatever depth your structure requires. The segmented board is the view you will spend most time in: a column per unit, the members of each shown as cards. You move people by dragging a card from one column to another. *** ## Units, chapters, and groups All four sit on the same underlying structure in Orgo, which is why they share features like member roles and a name, but they behave differently: | | Belongs to | Membership | Created by | | ---------------------------------------------------- | ---------------------------------------------------------------- | -------------------------------------------- | ----------------------------------- | | **Chapter** (local center) | The organization, or another chapter when parent chapters are on | The member's primary chapter, one per member | `ADMIN_TENANT` | | **Unit** | A chapter (usually) and optionally a parent unit | Assigned by an admin | `HR_LOCAL` within their own chapter | | **[Private group](/docs/platform/groups/private-groups)** | The organization | People join or are invited | Any member allowed to create groups | | **[Role group](/docs/platform/groups/role-groups)** | The organization | Filled automatically from a query | `ADMIN_TENANT` | The practical difference: a unit describes where someone sits in the org chart, a group describes what they are working on. Units and chapters both nest, and they are separate trees. Chapters nest into each other to any depth (national, region, district, branch), and units nest inside one chapter along your chain of unit types. A unit never spans two chapters, and a unit is never the parent of a chapter. *** ## Before you start | Requirement | Where | | -------------------------------------------------------------------------- | ------------------------------------------------------------------- | | **Enable Organizational Units** switched on | **Settings** → **Modules** → **Groups & Teams** → **Configuration** | | At least one unit type defined | **Settings** → **Modules** → **Groups & Teams** → **Unit Types** | | `HR_LOCAL` to see the unit screens, `ADMIN_LOCAL` to create and edit units | Scoped to the chapter | *** ## Unit types A unit type is the template for a layer of your structure. Define them once at **Settings** → **Modules** → **Groups & Teams** → **Unit Types**, then create units of that type inside each chapter. Unit Types settings page showing type cards with Within local center and Has user types badges | Field | What it does | | ----------------------- | ---------------------------------------------------------------------------------------------------------------- | | **Title** | Singular name, used on buttons like "add Patrol" | | **Plural name** | Used as the page heading and the chapter tab label | | **Parent unit type** | The type one level up. Setting this is what makes units nest, and it drives the parent selector on the unit form | | **Within local center** | Units of this type belong to a chapter. New units are stamped with the creator's chapter automatically | | **Has user type** | Units of this type carry a member type, which colors them in the lists and boards | Creating, editing, and deleting unit types is restricted to organization admins (`ROLE_ADMIN_TENANT`). Delete a type only after nothing uses it. **Within local center** is the switch that decides whether a type shows up as a chapter tab and in the chapter row menu. A type without it produces units that are not tied to any chapter, so only tenant-level admins can manage them. *** ## Working with units ### The unit list The chapter header carries a tab named after your local unit types (visible with `HR_LOCAL`). It opens a list of every unit of that type in the chapter. The heading is the type's plural name. `HR_LOCAL` gets an **active** / **archived** filter. `ADMIN_LOCAL` gets an **add** button naming the type, and a pencil on each row. Each row shows the member type badge or logo, the unit name linking to its members, the member count, and the parent unit name (with an **archived** tag if the parent is closed). Clicking a row slides in the unit form: | Field | Notes | | --------------- | --------------------------------------------------------------------- | | **name** | Required | | **dateBegin** | Existing units only | | **dateEnd** | Only when the unit is archived | | **userType** | Only when the type has **Has user type** and member types are enabled | | Parent selector | Labelled with the parent type's name. Archived parents are marked | | **status** | **active** or **archived** | Deleting a unit asks for confirmation and removes its role assignments with it. ### The segmented board `ADMIN_LOCAL` also gets a drag-and-drop board for the whole chapter. When your types nest, it renders as columns: one per parent unit, with its child units stacked inside. Any child unit that has not been given a parent is collected in a final **Unassigned** column. When the type you are looking at has no parent type, the board is flat instead: one section per unit. From the board you can drag a member from one unit to another, use **Add member** to search and place someone, create a child unit inline, edit or delete a unit, set each member's role, and mark a member as **Admin** of their unit. The **Admin** flag on a unit member is not cosmetic. It delegates scoped fee access and unit event attendance, so it is restricted to people who already hold `HR_LOCAL`, `FINANCIAL_LOCAL`, or `ADMIN_TENANT` over the chapter. Unit admins cannot appoint each other. ### From the chapters list When units are enabled, each chapter row in the chapters list grows a chevron. Expanding it loads that chapter's whole unit tree inline, indented by depth, showing each unit's type, member type color, and member count. A unit name in that tree is a link only if you can open it. You can when you hold `HR_LOCAL` over the chapter, or you are an admin of that unit or one above it, or you hold a role on that unit type (or any type above it in the parent chain). `ADMIN_LOCAL` reaches the units of its own chapter only, however deeply those units are nested inside it. It does not reach units belonging to a chapter below yours in the chapter tree, even one directly below. To administer a branch's units you need a `_PARENT_LOCAL` permission, which is the permission family that travels down the chapter tree. This closes a case where a parent chapter's `ADMIN_LOCAL` holders reached units sitting directly inside their child chapters. *** ## Who can do what | Action | Requires | | ------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | | See the unit screens | `HR_LOCAL` | | Create a unit | `ADMIN_LOCAL` on the chapter, which is what the **add** button checks. `HR_TENANT` may create any type; local admins are limited to ordinary units | | Edit or delete a unit | `ADMIN_LOCAL` on the unit's chapter | | Toggle a member's unit **Admin** flag | `HR_LOCAL` or `FINANCIAL_LOCAL` on the chapter, or `ADMIN_TENANT` | | Create, edit, or delete unit types | `ROLE_ADMIN_TENANT` | Chapters and role groups can never be created or edited through the unit screens even by tenant admins; they have their own flows. *** ## Common questions As deep as your chain of unit types. Each type points at one parent type, and units of a type can only sit under units of that parent type. The chapters list renders the resulting tree at whatever depth it finds. Unit membership is a role assignment, so a member can hold roles in more than one unit at the same time. Dragging on the segmented board moves them; adding them from a second unit's **Add member** leaves both. Three things must all be true: **Enable Organizational Units** is on, at least one unit type has **Within local center** ticked, and you hold `HR_LOCAL` over the chapter. Archiving sets the unit's status to closed and records an end date. It stays visible under the **archived** filter and keeps its history; it just stops appearing in the active list and in the chapter's unit tree. A unit if the committee is a permanent part of the chapter's structure and you want it in the org chart and in fee scoping. A [private group](/docs/platform/groups/private-groups) if it is a working space people join for a project. *** ## Related * [Local Centers](/docs/platform/groups/local-groups) - the chapters that units live inside * [Groups Overview](/docs/platform/groups) - all group types and when to use each * [Role Groups](/docs/platform/groups/role-groups) - membership defined by a query instead of an assignment * [Member Transfers](/docs/platform/groups/transfers) - what happens to assignments when a member changes chapter * [Permissions](/docs/platform/permissions) - how the local roles are evaluated # Help Desk Source: https://orgo.space/docs/platform/help-desk A support desk inside Orgo: members raise tickets, your support team answers and closes them **Built for** organisations whose admins answer the same member questions over email. **Replaces** a shared inbox or an external ticketing tool. Members open a ticket from inside Orgo, a named support team picks it up, and the whole exchange stays on one page with the member's identity already attached. Tickets use the same board as [project issues](/docs/platform/issues), scoped to the whole organisation instead of to a group. Support ticket board listing tickets with type, assignee, priority and status *** ## Turning it on **Settings → Modules → Helpdesk → Enable Helpdesk Module** (needs `ADMIN_TENANT`). Once it is on, a **Support** entry appears in every member's profile menu (top-right avatar). Nothing else has to be configured for members to start writing in, but a ticket with no support team behind it notifies nobody. Helpdesk module settings with the Members, Issue statuses and Issue types tabs *** ## Configuration The Helpdesk configuration page has three tabs. ### Members Search for a member and add them to the support team. Each row has a **Notifications** switch: only team members with it on are notified when a new ticket arrives. Removing someone from the team also clears them as the default assignee on issue types and unassigns every issue they were assigned to. Removing a support team member unassigns them from all issues, not only from support tickets. Reassign their open work first. ### Issue statuses Your ticket workflow. Add a status, click its name to rename it, pick a colour, drag rows to reorder. A new status starts out named **New status**. Unless your organisation was set up with sample data, this tab starts empty, so define your statuses before inviting members to write in. Closing is separate from status: a closed ticket loses its status and is filed under **Closed** instead. ### Issue types The categories members choose from when raising a ticket, with the same rename, colour and reorder controls. Each type can carry a **Default assignee**, picked from the support team. When a ticket of that type is created (or edited) with nobody assigned, Orgo assigns that person automatically. *** ## How a member raises a ticket Profile menu (top-right avatar) → **Support**. A form opens with a **Request type** dropdown, a subject line and a description. Photos, videos and files can be added to the description. The ticket appears in the list, and the member is subscribed to it automatically so every reply reaches them. A member who is not on the support team sees only the tickets they opened, and cannot change type, status, assignee or priority. Support team members and anyone with `HR_TENANT` see every ticket in the organisation. *** ## Working a ticket Open a ticket to read it, reply in the comment thread, and set the fields in the sidebar. From the list you can change type, status, assignee and priority inline without opening the ticket. | Field | Notes | | ---------------- | --------------------------------------------------------------------------- | | **Request type** | One of the types you configured | | **Assignee** | A support team member. Set automatically if the type has a default assignee | | **Priority** | Highest, High, Medium, Low, Lowest. New tickets start at Medium | | **Status** | One of your configured statuses, or **Close** | Closing offers two options: **Close**, or **Close and comment**, which asks for a closing message before archiving. Closed tickets drop out of the default list and come back with the **Closed** status filter. There are no private replies. Every comment on a ticket is visible to the member who opened it, so keep internal discussion somewhere else. ### Finding tickets The board defaults to **Opened**. Support team members get the full filter row: free-text search over the subject, a **Task type** filter, a status filter (Opened, any individual status, or Closed), assignee avatars including **unassigned**, and a mentions-of-me toggle. Everyone gets column sorting by creation date, priority, type or status, and an **author** button that shows or hides the requester column. The list updates live as colleagues change tickets, without a refresh. *** ## Notifications | Event | Who is notified | | ----------------------------- | --------------------------------------------------------------------------------------------------- | | **New ticket** | Support team members whose **Notifications** switch is on | | **New comment** | Everyone following the ticket, which includes the member who opened it and anyone who has commented | | **Ticket assigned** | The new assignee, unless they assigned it to themselves | | **Ticket closed or reopened** | The member who opened it, or the assignee when the requester is the one doing the closing | Changing a ticket's status, type or priority notifies nobody. Comment notifications follow each member's own comment preference; see [Notifications](/docs/platform/notifications) for the per-member controls. *** ## Common questions It only appears when the Helpdesk module is enabled, and it lives in the profile menu behind the avatar, not in the sidebar. Check the **Notifications** switch on each row of the support team list. A team member with it off still sees tickets but is not alerted. The Issue statuses tab starts empty on a fresh organisation. Create your statuses under **Settings → Modules → Helpdesk → Issue statuses**. Yes, through issue types. Give each type a default assignee and every new ticket of that type lands on that person. Same board, different scope. The help desk is organisation-wide and members write into it; issues belong to a project group and only its members see them. No. Orgo does not compute resolution times or per-agent workload for the help desk. *** ## Related * [Issues](/docs/platform/issues) - the same board scoped to a project group * [Notifications](/docs/platform/notifications) - how members control what reaches them * [Permissions](/docs/platform/permissions) - what `ADMIN_TENANT` and `HR_TENANT` unlock * [Members](/docs/platform/users) - member records behind each ticket * [Contacts](/docs/platform/contacts) - people without an account, who cannot raise tickets # Identity Validation Source: https://orgo.space/docs/platform/identity-validation Collect ID document scans, read Romanian IDs automatically, and have an admin approve or reject each one Identity validation collects a scan of a member's ID document, stores the details read off it, and puts the record in front of an admin who approves or rejects it. It exists mainly for organisations that must know who is behind a payment, which is why most of the flow is wired to online payments and recurring donations. Automatic document reading only understands Romanian documents: the old Romanian ID card, the new Romanian ID card, and the Romanian passport. It keys off the CNP (the 13 digit Romanian personal number) and fails if it cannot find one. For every other country the upload and review flow still works, but an admin types the document details in by hand, and Orgo only requires a first and last name before the record can be approved. *** ## Enabling it **Settings** → **Modules** → **Identity Validation**. Requires `ADMIN_TENANT`. Identity Validation module settings with Enable Identity Validation on and toggles for Require for Users, Require for Online Payments, Automated Identity Validation, Hide Address Fields and Cancel Subscriptions Without Identity Reconfirmation | Setting | What it does | | -------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Enable Identity Validation** | Master switch for the module. Also controls whether the identity emails appear in the email template list. | | **Require for Online Payments** | Ties identity to payments. Payments wait for an identity, renewal reminder emails go out, and the checkout flow asks for a document. | | **Automated Identity Validation** | After a successful read, marks the record **Orgo validated** and lets a pending donation subscription proceed to Stripe checkout without waiting for a human. Applies to subscriptions only, not to one-off payments, and never to the new Romanian ID card, which always needs its back side uploaded first. | | **Hide Address Fields** | Removes the address street and address details fields from the admin review form. | | **Cancel Subscriptions Without Identity Reconfirmation** | Cancels a subscription whose renewal is less than a day away when the identity has not been reconfirmed. | | **Require for Users** | Nothing in the product reads this setting. Turning it on has no effect today. | *** ## What the member does A member reaches the upload page from their own profile, where the identity row shows **Upload identity** if nothing has been submitted. Payment and renewal emails link to the same form with the payment attached. Validate your identity page with an Upload identity scan image button and a Document has information on the backside toggle PNG, GIF and JPEG are accepted. PDFs are rejected. A second upload button appears. The new Romanian ID card needs this, because the address and issue date are on the back. The record is created with status Pending and the reading runs in the background. There is no selfie step, no liveness check, and no field for the member to correct what was read. Everything after the upload is done by an admin. ### What automatic reading extracts From the front: first name, last name, date of birth (derived from the CNP), document series, document number, CNP, expiry date and document type. From the back: issue date, town, county, street and address details. Reading is best effort. If it fails, the record is still created and an admin fills in the details. Two cases do stop the upload with an error: the document has no readable CNP, or the CNP shows the person is under 18. *** ## What the admin does There is no central review queue. You open an identity record from wherever it is referenced: * a member profile or contact record, where the status tag links straight to it; * **Payments** and **Subscribers** on a product; * the adhesion list. Reviewing checks `HR_ASSISTANT_LOCAL` over the member's local center. That is the widest of the HR levels, so it is satisfied by `HR_LOCAL`, `FINANCIAL_LOCAL` and `ADMIN_LOCAL`, by their parent center equivalents, and by the tenant-wide `HR_TENANT`, `FINANCIAL_TENANT` and `ADMIN_TENANT`. If you want identity documents seen by fewer people than that, review who holds local finance and HR permissions before turning the module on. Identity validation review screen showing the uploaded document on the left and the extracted first name, last name, personal number, birth date, document serial and number, issue and expiry dates on the right, with Validate, Reject and Change identity data controls The review screen shows the uploaded images with a rotate control, who uploaded them and when, and the extracted fields. **Change identity data** unlocks the fields so you can correct them. Green and red markers next to the issue and expiry dates flag dates that do not make sense. | Action | Result | | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Validate** | Sets the record to Validated, stamps who approved it and when. Any pending subscription moves on, and a payment held for review is captured. The member is emailed. | | **Reject** | Requires one of three reasons: **Id type not eligible**, **Id expired**, **Id not readble**. The member is emailed with the reason and can upload again. | | **Reopen** | Returns a validated or rejected record to Pending so the member or an admin can replace the document. | For organisations registered in Romania, **Validate** refuses the record unless the first name, last name, document number, CNP, document type, issue date, expiry date and date of birth are all filled in, the document is not expired, the issue date is in the past, and the person is at least 18. Everywhere else only first and last name are required. ### Statuses | Status | Meaning | | ------------------ | ------------------------------------------------------------------------------------------- | | **Pending** | Uploaded, waiting for a human | | **Orgo validated** | Read automatically and accepted provisionally, still open for an admin to confirm or reject | | **Validated** | Approved by an admin | | **Rejected** | Turned down, with one of the three reasons | There is no expired status. An expired document keeps its old status, and expiry is enforced at the moment someone tries to validate it. *** ## Reminders and renewals All of these only run when **Require for Online Payments** is on. * Upload reminders for a payment or subscription with no document go out on an hourly job, up to three times: about two hours after the payment, again after a day, and again after three days. The ladder stops at ten days. * For an active subscription, Orgo emails the member 7, 4 and 2 days before the renewal date asking them to confirm or replace their document. The email offers both "same document" and "upload a different one". * With **Cancel Subscriptions Without Identity Reconfirmation** on, a subscription renewing within a day and still unconfirmed is cancelled. * A member can only replace a subscription document inside the last 7 days before renewal, and not at all while the current one is in the **Orgo validated** state. * Every upload attached to a payment emails everyone holding `FINANCIAL_TENANT`. *** ## Data handling The document number and the CNP are written to the database twice: once as plain text and once encrypted. Document images go to Orgo's S3 media bucket under an unguessable file name. Every create and every change to an identity record writes an audit entry naming the admin and the fields that changed. Orgo has no delete operation for an identity record and no retention timer. The record is only removed when the underlying member or contact row is deleted from the database, which closing an account does not do on its own. If your retention policy requires ID scans to be purged after a period, that has to be arranged outside the product, through Orgo support. Identity data is not part of the member privacy switches. A member cannot hide their identity record, and other members never see it: only the permission levels listed above can open one. *** ## Related * [Privacy Settings](/docs/platform/users/privacy-settings) governs the rest of a profile * [Adhesion](/docs/platform/users/adhesion) can pair a membership application with a document check * [Permissions](/docs/platform/permissions) explains the roles named above * [Donations](/docs/platform/fees/donations) is where the payment-linked flow is most used * [Stripe Integration](/docs/platform/fees/stripe-integration) covers the checkout side of the same flow # Welcome to Orgo Source: https://orgo.space/docs/platform/index The all-in-one platform for managing members, groups, events, payments, and communications in your organization The Orgo member dashboard: welcome banner and discussion feed in the centre, group and committee navigation on the left, and voting, events, tasks and suggested-group widgets on the right Orgo is a membership management platform. Member records, chapters and groups, events, payments and communications sit in one system, so the people you email are the people you already manage, and a fee payment updates the profile it belongs to. **Built for** membership organizations, especially ones with chapters or branches: youth organizations, professional associations, trade unions, alumni networks, faith communities, and advocacy groups. **Replaces** spreadsheets, mailing-list software, and standalone event-registration tools. Works alongside Stripe, which handles the card payments and the payouts. Orgo is modular. Most of what is listed below is a module you switch on in **Settings → Modules**, so your workspace only shows the parts you use. See [Modules](/docs/platform/organisation/modules) for the full list and what each one turns on. *** ## Set up your organization Name, contact details, legal identity, currency and bank details. Invoices, emails and public pages all read from it. [Organization Info →](/docs/platform/organisation/organisation-info) · [Branding →](/docs/platform/organisation/branding) Events, payments, discussions, campaigns, documents. Everything else stays hidden. [Modules →](/docs/platform/organisation/modules) Design the registration form, define your user types, and choose whether new members need approval. [Registration Form →](/docs/platform/users/registration-form) · [User Types & Roles →](/docs/platform/users/user-types) Chapters for geography, units for teams inside them, role groups that fill themselves from member roles. [Groups & Teams →](/docs/platform/groups) Assign permissions by domain and scope so chapter admins see their chapter and nobody shares a login. [Assigning Permissions →](/docs/platform/permissions-assigning) *** ## Members The member record and everything stored on it. * [Users & Profiles](/docs/platform/users): the directory, filters, bulk actions and exports * [Registration Form](/docs/platform/users/registration-form): what new members fill in when they join * [User Types & Roles](/docs/platform/users/user-types): member categories and organizational positions * [Profile Fields](/docs/platform/users/profile-fields): which built-in fields appear, in what order, and which are required * [Custom Fields](/docs/platform/users/custom-fields): your own fields, with per-field visibility and encryption * [Lists & Segments](/docs/platform/users/lists): reusable audiences built from member criteria * [Companies](/docs/platform/users/companies): corporate membership with a seat allowance and one covering fee * [Family Members](/docs/platform/users/family-members): parents, guardians and children in one family record ## Joining and leaving * [Member Invitations](/docs/platform/users/invitations): let members invite the people they know * [Adhesion](/docs/platform/users/adhesion): a formal application with review before full membership * [Referral Program](/docs/platform/users/referral): existing members vouch for a new signup * [Waitlist](/docs/platform/users/waitlist): queue registrations per chapter and admit them when there is room * [User Statuses](/docs/platform/users/statuses): what each status blocks and who can change it * [Resignation](/docs/platform/users/resignation): member-initiated departure with an approval step * [Deletion of Account](/docs/platform/users/deletion-of-account): what is deleted, what is anonymised, what is kept * [Merging Duplicates](/docs/platform/users/merging-duplicates): combine two records and choose which values survive ## Access and privacy * [Permissions](/docs/platform/permissions): the six domains, the three scopes, and how they combine * [Assigning Permissions](/docs/platform/permissions-assigning): who should hold what, and how to audit it * [Privacy Settings](/docs/platform/users/privacy-settings): organization defaults and per-member controls over profile data * [Identity Validation](/docs/platform/identity-validation): collect ID documents and have an admin approve them * [Troubleshooting Member Access](/docs/platform/users/troubleshooting-access): what to check when someone cannot sign in ## Groups and structure * [Groups & Teams](/docs/platform/groups): how the group types differ and when to use each * [Main Group](/docs/platform/groups/main-group): the organization-wide space every member can reach * [Local Centers](/docs/platform/groups/local-groups): chapters and branches with their own admins, events and fees * [Units](/docs/platform/groups/units): named teams inside a chapter, typed and nested * [Role Groups](/docs/platform/groups/role-groups): groups that fill themselves from roles, age, chapter or fee tier * [Private Groups](/docs/platform/groups/private-groups): invite-only spaces for committees and project teams * [Member Transfers](/docs/platform/groups/transfers): move a member between chapters with an approval ## Events * [Events](/docs/platform/events): the events module and what it covers * [Create Event](/docs/platform/events/create-event): every field on the event form and what it controls * [Event Types and Statuses](/docs/platform/events/event-types): categorize events and track their progress * [Event Templates](/docs/platform/events/event-templates): save a setup once and start new events from it * [Registration Forms](/docs/platform/events/registration-forms): what each event asks at registration * [Ticketing](/docs/platform/events/ticketing): price tiers, member pricing, addons and vouchers * [Attendance](/docs/platform/events/attendance): registrations, invitations, walk-ins and the attendee export * [QR Check-in](/docs/platform/events/check-in): scan attendees in at the door * [Speakers and Trainers](/docs/platform/events/speakers-trainers): who presents, per event and per session * [Public Event Page](/docs/platform/events/public-page): the page anyone can open without an account * [Sharing Events](/docs/platform/events/sharing): share links, the public directory, and embeds * [Event Reports](/docs/platform/events/event-report): record what an event set out to do and what it cost * [Annual Event Report](/docs/platform/events/annual-report): a printable booklet over any date range * [Event Analytics](/docs/platform/events/analytics): attendance, capacity, RSVP mix and ticket revenue ## Event App The mobile companion attendees use during an event, with its own sign-in. * [Event App](/docs/platform/events/event-app): enabling it, and how attendees sign in with a one-time code * [Agenda, Feed and Votes](/docs/platform/events/event-app-feed): the live surfaces during the event * [Networking](/docs/platform/events/event-app-networking): attendee profiles, connections and 1:1 meetings ## Payments and fees * [Products](/docs/platform/fees/products): fee products, donation campaigns and payment pages * [Membership Fees](/docs/platform/fees/fees): dues, who has paid, and subscriptions * [VAT & Registration Fees](/docs/platform/fees/vat): tax on fees and a one-time joining fee * [Renewals & Reminders](/docs/platform/fees/renewals): the reminder schedule and what an expired member can still do * [Recording a Payment](/docs/platform/fees/record-payment): log bank transfer, cash and cheque payments * [Invoices](/docs/platform/fees/invoices): creation, numbering, templates and delivery * [Cancelling & Correcting Invoices](/docs/platform/fees/cancelling-invoices): void, refund, and what that changes * [Stripe Integration](/docs/platform/fees/stripe-integration): connect Stripe to take payments online * [Donations](/docs/platform/fees/donations): campaigns with goals, suggested amounts and donor messages * [Donation Pages & Widgets](/docs/platform/fees/donation-pages): the public page, the donor wall and embeds * [Chapter Fees](/docs/platform/local-group-fees/create-local-fees): a chapter fee alongside the organization fee * [Member Fees Table](/docs/platform/local-group-fees/member-fees): record payments member by member, period by period ## Communication * [Discussions](/docs/platform/discussion): forum-style posts and conversations inside groups * [Discussion Namespaces](/docs/platform/discussion/discussion-namespaces): categories members can filter by * [Discussion Moderation](/docs/platform/discussion/moderation): hold posts for review and work the queue * [Newsletter](/docs/platform/newsletter): campaigns with audience targeting, scheduling and delivery reporting * [Newsletter Builder](/docs/platform/newsletter-builder): the drag-and-drop editor, placeholders and reusable designs * [Signup Widgets](/docs/platform/newsletter-widgets): embed a subscribe form on your own website * [Emails](/docs/platform/emails): sender identity, template language and delivery * [System Emails](/docs/platform/emails/system-emails): every automatic email, its trigger, and which can be switched off * [Email Templates](/docs/platform/emails/email-templates): rewrite subject and body, one version for every recipient * [Email Lists](/docs/platform/emails/email-lists): reusable audiences and what feeds them * [Email Logs](/docs/platform/emails/email-log): the record of what was sent, for answering "it never arrived" * [Notifications](/docs/platform/notifications): in-app, push and email notifications, and member toggles ## Governance * [Organizational Chart](/docs/platform/organisational-chart): a live map of who holds which position * [Official Gazette](/docs/platform/official-gazette): a dated, numbered register of decisions and documents * [E-Voting](/docs/platform/e-voting): elections, motions and polls with timed ballots and live results ## Documents and files * [Files & Documents](/docs/platform/files): shared drives with public links you can revoke * [E-Documents](/docs/platform/contracts): templates filled with member data and signed on screen * [Signatures and Records](/docs/platform/e-documents): what a signature captures and how it is stored ## Work and automation * [Projects](/docs/platform/projects): projects with tasks, a board, a timeline and goals * [Tasks](/docs/platform/tasks): assignees, statuses, checklists and dependencies * [Issues](/docs/platform/issues): a shared board for group work, with types, priorities and comments * [Forms](/docs/platform/forms): standalone forms and surveys with a public link and response charts * [Workflows](/docs/platform/workflows): trigger an email or a tag from something that happens in Orgo ## Learning and recognition * [Courses](/docs/platform/courses): lessons, quizzes, enrolment and progress * [Badges](/docs/platform/badges): awards given by hand or from hours, events and courses * [Gamification](/docs/platform/gamification): points, tier badges and the leaderboard ## People beyond your members * [Contacts](/docs/platform/contacts): donors, subscribers, ticket buyers and partners * [Help Desk](/docs/platform/help-desk): members raise tickets, your support team answers them * [Professional Network](/docs/platform/professional-network): members browse each other by industry and connect ## Insights and records * [Insights & Ask Orgo](/docs/platform/insights): ask questions in plain language, and the built-in dashboards * [Activity Log](/docs/platform/logs): a read-only record of who changed what ## Organization settings * [Organization Settings](/docs/platform/organisation): the settings area and what lives where * [Organization Info](/docs/platform/organisation/organisation-info): identity, contact, legal and bank details * [Branding](/docs/platform/organisation/branding): logos, login background and the default theme * [Custom Domain](/docs/platform/custom-domain): serve your community from your own address * [Modules](/docs/platform/organisation/modules): turn features on and off, and configure each one * [Mobile Apps](/docs/platform/mobile-apps): the iOS and Android apps, push setup and branded apps ## Customization * [Customization](/docs/platform/customization): what can be changed about the interface itself * [Languages](/docs/platform/customization/languages): enable interface languages and set a default * [Texts](/docs/platform/customization/labels): replace any wording in the interface with your own * [Menu Organizer](/docs/platform/customization/menu-organizer): reorder, rename, hide and scope the sidebar * [Dashboard Organizer](/docs/platform/customization/dashboard-organizer): build the member dashboard from widgets * [Dashboard Welcome](/docs/platform/customization/dashboard-welcome): the greeting at the top of the dashboard * [Data Import](/docs/platform/customization/import): bulk-create and update records from CSV ## Your Orgo account * [Usage & Billing](/docs/platform/usage-billing): what you consume against your plan limits, your plan, card on file, and Orgo's invoices to you ## Developers * [API Access](/docs/platform/api): API tokens, their scopes and the audit trail * [OAuth Server](/docs/platform/oauth): let members sign in to your own apps with their Orgo account * [Webhooks](/docs/platform/webhooks): push events to your systems in real time * [Orgo MCP](/docs/platform/mcp): connect AI assistants to your Orgo data * [Integrations](/docs/platform/integrations): Stripe, analytics, automation tools and SSO *** ## Quick links for admins Choose which features are active in your workspace. Six permission domains, three scopes, and what each unlocks. Capture organization-specific data on profiles and forms. What to check, in order, when a member cannot sign in. Cannot find what you are looking for? Organization admins can open the support chat in the corner of the app on desktop, or contact support at **[support@orgo.space](mailto:support@orgo.space)**. See [Orgo Support](/docs/platform/orgo-support). # Insights & Ask Orgo Source: https://orgo.space/docs/platform/insights Ask questions about your organisation in plain language, and read the built-in analytics dashboards Orgo answers questions about your data in three ways. **Ask Orgo** is a chat where you type a question in your own words and get a table or chart back. **Analytics** is a set of prebuilt dashboards for membership, geography, activity, and money. [Reports](/docs/platform/reports) is a builder you fill in yourself, for the extract you download again every month. **Built for** admins who need a number now and do not want to file a report request or export three spreadsheets to get it. **Replaces** ad hoc CSV exports, spreadsheet pivot tables, and asking a developer to run SQL. Ask Orgo welcome screen with a greeting, a question box, and suggested question chips such as active members per local center *** ## Where to find it | Surface | Route | Who can open it | | -------------------------------- | -------------------------------------- | ------------------------------------------------------------------------- | | **Ask Orgo** | `/ask-orgo`, sidebar item **Ask Orgo** | `ADMIN_TENANT` only | | **Analytics** | `/stats`, sidebar item **Analytics** | The **Minimum access level** on the analytics module, then a per-tab role | | **Database Queries** | Analytics, **DB Query** tab | `FINANCIAL_TENANT`, or any member a saved query was shared with | | **[Reports](/docs/platform/reports)** | `/reports`, sidebar item **Reports** | `ADMIN_TENANT` only | Analytics needs the analytics module active. The module switch is on **Settings** → **Modules** → **All Modules** (`/tenants/settings/features`), under `analytics`. The **Minimum access level** and the per-tab roles are on **Settings** → **Modules** → **Users & Profiles** → **Security & Permissions**, which collects those dropdowns from every active module onto one page. *** ## Ask Orgo Type a question and press Enter. Questions are capped at 1000 characters, and you can attach one image (PNG, JPEG, GIF, or WebP, up to 5 MB). The welcome screen offers eight starting points, including **Active members count per local center**, **Revenue by product type this year**, **Members who have never made a payment**, and **Top 10 members by discussion posts**. Ask Orgo replies with one of three things: * a **result**: a summary sentence, a table, and a chart when the shape of the data suits one; * a **clarifying question**, when the request is too vague to turn into a query; * a **segment proposal**, when you asked it to build or save a list rather than show one. It shows the criteria and an estimated member count, with **Open in editor** to finish it as an [email list](/docs/platform/emails/email-lists). Follow-ups stay in the same chat and modify the previous query, so "add their email", "only active ones", "break it down by month", and "show as a chart" all work. Name the values you want, in business terms, rather than pointing at rows on screen: the assistant cannot read the result table. A conversation keeps its most recent 20 messages; your chat list shows your own last 50 conversations, newest first, with a search box. You can delete a chat, and rate an answer with the thumbs up and down buttons. Ask Orgo carries a **Beta** badge, and the page warns that it can make mistakes and that database entries are worth checking. *** ## What Ask Orgo can reach Ask Orgo has no free access to the database. It works from a fixed catalogue of 55 record types and, within each, a hand-picked list of fields. | Area | Record types in the catalogue | | -------------- | ------------------------------------------------------------------------------------------------------------------------------------- | | **People** | Members, contacts, families and family members, companies and company membership, roles and role assignments, group memberships, tags | | **Structure** | Local centers, units, towns, counties, countries | | **Membership** | Adhesions (applications), resignation requests, waitlist entries, certifications, identity verification records | | **Money** | Products, product prices and add-ons, payments, fee payments, invoices, subscription profiles | | **Events** | Events, registrations and attendance, attendance add-ons | | **Learning** | Courses, sections, lessons, enrolments, badges, badge awards, badge points | | **Engagement** | Discussions, newsletters and their recipients, email delivery log, forms and submissions, votes and voting sessions, referrals | | **Work** | Projects, tasks, contracts and contract assignments, official gazettes, custom field definitions and values | Some are reachable only through a related record: registrations always through their event, prices through their product. Not in the catalogue: credentials, tokens, and session data. Identity verification records expose only the upload date, validation status, and validation date, because ID and personal numbers are stored encrypted and are not queryable (see [Identity validation](/docs/platform/identity-validation)). Voting records expose only whether a member voted, never which option they chose (see [E-voting](/docs/platform/e-voting)). Values stored in encrypted [custom fields](/docs/platform/users/custom-fields) come back in their stored encrypted form through Ask Orgo, because results are read as raw rows rather than as full records. Read those values on the member profile instead. *** ## How a question becomes an answer Orgo sends Anthropic's Claude API your question, the catalogue above (record and field names with their descriptions), and the structured queries from earlier turns in the same chat. It does not send result rows, which is why a follow-up cannot refer to "those ones" and has to name the values. A structured description: which record type to start from, which related records to join, filters, columns, grouping, and sorting. Unknown record types, fields, and operators are rejected. A query may use at most 6 joins, 20 filters, 20 columns, and 5 aggregate filters, and the page size is clamped to 500 rows. Queries that would inflate totals by combining several one-to-many relations are refused with an explanation rather than returning a wrong number. Before anything else is added, the compiler pins the query to your organisation, and every joined record hangs off that filter. Only SELECT statements are allowed, and a non-SELECT is refused before it reaches the database. The round trip has a 30 second budget. A query that is too heavy comes back asking you to narrow it: a date range, one local center, or a count instead of the detail rows. Ask Orgo runs with full tenant-admin reach: an `ADMIN_TENANT` user can ask about any member in the organisation, including data they would have to click through several profiles to see. Grant `ADMIN_TENANT` accordingly. Local admins do not get Ask Orgo at all. *** ## Working with a result Ask Orgo conversation showing a summary sentence above a result table with column headers and a row count | Action | What it does | | ------------------- | ------------------------------------------------------------------------------------------------------------------ | | **Expand table** | Opens the result in the full-width panel with pagination, 50 rows a page | | Chart toggle | Switches between the table and the chart the model recommended (available for aggregate results with 2 to 30 rows) | | **Export CSV** | Downloads the full result set, 10,000 rows per file, as several files if needed | | **Save** | Stores the query under a name in **Database Queries** | | **Save as segment** | Opens the email list editor prefilled from the question, for results that are lists of people | Column headers come back in the language you asked the question in. *** ## Analytics Analytics Platform tab showing the membership and financial summary cards, contact, chapter and subscriber tiles, and a row of activity sparklines with a period selector Tabs appear only if you hold the role configured for them. Defaults: | Tab | Default role | Shows | | ---------------- | -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Platform** | `ADMIN_TENANT` | Active and inactive members, new members and members lost, contacts, emails sent, newsletter and notification subscription splits, discussions, comments, reactions, events, disk usage, revenue totals, paying and non-paying members | | **Members** | `HR_TENANT` | Members by status, by user type, by gender, average age, signups and exits over time, fees paid by year | | **Geography** | Any signed-in member | Members by town, county or state, country, and local center | | **Leaderboards** | Any signed-in member | Top members by posts, reactions, events, referrals, and badge points, over 7 days, 30 days, or all time | | **Finance** | `FINANCIAL_TENANT` | Total, recurring, and donation revenue, and payment counts over a period. Needs online payments active | | **DB Query** | `FINANCIAL_TENANT` | Saved database queries | The Platform tab is also open to `ADMIN_LOCAL` and `ADMIN_PARENT_LOCAL` when local centers are in use, scoped to their own local center and its descendants, never organisation-wide. Membership and geography tabs accept a local center filter and check the local equivalent of the tab role against it. Period selectors offer 7 days, 30 days, 90 days, 12 months, and a custom range. Daily totals are aggregated overnight, at 04:00 UTC for the previous day, and the page says so. Today's figures are computed live and added on top, and responses are cached for five minutes. **Reset cache** next to the page title clears that cache and reloads, which is the fix when a number looks stale after a bulk import or a large payment run. *** ## Database Queries Anything you save from Ask Orgo lands here as a named query that admins can run again without the chat. Opening one runs it and shows the results, with **Export** for a download. It is stored as the finished statement, with your organisation's filter baked in, so it keeps returning your data only. `FINANCIAL_TENANT` admins see every saved query in the organisation; everyone else sees only the queries shared with them, listed under **Extra access** on the query. Every run is recorded in the activity log with the query name and who ran it. *** ## Troubleshooting Give it a scope: "how many active members joined each month this year" works better than "membership trends". Two settings are checked before the page renders, and failing either one redirects you to the dashboard with no message. The analytics module has to be active, and you have to clear the analytics setting labelled **Minimum access level**, which ships as any signed-in member. Worked example: an organisation raises **Minimum access level** to `HR_TENANT` so that ordinary members stop seeing the numbers. That works, but it also takes away the Geography and Leaderboards tabs, which default to any signed-in member and were the two tabs the organisation actually wanted everyone to have. The minimum is a gate on the whole page, evaluated before any per-tab role. If you get in and the page is empty, the minimum passed and none of the tab roles did. Finance needs the role and online payments switched on. The tab checks both, so an organisation that collects fees by bank transfer only never sees it, whoever is looking. Revenue totals still show on the Platform tab. **DB Query** is the other tab keyed to `FINANCIAL_TENANT`, and it does not check the payments setting, so seeing Database Queries but no Finance is the normal shape of that combination rather than a fault. No, on both counts. The route, the sidebar entry and every endpoint behind the chat require `ADMIN_TENANT`, and the sidebar entry is written into the menu in code rather than drawn from your configurable menu, so it cannot be added to another role's menu or moved. Someone without `ADMIN_TENANT` who follows a link to Ask Orgo is sent to the login screen rather than shown a permission message, which reads like an expired session and is not one. The same is true of any page in Orgo that they lack the role for. There is no read-only or delegated version of the chat; if a colleague needs an answer regularly, save the query and give them access to it, with the caveat in the next answer. Sharing works, the way in does not. Adding somebody under **Extra access** lets them run that query, and once at least one query is shared with them a **queries** entry appears in their sidebar. That entry points at the Database Queries tab of Analytics, and the tab itself renders only for `FINANCIAL_TENANT`, so they land on Analytics without it. Send them the query's own address instead, the one in your browser bar when you have the query open. That page has no role gate of its own and checks the share, so it opens for them and records the run in the activity log under their name. The related setting is the analytics `hasQuery` flag: turning it off removes the sidebar entry for everyone but leaves the tab in place for finance admins. It refuses when the arithmetic would be wrong rather than returning a number that looks fine. Worked example: ask for total fees paid and the number of events attended, per member. Both hang off the member as separate one-to-many branches, so joining them multiplies every fee row by every attendance row: a member with 4 payments and 5 events contributes 20 rows, and the fee total comes back five times too high. Orgo detects the shape, blocks the sum, and tells you to query each metric separately. Ask it as two questions, then line the answers up by member in a spreadsheet, or ask for counts rather than sums when you only need magnitude. The export from the chat asks for pages of 10,000 rows, but every query, including that one, is capped at 500 rows per request. So a result of more than 500 rows exports as a single file holding the first 500, and the completion message still says the export finished. Worked example: a question matching 3,000 members reports 3,000 in the chat and downloads a CSV with 500 rows in it. For a full extract, use **Save** to store the query, then run and export it from **Database Queries**. Saving deliberately drops the paging limit, so the saved statement returns the whole result set. The other option is to narrow the question until it fits, one local center or one month at a time. Saving removes any row limit of 50 or more, on the assumption that it came from the default paging rather than from your question. Limits below 50 are kept, because those look like something you asked for. Worked example: "top 100 members by discussion posts" answers with 100 rows in the chat. Saved and re-run from Database Queries, it returns every member ranked by posts, which for a large organisation is a much heavier query than the one you tested. "Top 25" saves as 25. If you want a fixed cut-off in a saved query, ask for fewer than 50, or add the real filter you mean (a date range, a status) instead of relying on the count. A conversation keeps 20 messages: the first two, which hold the original framing, and the most recent eighteen. Turns in the middle are dropped, so in a long session a follow-up can no longer see a constraint you set twenty turns ago. Restate it, or start a fresh chat for a new line of questioning. Reopening an old chat shows at most 50 rows of the last result, because that is the size of the snapshot stored with the conversation. It is a record of what you saw, not a live result. Re-run the question to page through everything or to pick up data that has changed since. Your chat list shows your own conversations only, and there is no shared inbox of everyone's chats. But conversations are stored per organisation rather than sealed per person, and another organisation admin who has the address of one can open it. In practice this changes little, because the feature is limited to `ADMIN_TENANT` and any admin can ask the same question themselves and get the same data. Treat chats as a shared admin workspace rather than private notes, and delete a conversation when you want its text and its stored rows gone. **Reset cache** requires `ADMIN_TENANT`, while the tabs themselves can be opened by `HR_TENANT`, `FINANCIAL_TENANT` or ordinary members depending on your settings. A finance admin looking at a stale figure after a large payment run has no button to press and has to wait out the five minute cache, or ask an organisation admin. **Reset cache** also only clears the five minute cache. It does not rebuild the overnight aggregation, so a figure that is a whole day out rather than minutes out will not move until the next nightly run, however many times you press it. Check the assumptions in the summary line. Ask Orgo defaults to active members, successful payments, and published events unless you say otherwise. Ask "include inactive members too" to widen it. Result rows are never sent. What leaves Orgo is your question, the catalogue of record and field names, and the structured queries from the same chat; an attached image goes with the question and is not stored on the conversation afterwards. The conversation itself lives in your organisation's own data as the message text, the structured query, and a snapshot of up to 50 rows from the last result, so reopening a chat does not re-run the query. Deleting the conversation removes all of it. *** ## Related * [Members](/docs/platform/users) for the directory the answers are drawn from * [Email lists](/docs/platform/emails/email-lists) for where a segment proposal ends up * [Permissions](/docs/platform/permissions) for what `ADMIN_TENANT` and `FINANCIAL_TENANT` unlock * [Custom fields](/docs/platform/users/custom-fields) for which values are encrypted * [Event analytics](/docs/platform/events/analytics) for per-event numbers, separate from these dashboards # Integrations Source: https://orgo.space/docs/platform/integrations Connect Orgo with Stripe, HubSpot, n8n, analytics tools and single sign-on providers Orgo connects to the tools your organization already uses: payments through Stripe, sign-in through Google or Microsoft, contact sync to HubSpot, automation through n8n, and the usual analytics tags. **Built for** administrators wiring Orgo into an existing stack. **Replaces** copy-paste between systems and bespoke glue scripts. Third-party Integrations page with the available integrations list on the left and the HubSpot configuration panel on the right *** ## Where it lives **Settings → Developers → Third-party Integrations**. Requires **ADMIN\_TENANT**. The list on the left shows every available integration with a switch indicating whether it is configured. The switch itself is a status light: you configure each integration in the panel on the right and press **Save Settings**. | Integration | What it does | | ---------------------- | ------------------------------------------------------- | | **SSO Authentication** | Members sign in with an account they already have | | **Stripe** | Card payments for fees, tickets, donations and products | | **n8n** | Visual automation between Orgo and other services | | **HubSpot** | Push members and contacts into HubSpot as CRM contacts | | **Facebook Pixel** | Page-view tracking for advertising | | **Google Analytics** | Usage analytics | | **Google Tag Manager** | One container for all your tags | Selecting **Stripe** takes you to the payment settings; see [Stripe Integration](/docs/platform/fees/stripe-integration). *** ## Single sign-on Members can sign in with an account they already have instead of an Orgo password. **Google**, **Microsoft** and **Apple** appear as buttons on the login screen, in a browser and inside the mobile apps, including [branded apps](/docs/platform/mobile-apps). You supply nothing: Orgo registers the applications with each provider centrally, so there is no client ID or secret to paste, and no per-domain restriction to configure. Where the switches on this page apply depends on the address members use: | Members sign in at | What the switches do | | ------------------------------------------------- | --------------------------------------------------------------------------------------------- | | Your `.orgo.space` address | Nothing. Google, Microsoft and Apple are always offered | | Your own [custom domain](/docs/platform/custom-domain) | **Enable SSO Login** turns the section on or off, and only the providers you switch on appear | The **LinkedIn** switch exists in this panel but there is no LinkedIn button on the login screen today, so turning it on changes nothing. Signing in with a provider matches on email address and signs the member into their existing Orgo account. It does not create accounts on its own: registration still goes through your [registration form](/docs/platform/users/registration-form). *** ## HubSpot Sync members and contacts into HubSpot as CRM contacts. Account Management → Integrations → Private Apps → Create new App, named Orgo. `crm.objects.contacts.read`, `crm.objects.contacts.write`, `crm.schemas.contacts.read`, `crm.schemas.contacts.write`. Copy it from the app's Auth tab into **HubSpot API Token** and press **Save Settings**. Once the integration is active, every member and every contact created or updated in Orgo is pushed to HubSpot. Orgo matches on email address: an existing HubSpot contact is updated, otherwise a new one is created. | Sent to HubSpot | Notes | | -------------------------------------------- | ------------------------------------------------ | | Email, first name, last name, phone, company | The matching key is email | | Address, city, country | Members also send state, postal code and website | | Lifecycle stage and lead status | Set to `lead` / `NEW` | The sync runs in the background, one direction only: changes made in HubSpot are never written back to Orgo, and deletions are not propagated. Saving a token is necessary but not always sufficient. If members and contacts are not appearing in HubSpot, ask support to confirm the HubSpot integration is switched on for your organization. *** ## n8n n8n is a visual automation tool with an official Orgo node, so you can connect Orgo to hundreds of other services without writing code. Toggle **Enable n8n**. It saves immediately. **Settings → Developers → API Tokens**. Scope it to what the automation needs, see [API Access](/docs/platform/api). Your organization's host plus the token. Then build the workflow. Use n8n cloud or self-host it. Orgo's own [webhooks](/docs/platform/webhooks) make good triggers for workflows that must react immediately. *** ## Analytics and tracking Each of these takes a single ID and applies to your member-facing pages. | Integration | Field | Where to find it | | ---------------------- | ---------------------------- | ----------------------------------- | | **Google Analytics** | Measurement ID (`G-XXXXXXX`) | Google Analytics admin, data stream | | **Google Tag Manager** | Container ID (`GTM-XXXXXXX`) | Google Tag Manager workspace | | **Facebook Pixel** | Pixel ID | Facebook Events Manager | Google Analytics and Tag Manager receive page views plus a small number of commerce events raised by Orgo itself, including checkout start and completed purchases on payment and donation pages. Facebook Pixel receives page views only. If you already run several tags, put the Tag Manager container ID in and manage the rest from there rather than filling in each field here. *** ## Common questions If Google Analytics is the only thing you run, the Measurement ID is enough. If you run several tags, use Tag Manager so you never have to come back to this page. Yes. Enable as many as you want; members pick one on the login screen. Two routes. [Webhooks](/docs/platform/webhooks) push events to any system that accepts an HTTPS POST, and the [API](/docs/platform/api) covers everything else. For sign-in from your own application, see [OAuth Server](/docs/platform/oauth). No. The sync fires when a member or contact is created or updated, so existing records appear as they change. To backfill, export and import on the HubSpot side. *** ## Related * [Stripe Integration](/docs/platform/fees/stripe-integration) - payment setup in detail * [API Access](/docs/platform/api) - tokens and scopes * [Webhooks](/docs/platform/webhooks) - real-time event delivery * [OAuth Server](/docs/platform/oauth) - Orgo as an identity provider * [Orgo MCP](/docs/platform/mcp) - connect AI assistants to your Orgo data # Issues Source: https://orgo.space/docs/platform/issues A shared task board for project groups: types, priorities, statuses, assignees and comments **Built for** working groups that need to track who is doing what. **Replaces** action-item lists in meeting minutes and message threads. An issue is a piece of work with an owner, a type, a priority and a status, discussed in a comment thread. Issues live on a **project group**: a group flagged as a project when it is created. The [help desk](/docs/platform/help-desk) uses the same board, scoped to the whole organisation instead of one group. Issue board for a project group with type, assignee, priority and status columns *** ## Issues, tasks or the help desk | You want to | Use | | ------------------------------------------------ | ---------------------------------------- | | Track work inside one working group | Issues | | Run a project with a board, gantt view and goals | [Projects and tasks](/docs/platform/projects) | | Answer member questions and requests | [Help Desk](/docs/platform/help-desk) | | Discuss something without tracking it | [Discussions](/docs/platform/discussion) | *** ## Creating a project group Issues are not available on ordinary groups. You need a project group, and the **Project Management** module has to be on: **Settings → Modules → Projects → Enable Project Management** (needs `ADMIN_TENANT`). On the Issues page, a member who belongs to no project yet is offered **Projects → New**, which creates a group in project mode. Who may create one follows the tenant's group-creation setting (**Settings → Modules → Groups & Teams**). Once the group exists, open it and pick the **Issues** tab. A new project group starts with: | | Seeded values | | ------------------ | ---------------------------------- | | **Statuses** | To do, In progress, Waiting list | | **Types** | Research, Maintenance, Development | | **Priority field** | On | | **Type field** | On | | **Due date field** | Off | Both lists are editable afterwards. Open the group, choose **Settings** from its menu (`/group/edit/{id}`, group owner or group admin), and the **Issue statuses** and **Issue types** tabs sit under the group form. **Add** creates an entry, clicking a name opens it for renaming, the colour button beside it sets its colour, dragging a row reorders it on desktop, and the bin deletes it. The pencil beside **Type** and **Status** in the issue form is a shortcut to the same screen. Issue statuses tab on a project group's Settings screen, with the statuses listed as coloured tags and one row open for editing, showing its name field, colour picker, Save and Cancel buttons and the delete bin, beside the Issue types tab and the Add button The three field switches are the part that is still fixed: **Priority field**, **Type field** and **Due date field** are set when the group is created and have no editing screen. With the type field off, the **Issue types** tab is hidden along with the field itself. *** ## Who sees what Issues are visible to members of the group they belong to, and to nobody else. That check runs on the server, not just in the interface, so an issue in a private working group stays inside it. Anyone who can open a project board can add an issue to it and edit the issues on it. *** ## Adding an issue Click **Add issue** on the board. The form asks for: | Field | Notes | | --------------- | ----------------------------------------------------------------- | | **Title** | Required | | **Description** | Rich text, with photos, videos and file attachments | | **Type** | Defaults to the first type in the list | | **Assignee** | Optional. Filled automatically if the type has a default assignee | | **Priority** | Highest, High, Medium, Low, Lowest. New issues start at Medium | | **Status** | Defaults to the first status, or **Close** to archive immediately | | **Due date** | Only when the due-date field is on for that group | Mentioning someone in the description notifies them. The author follows the issue automatically and is notified of every comment. *** ## The board The board is a sortable list. Columns: due date where enabled, type, title, assignee, priority and status, plus a created-date-and-author column that the **author** button in the toolbar shows or hides. Type, status, assignee and priority can all be changed inline from the list. Filters sit above the list: * free-text search over the title * **Task type** * status: **Opened** (the default), any individual status, or **Closed** * assignee avatars, including **unassigned** * your own avatar, which filters to issues that mention you * an **Author** search, to see one person's issues Sorting by priority turns on drag-and-drop, so you can reorder issues by hand within the priority ranking. The board updates live as colleagues change things. *** ## Closing an issue Set the status dropdown to **Close**. Two variants: * **Close** archives the issue immediately and clears its status. * **Close and comment** opens a box for a closing note, then archives it. Closed issues disappear from the default view and come back through the **Closed** status filter. Reopening means giving the issue a status again. *** ## Comments and attachments Every issue has a thread. Comments support rich text, images, video and file attachments, and mentions. Following an issue happens automatically when you create or comment on one. ## Who gets notified | Event | Who is notified | | ------------------------------------------- | ---------------------------------------------------------------------------- | | **New comment** | Everyone following the issue | | **Issue assigned** | The new assignee, unless they assigned it to themselves | | **Issue closed or reopened** | The person who raised it, or the assignee when the author is the one closing | | **Mention in the description or a comment** | The person mentioned | Changing status, type, priority or due date notifies nobody, and there is no reminder when a due date approaches. If you need due-date reminders, use [tasks](/docs/platform/tasks). *** ## Common questions The tab only appears on groups created in project mode, and only for members of the group. An ordinary group cannot be converted afterwards. Rename, recolour, reorder or delete them on the group's **Settings** screen, under **Issue statuses**, and add your own with **Add**. Statuses are per group, so changing them here affects only this project. There is no kanban view. The board is a sortable list, with drag-and-drop reordering when you sort by priority. No. An issue belongs to exactly one project group. Work that spans teams needs a shared group, or a project. The due-date field is off for project groups by default and there is no screen to switch it on. Projects and tasks carry due dates as standard. *** ## Related * [Help Desk](/docs/platform/help-desk) - the same board for member support requests * [Projects](/docs/platform/projects) - the fuller project workspace with editable workflows * [Tasks](/docs/platform/tasks) - task assignment, due dates and reminder digests * [Groups](/docs/platform/groups) - where project groups are created and managed * [Notifications](/docs/platform/notifications) - controlling what reaches you # Chapter Fees Source: https://orgo.space/docs/platform/local-group-fees/create-local-fees Let each chapter charge its own membership fee alongside the organisation fee A chapter (local center) can charge its own membership fee on top of the organisation fee. It picks its own fee product and its own default price, and when it has its own Stripe account the money settles into that account. A member then carries two independent fee validity dates: one for the organisation, one for the chapter. **Built for** federations where chapters keep their own budget: scout districts, regional branches, county associations. **Replaces** the parallel spreadsheet each branch treasurer keeps. *** ## Turning it on **Settings** → **Payments & Fees** → **Membership fees**, section **Local Center Fees**. Requires `ADMIN_TENANT`. | Setting | What it does | | ------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | | **Local Center Fees Enabled** | Master switch. Everything on this page is hidden until it is on. | | **Local Center Members Table** | Adds the per-chapter [Member fees table](/docs/platform/local-group-fees/member-fees) used to record offline payments. | | **Minimum Members per Local Center** | Flags chapters whose count of paid fees falls below this number, on the chapter fee statistics screen (`/fee/stats`, `FINANCIAL_TENANT`). | | **Minimum Active Members Percentage** | Same flag, comparing paid fees against this share of the chapter's active members. | *** ## Setting up one chapter Chapter fee settings showing the Product and Default price selectors with Add price and Save **Finance** → **Fees settings** in the sidebar, or open the chapter and pick **Fees settings** in its settings sidebar. The screen itself requires `ADMIN_LOCAL` on that chapter (`ADMIN_TENANT` qualifies everywhere). With no chapter fee product yet you get **Start local fees by adding your first product** and an **Add product** button. A fee product created by anyone who is not `FINANCIAL_TENANT` is stamped with their own chapter, and if that chapter has no fee product yet it is set as the chapter's fee product automatically. **Add price** opens the product's **Prices** tab. Each price is one membership level (for example Youth, Adult, Family). Archived prices are not offered. **Product** lists only products belonging to this chapter. **Default price** lists that product's non-archived prices with their amount and the organisation currency symbol. Without one, chapter fee charges fall back to the organisation's Stripe account. See [Stripe Integration](/docs/platform/fees/stripe-integration). The chapter settings sidebar shows **Fees settings** to `FINANCIAL_LOCAL`, but the screen behind it needs `ADMIN_LOCAL`. A finance-only chapter admin will see the entry and land on an empty page. *** ## What the default price does The default price is not just a suggestion. Whenever the [Member fees table](/docs/platform/local-group-fees/member-fees) or a member's fee view loads, every fee-eligible member of the chapter who has no chapter fee tier yet is given the chapter's **Default price**. With **Enable Age Restrictions on Prices** on, the age-appropriate variant of that price is chosen instead. Change an individual member's tier from the Member fees table, or from the member's **Fee** tab (needs `FINANCIAL_LOCAL` on their chapter, or the member changing their own). *** ## How a member pays both fees A member's profile **Fee** tab shows two cards side by side, **Organisation fee** and **Local fee**. The local card only appears when chapter fees are on, the member's chapter has a fee product, and the member has a chapter fee tier. Member profile Fee tab with a summary card splitting the total fee into an organisation line and a chapter line, above an Organisation fee card and a Local fee card side by side, each showing its tier, validity and payment history The two are charged separately, never in one checkout: * The chapter fee charge is routed to the chapter's own Stripe account when it has one, otherwise to the organisation account. * The amount is charged in the chapter's currency when the chapter has its own currency override, otherwise in the organisation currency. * The one-time registration fee is organisation-level only. It is never added to a chapter fee. * The local fee card offers one-off payment only. Recurring subscriptions are not available for chapter fees. * Members can start a chapter fee payment for themselves only. Admins record payments on a member's behalf instead of paying for them. Online payment of the chapter fee also needs the **Online Payments** module active with **Membership Fees** on, plus either **All Members Fee Eligible** or, on the chapter's own edit form, **Enable members in this chapter to pay membership fees by online payments**. *** ## Fee validity Paying the chapter fee stamps a billing period and sets the member's **chapter fee validity date** to the end of that period. It is stored and evaluated separately from the organisation fee validity date, so a member can be current on one and expired on the other. A lifetime price with no amount sets the date 100 years out. *** ## Recording offline payments Cash and bank transfers collected by the chapter are recorded in the [Member fees table](/docs/platform/local-group-fees/member-fees), which stages the amounts as a draft and then writes them as one pending fee payment batch for an organisation admin to approve. Settling a single member instead, with **Mark as paid** on their profile's **Fee** tab, needs no approval: that batch is written as already approved and the validity date moves at once. See [Recording a payment](/docs/platform/fees/record-payment). *** ## Who can do what | Action | Permission | | --------------------------------------------------- | -------------------------------------------------------------------------------- | | Turn chapter fees on for the organisation | `ADMIN_TENANT` | | Choose the chapter's fee product and default price | `ADMIN_LOCAL` on the chapter | | Create or edit the chapter's fee product and prices | `FINANCIAL_LOCAL` on the chapter | | Change a member's chapter fee tier | `FINANCIAL_LOCAL` on their chapter (or the member, for themselves) | | Mark a chapter fee period as paid | `FINANCIAL_LOCAL` on the member's chapter, and **Allow Mark as Paid** must be on | | Record a chapter fee payment batch | `FINANCIAL_LOCAL` on the chapter, or an active unit-admin role in it | | Approve a pending batch | `ADMIN_TENANT` | | Cancel a pending batch, which deletes it | `ADMIN_LOCAL`, and the server keeps it to that admin's own chapter | *** ## Troubleshooting It lists only products that belong to this chapter. A product created by a `FINANCIAL_TENANT` user is an organisation product and will not appear. Create the product from the chapter's Fees settings so it is stamped with the chapter. Check that the chapter has both a **Product** and a **Default price** saved, that the member is fee eligible, and that their member type is not flagged as not eligible for fees. Members with no chapter fee tier get one assigned automatically the next time the fee views load. That chapter has not connected its own Stripe account. Charges fall back to the organisation account by design until it does. The IBAN fields on a chapter record are reference details. The native-currency one is shown on the chapter's info page under **Legal details**, but bank-transfer invoices and PDF payment proofs use the organisation IBAN. *** ## Related * [Member fees table](/docs/platform/local-group-fees/member-fees): recording chapter payments member by member * [Membership Fees](/docs/platform/fees/fees): the organisation-level fee and its settings * [Products](/docs/platform/fees/products): fee products, prices and tiers * [Stripe Integration](/docs/platform/fees/stripe-integration): chapter Stripe accounts and currency rules * [Chapters](/docs/platform/groups/local-groups): chapter records, settings sidebar and waitlist # Member Fees Table Source: https://orgo.space/docs/platform/local-group-fees/member-fees Record chapter and organisation fee payments member by member, period by period The Member fees table is the chapter treasurer's screen: one row per member, one column per fee period, and a checkbox on every period the member still owes. Tick what was collected, and Orgo writes it as a single payment batch. Member fees table for a chapter with member, unit and fee tier columns and one column per fee period, several periods ticked and the running total and Pay button above the table *** ## Getting there The table needs **Local Center Members Table** on under **Settings** → **Payments & Fees** → **Membership fees**, plus either `FINANCIAL_LOCAL` on the chapter or an active unit-admin role inside it. | From | How | | ------------------------------ | ---------------------------------------------------------- | | The sidebar | **Finance** → **Local members fees**, for your own chapter | | A chapter page | **Fees** in the chapter header | | A unit page | **Fees** in the unit header, pre-filtered to that unit | | The chapter list | The fees action on a chapter row | | **Finance** → **Fee payments** | The chapter name on any batch row | Chapter admins always land on their own chapter. An organisation admin can open any chapter, and everything they then stage or record is anchored to the chapter they are viewing, not to their own. *** ## Reading the table | Column | What it shows | | -------------- | --------------------------------------------------------- | | (icon) | The member's type | | **Member** | Last and first name, linking to the profile | | **Unit** | The member's sub-unit, with its colour dot | | **Fee** | The tier the member is charged at, editable unless locked | | One per period | The period start and end, with what is paid or owed | Each period cell shows a green tick with the amount when the period is paid, an orange tick while a payment is still processing, and a checkbox with the outstanding amount when it is not. Partly covered periods show one checkbox per missing slice, so proration is preserved. Above the table: the **Organisation** / **Local** toggle (only when chapter fees are on and the chapter has a fee product), the fee year, a member status filter (**Active**, **Inactive**, **Suspended**, plus any of Awaiting referral, Excluded, Helping hands or Contributor your organisation uses), and a unit filter with **All units** and **No unit**. A member with active roles in more than one sub-unit is still listed under a single unit. Orgo picks the unit where they hold plain membership ahead of any unit where they are a unit administrator or hold a role that carries permissions, so a leadership position elsewhere does not pull someone out of the unit they are registered in. A member whose only role is a leadership one is listed under that unit. Where that still leaves a tie, the first unit by name wins. The **Unit** column, the unit filter and the unit recorded against payments you take here all follow the same choice. The table only shows payments made through this chapter. A member's full fee history, including payments recorded elsewhere, lives on their profile's **Fees** tab. *** ## Changing a member's tier The **Fee** column is a dropdown of the fee product's prices. Picking a new one applies from the start of the fee cycle you are currently viewing, so setting next year's tier does not rewrite this year's. The dropdown is replaced by a padlock and the tier name once a successful payment covers the viewed cycle or a later one. Trying anyway is refused with *The fee is already paid and can no longer be changed*. *** ## Recording a payment The running **Total** above the table adds up everything ticked, in the chapter's currency. **Save** stores what you ticked as a draft, so the selection survives leaving the page. The draft is shared across the chapter's fee admins, and each admin sees only the members they are allowed to manage. **Pay \[total]** writes one fee payment batch covering every ticked period and takes you to **Finance** → **Fee payments**. The batch is stamped with the bank transfer (`iban`) method and starts as **pending**. On **Fee payments**, **Approve** marks the batch and every payment inside it successful, then recalculates each member's fee validity date, chapter validity for chapter fee products and organisation validity otherwise. **Approve** is offered to `ADMIN_TENANT` only. A pending batch can instead be removed with **Cancel**, which needs `ADMIN_LOCAL` and deletes the batch and its payment rows. Paid rows clear from the draft automatically, so reloading the table after a successful **Pay** does not show them ticked again. *** ## Unit admins A member with an active admin role on a unit reaches this table without chapter-level finance rights. They see and manage only members holding an active role in their admin units or any unit below them. Staging and recording are filtered the same way on the server, so one unit's treasurer can neither see nor overwrite another's rows. Their **Fee payments** list opens on the **Local** tab, which is where the payments they record appear. *** ## Troubleshooting Either **Local Center Fees Enabled** is off, or this chapter has no fee product selected in its [Fees settings](/docs/platform/local-group-fees/create-local-fees). Their member type is not eligible for fees, or the period falls before they joined. Periods before the join date are left blank. Nothing is ticked, or the total is zero. The **Pay** button only appears once the total is above zero and the table has rows. The batch is pending. Fee validity dates only move when an organisation admin approves it. *** ## Related * [Chapter Fees](/docs/platform/local-group-fees/create-local-fees): setting up a chapter's own fee * [Recording a payment](/docs/platform/fees/record-payment): the other ways to log an offline payment * [Membership Fees](/docs/platform/fees/fees): fee cycles, validity dates and reminders * [Units](/docs/platform/groups/units): unit admins and the unit hierarchy * [Permissions](/docs/platform/permissions): what `FINANCIAL_LOCAL` and `ADMIN_LOCAL` unlock # Activity Log Source: https://orgo.space/docs/platform/logs A read-only record of who changed what in your organization, with the before and after values The activity log answers "who changed this, and when". Every entry names the person who acted, the record they acted on, and, for edits, exactly which fields changed and what they changed from. **Built for** answering member disputes, audits, and the moment someone asks why a profile no longer says what it said last week. **Replaces** guessing from database backups. **Settings → Developers → Logs** Requires **ADMIN\_TENANT**. There is no local-admin view of the tenant-wide log, and the same permission gates the log tabs that appear on individual records. Activity log table with filter pills for action, entity, author, user and date above rows showing date, action, author and entity *** ## Reading an entry | Column | What it holds | | ---------- | ------------------------------------------------------------------- | | **ID** | The entry's own identifier | | **Date** | When it happened, to the minute | | **Action** | What kind of change it was | | **Author** | The person who made the change, linked to their profile | | **User** | The member the change was about, when the entry concerns one person | | **Entity** | The record type and its name, or its id when there is no name | | **IP** | The address the request came from | Click the arrow at the start of a row to expand the details. For an edit, the details show only the fields that actually changed, each with its old and new value. Fields whose value did not really change are dropped before storage, as is the automatic "last updated" timestamp, so the detail block is the real diff rather than a dump of the whole record. For a deletion, the details hold a snapshot of the key fields as they were just before the record went away. Entries are 15 to a page, newest first. *** ## Filtering The pills above the table combine, and the result is written into the page URL, so a filtered view can be bookmarked or pasted to a colleague. | Filter | Notes | | ---------- | ----------------------------------------------------------------------------------------- | | **Action** | The kinds of change listed below | | **Entity** | Record type. See the caveat below: it matches deletions and query exports, not every edit | | **Author** | Search by name or email from two characters up | | **User** | The member the entry is about, same search | | **Date** | A "date after" and a "date before" picker, either or both | **Refresh** re-runs the current filter. *** ## What gets recorded | Action | Written when | | -------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **create** | An adhesion, an identity submission, a unit or group, or an event attendance is created, or a tag is added to a member or contact profile | | **update** | A member profile is edited (the diff of changed fields), an adhesion or identity changes status, a unit or group is edited, an attendance changes, a contract is updated, a member's email is changed or their password is reset, an administrator unsubscribes a contact from the newsletter | | **remove** | A record is deleted through the application: newsletters and newsletter templates, email templates, events, courses and lessons, products, forms, users, adhesions, identities, contracts, contacts, roles, role groups, groups, local centers and units, plus discussions, posts and comments. Also written when a tag is removed from a member or contact profile, and when a [profile note](/docs/platform/users/profile-activity) is deleted | | **moderate** / **unmoderate** | A discussion post or comment is hidden or restored | | **csv** | Members, role-group members, contacts, or a saved query are exported | | **upload\_identity** | A member uploads an identity document | | **confirm\_identity** | An identity is confirmed before a subscription charge | | **custom\_field\_encryption\_enabled** / **custom\_field\_encryption\_disabled** | Encryption is switched on or off for a custom field | | **decrypt\_custom\_field** / **decrypt\_custom\_field\_failed** | An encrypted custom field value is read, or a read fails | Record merges are logged too, but they are not offered in the Action filter. Review them on the merge history page instead. ### What is not recorded here Deletions are logged only when they come through the application. A cascade (deleting a group that takes its memberships with it), a bulk operation run by Orgo support, and background jobs do not each write a row. This is deliberate: one cascade should not produce thousands of entries. * **Logins** are not in this log. * **Email delivery** is not in this log. Use the [email log](/docs/platform/emails/email-log). * **Webhook deliveries** have their own log on each webhook subscription. * **Imports** report per-row results on the import itself, not here. * **Changes made without a signed-in account** produce no entry. A visitor registering for a public event, for example, creates the attendance but no log row, because there is nobody to attribute it to. ### The Entity filter is narrower than the table The **Entity** column and filter are populated for deletions and for saved-query exports. Most edit entries identify their subject through the **User** column instead and carry no entity type, so filtering by, say, `User` will not return profile edits. To review edits to one member, filter by **User**, or open that member's profile and use its own log tab. The filter dropdown is also a fixed list, and it is shorter than the set of entity types the table displays. Tag changes (`ProfileTag`) and note deletions (`UserNote`, `ContactNote`) write rows that show their type in the **Entity** column but have no option in the filter, so they cannot be narrowed down that way. Filter by **User** and **Action** instead, or read them in order on that person's [Activity tab](/docs/platform/users/profile-activity). *** ## The IP and impersonation columns The IP address is captured from the browser request that made the change, so entries written from an asynchronous handler rather than directly from the request carry no IP in that column. Encrypted custom field reads are the notable case: they are recorded asynchronously, and their IP is stored inside the details block instead. Deletion entries also record an **impersonator** when the deletion happened while an administrator was viewing the platform as another user. That tells you the account the action was attributed to and the account that actually performed it. *** ## The same log, scoped to one record The tenant-wide page is not the only way in. The same entries appear filtered on: * a **member profile**, on its logs tab; * an **event attendance**, on the attendees screen; * an **adhesion**, on its log view. All three read the same store and need the same ADMIN\_TENANT permission, so a local admin will not see them. The expanded details panel of an activity log row, showing the JSON diff with the old and new value for each changed field *** ## Retention and export Entries are kept for as long as your organization exists. Nothing prunes them on a schedule, and deleting your organization removes them along with everything else. The log is strictly read-only: entries cannot be edited or deleted from the interface, and there is no endpoint that would let anyone do so. There is no export button on this page; if you need the entries outside Orgo, read them through the API. *** ## Troubleshooting Three common reasons. It was a cascade or a background job, which are not logged per record. It was a kind of change that has no log action at all (see the table above; not every screen writes an entry). Or the Entity filter is hiding it, because edits generally carry no entity type: clear the filters and narrow by **User** and date instead. The address is taken from the browser request that made the change. Entries written from an asynchronous handler rather than directly from the request, such as reading an encrypted custom field, carry no IP. The author is still recorded. Filter Action = **remove** and Entity = **User**, then expand the row. The snapshot holds the email, first and last name and status the account had at deletion, and the Author column names who did it. It is not visible to them. The log requires ADMIN\_TENANT, and that includes the log tabs on individual profiles. Filter Action = **decrypt\_custom\_field**. Failed attempts are recorded separately as **decrypt\_custom\_field\_failed**, and switching encryption on or off for a field is recorded as its own action. *** ## Related * [Permissions](/docs/platform/permissions) * [Email log](/docs/platform/emails/email-log) * [Merging duplicates](/docs/platform/users/merging-duplicates) * [Custom fields](/docs/platform/users/custom-fields) * [Workflows](/docs/platform/workflows) # Orgo MCP Source: https://orgo.space/docs/platform/mcp Connect AI assistants like Claude and ChatGPT to your Orgo data Orgo MCP connects AI assistants to your organization's data using the Model Context Protocol (MCP), an open standard that lets tools like Claude securely talk to other apps. Once connected, you ask questions in plain language and the assistant looks up the answers in Orgo for you. AI assistant chat using Orgo MCP to check chapter renewal rates and send reminders to chapter leaders *** ## What you can do Most people use Orgo MCP for data analysis and light administrative actions: * **Ask questions about your data**: "How many members joined in June?", "Which events this year had the most attendees?", "Show unpaid membership fees by chapter." * **Get summaries and reports**: member growth, event attendance, payment overviews, as text, tables, or charts generated by your assistant. * **Take light actions**: draft a newsletter, create an event, add a contact note. Review what the assistant proposes before it is saved. Under the hood, the assistant has access to the full Orgo REST API (700+ operations across members, events, payments, newsletters, votes, and more), so anything the API can do, your assistant can do too. The assistant acts with your permissions: it can only see and change what your own account can. Still, always review the actions it proposes before confirming them. *** ## Hosted server (recommended) The hosted server is the easiest way to connect: nothing to install, always up to date: ``` https://mcp.orgo.space/mcp ``` Add this URL to your AI tool and sign in with the user on your Orgo workspace when prompted. Your organization is detected automatically from the account you log in with. 1. Go to **Settings** → **Connectors** → **Add custom connector** (on claude.ai or in the Claude Desktop app) 2. Enter the URL `https://mcp.orgo.space/mcp` and click **Add** 3. Sign in with your Orgo workspace account when prompted ```bash theme={null} claude mcp add --transport http orgo https://mcp.orgo.space/mcp ``` Then run `/mcp` inside Claude Code to complete the sign-in in your browser. Add to `~/.cursor/mcp.json` (or `.cursor/mcp.json` in your project): ```json theme={null} { "mcpServers": { "orgo": { "url": "https://mcp.orgo.space/mcp" } } } ``` Any MCP client that supports remote HTTP servers with OAuth works: ```json theme={null} { "mcpServers": { "orgo": { "url": "https://mcp.orgo.space/mcp" } } } ``` Sign-in uses standard OAuth with automatic client registration, so no API keys are required. *** ## Local server (developers) For server-to-server automation, custom deployments, or local development, run the MCP server yourself from npm: ```bash theme={null} npx -y orgo-mcp ``` Example configuration using an API token (see [API Access](/docs/platform/api) to create one): ```json theme={null} { "mcpServers": { "orgo": { "command": "npx", "args": ["-y", "orgo-mcp"], "env": { "ORGO_TENANT_HOST": "your-org.orgo.space", "ORGO_API_TOKEN": "your-api-token" } } } } ``` The local server also supports JWT and OAuth token authentication and stdio, HTTP, and SSE transports. Full setup, configuration, and tool reference are in the repository README: [github.com/Orgo-space/orgo-mcp](https://github.com/Orgo-space/orgo-mcp). An API token carries the access level of the administrator who created it, so keep it out of shared configurations. If the assistant only needs part of your data, create a restricted token: the scope you grant is exactly what the assistant can reach. See [API Access](/docs/platform/api). *** ## Technical capabilities | Capability | Details | | ----------------------- | ------------------------------------------------------------------------- | | API tools | Discover and call any Orgo REST API operation (458 paths, 743 operations) | | Auth helpers | `whoami`, login with OTP verification, token refresh | | Documentation resources | 21 resources under the `orgo://` scheme: concepts, recipes, webhooks | | Transports | stdio (local), HTTP with OAuth (hosted), SSE streaming | *** ## Related * [API Access](/docs/platform/api) - REST API and API tokens * [OAuth Server](/docs/platform/oauth) - the authentication behind the hosted server * [Webhooks](/docs/platform/webhooks) - push events out instead of asking for them * [Integrations](/docs/platform/integrations) - HubSpot, n8n, analytics and SSO * [API Reference](/docs/api-reference/concepts/authentication) - the operations your assistant can call # Mobile Apps Source: https://orgo.space/docs/platform/mobile-apps The Orgo iOS and Android apps, push notification setup, deep links, and branded apps Orgo ships native iOS and Android apps that wrap the same Orgo interface your members use in a browser, plus the two things a browser cannot do: push notifications to the lock screen, and links that open straight into the app. **Built for** organizations whose members engage between meetings: alumni networks, professional associations, scouting and youth groups, unions, and anyone running frequent in-person events. **Works alongside** the web app rather than replacing it. Every screen in the app is the Orgo web interface, so a feature that exists on the web exists in the app, and there is nothing separate to configure per screen. *** ## Which app your members install Most organizations use the shared **Orgo Community** app. There is nothing to enable: any member of any Orgo organization can install it and sign in. | Platform | Store listing | | -------- | --------------------------------------------------- | | iOS | `apps.apple.com/us/app/orgo-community/id1484759378` | | Android | `play.google.com/store/apps/details?id=com.orgoapp` | Orgo also builds **branded apps**: a separate App Store and Play Store listing under your own name and icon, with its own push credentials and its own deep links. A branded app is provisioned by Orgo, not self-served, because it needs entries in your Apple Developer and Google Play accounts. Contact Orgo if you want one. Once a branded app exists, your organization record stores its two store URLs, and every "Download app" link in the product points at your listing instead of the shared one. *** ## How members find the app Two places surface the download, both automatic: * **Download app** in the user menu (sidebar on desktop, profile menu on mobile). It opens a submenu with **Download iOS App** and **Download Android App**. Hidden when the member is already inside the app. * An **install banner** at the top of the screen on mobile browsers, showing your app name and **Install app**. On a device that already has the app, the button becomes **Open app** and hands the current page over to it. Dismissing the banner is remembered on that device. It keys off the device, not the window: a phone or tablet browser shows it, a narrow desktop window does not, because there is nothing to install there. Sidebar user menu with the Download app submenu open showing Download iOS App and Download Android App Install banner at the top of a mobile browser showing the app name, the line Faster smoother in the app, and an Install app button *** ## Signing in Members sign in with the same email and password they use on the web, or with any other method your organization allows: a one-time code, MFA, or **Continue with Google**, **Microsoft** or **Apple** where you have [single sign-on](/docs/platform/integrations#single-sign-on) switched on. There is no separate app account and no workspace code to type. A social sign-in returns into the app it was started from, including a branded app. If a member belongs to more than one Orgo organization under the same email address, signing in through the shared app signs them into all of them at once and they switch between organizations from the workspace switcher. Signing in through a branded app or a custom domain signs them into that organization only. Non-member ticket holders do not use this login at all. They reach the Event App through a one-time code sent to the email on their ticket. See [Event App](/docs/platform/events/event-app). *** ## Push notifications Push has three moving parts, and all three must be true for a notification to arrive. **Settings → Emails & Notifications → Notification Preferences → Push Notifications** sets the default for new members. Requires `ADMIN_TENANT`. **Push notification, mobile app & web browser** on the **Notifications** tab of their profile (`/me/update`). Members who never touched the toggle are treated as opted in. The app registers the device automatically the first time the member opens it while signed in, and again whenever the device's push identity changes. Nothing to do by hand. Notifications tab of a member profile showing the Push notification, mobile app and web browser switch turned on A device is registered per organization. A member in two organizations who only ever opens one of them in the app receives push for that one until they open the other. Browsers get push too, through a different mechanism, on Chrome, Edge, Firefox and other Chromium browsers. Safari is excluded, so a member whose only Orgo access is Safari on a Mac or iPhone gets email notifications but not push. Installing the app is the fix. Turning the toggle on inside Orgo is not enough on its own: the member must also grant notification permission to the app or browser when the operating system asks. The setting screen says so. ### Testing that push works Admins with `ADMIN_TENANT` can open `/demo-notification` and send a test push to their own devices or to a specific member id, with a title, body and target link. It is the fastest way to prove a device is registered before debugging anything else. *** ## Deep links Links Orgo sends to a mobile-capable surface are built as **smart links** on the `l.orgo.space` domain. Opened on a phone with the app installed, the operating system hands them to the app; on any other device they fall through to the web. Orgo publishes the Apple and Android verification files for that domain automatically, including one entry per branded app. Smart links are used for: * **Push notifications** for discussions and mentions, events and event feed posts, event networking invitations, connection requests, local center and unit membership, task assignment and status changes, and new media files. * **Email links** for event invitations and registrations, discussion notifications, task assignment, and event networking invitations. * **Event ticket QR codes** and **vote share links**, which always prefer the app. Everything else, including all other emails and notifications, links to your normal Orgo address. *** ## Known limits Payment buttons are hidden in the iOS app and replaced with "To make a payment, please access app in browser." This is Apple's in-app purchase policy, not an Orgo setting. Members pay from a mobile or desktop browser; the payment then shows in the app like any other. Screens that record audio or video are blocked in current app builds and offer to reopen the page in the device browser instead. Uploading an already-recorded file works normally. The app needs a connection for every screen. Nothing is cached for offline reading and posts are not queued while offline. The web app's install metadata carries Orgo's own name and icon, so a browser "Add to Home Screen" shortcut is branded Orgo even for organizations with custom branding elsewhere. A branded app is the way to get your own icon on the home screen. Check, in order: notification permission for the app in the device's system settings; the member's **Push notification** toggle; that the member has opened the app at least once while signed in to that organization. Then send a test from `/demo-notification`. Signing out of the app removes that device's registration. *** ## Related * [Notifications](/docs/platform/notifications) - notification types, channels and digests * [Event App](/docs/platform/events/event-app) - the attendee experience and its separate login * [Check-in](/docs/platform/events/check-in) - scanning ticket QR codes at the door * [Branding](/docs/platform/organisation/branding) - logos and theming across the product * [Custom domain](/docs/platform/custom-domain) - your own address for the web app # Newsletter Source: https://orgo.space/docs/platform/newsletter Send email campaigns to members and contacts, with audience targeting, scheduling, and delivery reporting Newsletter is Orgo's email campaign tool. You pick who receives the email from the data already in the platform (members, contacts, a group, a list, the attendees of an event), design it, then send or schedule it. **Built for** membership organizations that need to reach a specific slice of their people, not a generic mailing list: one local center, one role group, the people registered for one event. **Replaces** Mailchimp or Constant Contact for member communication. It has no marketing automation and no A/B testing. Email campaigns page with four summary tiles, a status filter, and a table of campaigns showing recipients, open and click rates *** ## Turning it on and who can use it **Settings** → **Modules** → **Emails & Notifications** → **Enable Email Campaign Module**. The same page holds the **Default Newsletter Widget UUID** used by [signup widgets](/docs/platform/newsletter-widgets). | Permission | What it allows | | ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `COMMUNICATION_TENANT` | Create, send, and report on any campaign in the organization | | `COMMUNICATION_LOCAL` | The same, but only for the local centers you manage and only the **Members from a group** audience. Tenant-wide and event audiences are hidden, recipient counts are refused unless capped to a center you manage, and the send is capped again to that center | | `EVENT_TENANT` | Campaigns attached to an event ("event messages") | | `ADMIN_TENANT` | Sees every campaign | The module adds a **COMMUNICATION** sidebar section: **Email campaigns** (`COMMUNICATION_LOCAL`), **Campaign templates**, **Lists & Segments**, **Newsletter subscription** (all `COMMUNICATION_TENANT`), and **Email Log** (`ADMIN_TENANT`). *** ## Building a campaign Three steps: **Configuration**, **Design content**, **Preview & send**. **Campaign title** is internal, **Email subject** is what recipients see. **Sender name** defaults to your organization's short name and **Reply-to email** to its contact email; override either per campaign. Pick a recipient option below (its recipient count appears next to it), then start from Blank or from a saved template. Build it in the [editor](/docs/platform/newsletter-builder), check it with **Send test to your email** against your own data, then **Send** or use the **Schedule** tab. After the first save the campaign opens as tabs: **Configure**, **Content** and **Schedule** while it is a draft, then **Report** and **Sent message** once it has gone out. Content auto-saves in the editor. Campaign Configure tab showing campaign title, subject, sender name, reply-to, and the five recipient options with the live recipient count on the selected one *** ## Audiences | Option | Who it resolves to | | ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- | | **All members and contacts** | Every subscribed member plus every subscribed contact. Gains a local center dropdown when local centers are enabled, which narrows the send to one center | | **Members from a group** | The members of one group, role group, or local center. Leaving the group empty sends to all members | | **All subscribed contacts** | Contacts only, no members. Gains the same local center dropdown when contacts are assigned to local centers | | **From a list** | A [user list](/docs/platform/users/lists), static or dynamic | | **Event attendees** | The people registered for one event, members and external registrants | A member is included when the account has an email address and newsletter email is on in their notification settings; a contact when it has an email address and is marked newsletter subscribed. The database-wide audiences also require the account to be active. A manual list does not: it sends to the people in it, inactive included, and drops only accounts that were merged away or deleted. Nothing else filters: previously bounced addresses are not removed automatically, so clean those up from the report. New members inherit the **Newsletter Notifications** default from **Settings** → **Modules** → **Emails & Notifications** at the moment their account is created. Changing that default later does not touch anyone who already exists. Two ways to reuse a campaign: * **Follow up with non-openers** (count in the button) creates a draft named "Follow-up: ..." locked to people who received the original but never opened it, minus anyone who bounced, complained, or unsubscribed. The set is recalculated at send time, so late openers drop out; if nobody is left, Orgo refuses both the copy and the send. * **Duplicate campaign** creates a draft named "Copy ..." keeping the content, the subject, and the audience. *** ## Sending and scheduling | Behaviour | Detail | | ---------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Queue | Recipients are resolved in batches of 2,000 and each email is dispatched individually at roughly three per second per worker, so a large send arrives over minutes rather than all at once | | Resend guard | A campaign already **Sent** cannot be sent again, and a resend to the same recipient is skipped even if the queue retries | | Schedule window | At least 2 minutes in the future, on a 15-minute boundary (:00, :15, :30, :45), because the scheduler runs every 15 minutes. Today is the earliest selectable date, so a send later this afternoon is fine | | Schedule fields | Date, time, and timezone (defaults to your own timezone, falling back to the organization's) | | Schedule failure | Retried, then marked **Failed** after three failures | | Statuses | **Draft**, **Scheduled**, **Sending**, **Sent**, **Stop**, **Failed** | | Sending to Sent | Checked hourly. Automatic once every recipient has a delivered or bounced event, or after 15 minutes with no new events at 95% or better delivery, or after 2 hours at 95% or better, with a hard cut-off at 24 hours regardless | ### Picking a date and time The **Schedule** tab on a draft campaign and the **Schedule** dialog in the content editor's side menu are the same form and follow the same rules. * **Today is the earliest date you can pick.** A campaign written this morning can go out this afternoon. The fields open on tomorrow at 09:00 as a default, so change the date if you want it to leave today. * The time picker steps in 15 minutes, which is the boundary a schedule has to land on. * Anything less than 2 minutes away is refused: the form shows "Scheduled time must be at least 2 minutes in the future" and keeps the confirm button disabled. The same check runs again on the server. * The timezone dropdown decides what the clock time means. The date and time you type are read in that timezone, so 09:00 in Europe/Bucharest leaves at 09:00 in Bucharest wherever you happen to be sitting. It defaults to your own timezone, or the organization's if your profile has none. * Rescheduling follows the same rules, and removing a schedule puts the campaign back to Draft. The 2-minute check inside the form is measured against your device clock rather than against the timezone you selected. Scheduling same-day into a timezone several hours from your own can make the two disagree, so the warning appears on a time that is genuinely fine, or a time the form accepted is refused on save. Push the send a few hours out, or schedule in your own timezone, and it does not arise. *** ## Reporting The **Report** tab shows Sent, Opened, Clicks, Bounce, and Unsubscribed, the campaign details (subject, sender, audience, author, sent date, plus reply-to and the public URL when those are set), and **Top links** with click counts per URL. **Export CSV** gives one row per recipient per recorded action (delivered, opened, clicked, bounced, complained, unsubscribed, rejected, failed) with name, email, and action. Campaign report with Sent, Opened, Clicks, Bounce and Unsubscribed tiles above a campaign details table and a top links panel Numbers come from the mail provider's delivery events, not from the send: * **Sent** counts distinct recipients with a delivered or bounced event, so it reflects what actually left the platform. * **Opened** and **Clicks** are unique per recipient, not per event. Open tracking needs the mail client to load images, so real opens are undercounted. * Results are cached, refreshed when older than five minutes or when a newer delivery event arrives, and frozen 30 days after the last event. **Refresh** re-reads them on a sent campaign. * Values are capped so sent never exceeds the recipient count and opens and clicks never exceed sent, so a figure can differ slightly from a raw event count. Four tiles above the campaign list cover all sent campaigns: total campaigns, average open rate, average click rate, total recipients. The averages are weighted by recipients and clamped per campaign, so odd data cannot push them above 100%. *** ## Unsubscribes and public links Every campaign email carries one-click unsubscribe headers, so a member can opt out from their mail client without opening it. If your design has no unsubscribe placeholder, Orgo appends an unsubscribe link (and, for members, a link to their notification preferences) to the footer before sending. You cannot re-subscribe someone on their behalf. **Generate public link for this newsletter** publishes a browser-readable copy: copy a short share URL, upload a social preview image, and the campaign appears in the campaigns gallery (`/newsletter-gallery`), the in-app archive where members see sent campaigns addressed to them or to everyone. *** ## Common questions The count is a live preview; the stored number is recalculated when you press Send, so people who joined, left, or unsubscribed in between are reflected. Check the account is active, has an email address, has newsletter email on in their notification settings, and fell inside the audience. Then read the [email log](/docs/platform/emails/email-log) and the CSV export, which record bounces and rejections per recipient. Use **Event attendees**, or start from the event with **Send email for participants**, which files the campaign under the event's own messages list and unlocks the event placeholders. *** ## Related * [Newsletter builder](/docs/platform/newsletter-builder) for the editor, placeholders, and templates * [Signup widgets](/docs/platform/newsletter-widgets) for collecting subscribers from your website * [Notifications](/docs/platform/notifications) for the automatic messages members get * [User lists](/docs/platform/users/lists) for building reusable audiences * [Contacts](/docs/platform/contacts) for non-member recipients # Newsletter builder Source: https://orgo.space/docs/platform/newsletter-builder Design campaign emails with the drag-and-drop editor, personalise them with placeholders, and reuse designs as templates The builder is where a [campaign](/docs/platform/newsletter) gets its content. It is a drag-and-drop email editor: blocks on the right, the email in the middle, and a placeholder menu for inserting each recipient's own data. **Built for** people who send member emails without writing HTML and still need the result to survive Outlook, Gmail, and a phone screen. **Replaces** hand-built HTML emails and the "paste from Word and hope" workflow. Email builder with the design canvas in the middle, the content block palette on the right, and the Placeholders dropdown in the toolbar above the canvas *** ## Opening the editor Open a draft campaign and switch to the **Content** tab. Content saves automatically while you work, and the toolbar shows **Saving** and then **Saved**; **Save** forces it. The same editor opens standalone when you create or edit a template. The editor loads inside the page from Orgo's canonical app domain, so it works the same on a [custom domain](/docs/platform/custom-domain). *** ## Blocks Drag a block from the right-hand palette onto the canvas, then click it to edit its content and styling. | Block | Use it for | | ------------- | -------------------------------------------------------- | | **Columns** | Splitting a row into two or more side-by-side areas | | **Heading** | Section titles | | **Paragraph** | Body text with inline formatting and links | | **Image** | Photos, graphics, and logos | | **Button** | A call to action such as register, donate, or read more | | **Divider** | A rule between sections | | **Social** | A row of social network icons | | **Menu** | A row of links, typically a header nav | | **Video** | A linked video thumbnail | | **Table** | Tabular content | | **HTML** | Raw HTML when you need something the blocks do not cover | The side tabs are **Content** (the palette above), **Blocks**, **Body**, and **Uploads**. The toolbar has undo and redo, a desktop and mobile preview toggle, and a full preview. Stock image search and the Facebook, Google, and Unsplash integrations are switched off. Upload your images or paste their URLs. *** ## Placeholders **Placeholders** in the toolbar copies a token to your clipboard; paste it anywhere in the design and it is replaced per recipient at send time. | Placeholder | Resolves to | | --------------------------------------------------------------------------------------- | ----------------------------------------------------- | | `{firstName}`, `{fullName}` | The recipient's name | | `{userPhoneNumber}`, `{userAddress}`, `{userPostalCode}`, `{userTown}`, `{userCountry}` | Their contact details | | `{userProfileURL}` | A link to their profile | | `{userCompanyName}`, `{companyName}` | Their company, when the Companies module is on | | `{contactEmail}` | Your organization's contact email | | `{membershipLevelName}`, `{membershipLevelPrice}`, `{currentPeriodEnd}` | Their membership tier, its price, and when it expires | | `{preferencesUrl}` | Their notification settings | | `{unsubscribeUrl}` | The unsubscribe link | A campaign attached to an event gets eight more: `{eventTitle}`, `{eventDescription}`, `{eventDateBegin}`, `{eventDateEnd}`, `{eventTimezone}`, `{eventLocation}`, `{eventRegisterUrl}`, and `{eventAgendaUrl}`. Event dates are rendered in the recipient's own timezone where they have one, otherwise the event's, otherwise the organization's. Notes that save people time: * Both `{firstName}` and `{{firstName}}` work. * Placeholders work inside link URLs as well as in text. `{unsubscribeUrl}` and `{preferencesUrl}` become a bare URL inside an `href` and a ready-made link when used on their own. * Anything that does not resolve for a given recipient (a phone number they never filled in) is replaced with nothing, not left as raw text. * `{eventAgendaUrl}` only resolves for recipients with a confirmed registration for that event. * If the design contains no `{unsubscribeUrl}`, Orgo appends an unsubscribe footer automatically before sending. Always use **Send test to your email** before a real send: it renders the placeholders against your own record, so an empty field shows up immediately. *** ## Templates **Administration** → **COMMUNICATION** → **Campaign templates** holds the reusable designs. They are filtered by **All**, **Orgo** (the designs that ship with the platform), and **Custom** (yours), with a badge on each card. Email templates gallery with All, Orgo and Custom tabs and template cards showing rendered previews Hovering a card offers: * **Start Campaign**, which opens the create form with that template preselected * **Preview**, a full-size render * **Duplicate**, which copies it into a new custom template you can edit * **Edit** and **Delete**, on your own templates only Orgo templates cannot be edited or deleted; duplicate one and change the copy. **Blank** is not a template, it is the "start from scratch" card. Templates are shared across the whole organization, and local communication managers can read, create, and edit them so they can build their own center's campaigns. Picking a template while creating a campaign replaces the design only. The title, subject, sender name, reply-to, and audience you already chose are kept. New campaign form scrolled to the recipient options, with the recipient count on the selected one and the Choose a template carousel below them *** ## Troubleshooting It was almost certainly misspelled or is not in the list above. Copy it from the **Placeholders** menu rather than typing it, and check the case: `{firstname}` is not `{firstName}`. Mail clients strip modern CSS. Keep to the blocks, avoid pasting styled content from a word processor, and check the mobile preview before sending. Test sends are the only reliable check. Build it once, save it as a template, then use **Start Campaign** from the template each month. **Duplicate campaign** on a sent campaign is the other route, and it also carries the settings across. *** ## Related * [Newsletter](/docs/platform/newsletter) for audiences, sending, and reporting * [Signup widgets](/docs/platform/newsletter-widgets) for collecting subscribers * [Email templates](/docs/platform/emails/email-templates) for automatic system emails * [Branding](/docs/platform/organisation/branding) for logos used in emails # Newsletter signup widgets Source: https://orgo.space/docs/platform/newsletter-widgets Embed a subscribe form on your website and collect confirmed newsletter subscribers into Orgo A newsletter widget is a subscribe form you style in Orgo and embed on your own website. Someone who fills it in confirms by email and becomes a subscribed contact, ready for the next [campaign](/docs/platform/newsletter). **Built for** organizations whose public website lives outside Orgo but whose mailing list should not. **Replaces** a third-party signup form plus the CSV export that follows it. *** ## Creating a widget **Administration** → **COMMUNICATION** → **Newsletter subscription**. Requires `COMMUNICATION_TENANT` or `EVENT_TENANT`. Press **Create Widget**, give it a name, and save. Styling options appear once the widget exists. Each card in the list shows the widget's public URL, a **Subscribers** button with the count, and **Edit**. One widget is always the **Default**, marked with a star. It is the one served when a page asks for your organization's widget without naming one, including the subscribe box under a published campaign's public page. Use **Make default** to move the star. You cannot delete the last remaining widget, and deleting the default promotes another one automatically. Newsletter subscription widgets page with widget cards showing the default star, subscriber counts, and public URLs *** ## What you can configure The editor is split into settings on the left and a live preview plus the embed code on the right. | Section | Settings | | --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Widget Content** | **Widget box title** and **Widget box description**, each with a checkbox to hide it, and **Name field format**: None, a single full name field, or separate first and last name fields | | **Subscriber Tag** | A [tag](/docs/platform/users/lists) applied automatically to everyone who subscribes through this widget, so you can build a list from it later | | **Container Styling** | Border type (none, flat, radius), border style, width and colour, padding size, background and text colour, font size, element spacing | | **Input Styling** | Field padding and corner radius | | **Button Styling** | Corner style, background colour, text colour | Only the email field is mandatory. Name fields appear only if you turn them on, and then they are required in the form. Widget editor with content and styling settings on the left and the live preview with embed code on the right *** ## Putting it on your site The **Integration** panel offers two snippets plus a plain link. A `div` plus a script tag. The form renders inline in your page and inherits the width of its container. Copy it with **Copy Code** and paste it where the form should appear. The script host in the snippet is generated from the address you are using Orgo at, so always copy it from your own organization rather than retyping one from a screenshot. A fixed-height `iframe`. Use it when the page cannot run third-party JavaScript, or when you want full isolation from your site's CSS. Every widget also has a hosted page you can simply link to, for example from social media or a printed QR code. The organization's default widget is served at `/newsletter` on your Orgo host. Both snippets carry the widget's own identifier, so subscriptions are attributed to the right widget and the right tag. Copy the code again after changing the widget only if you switched widgets; styling changes apply to the live form without re-pasting. *** ## What happens when someone subscribes The address is validated. Submitting the same address twice within 5 minutes is refused so a double click does not send two emails. The form then shows "Please check your email for a confirmation message". Nobody is subscribed at this point. If the address already belongs to a member or a contact, that record is switched to newsletter subscribed. Otherwise a new contact is created with its source recorded as the newsletter. The widget's tag is applied, and the subscription is recorded against the widget for the subscriber count. This is a confirmed opt-in: an address that never clicks the link is never subscribed and never appears in the subscriber list. If people report signing up but not receiving campaigns, the confirmation email is the first thing to check. **Subscribers** on a widget card lists who came in through it, newest first, with a link to each member or contact record. *** ## Related * [Newsletter](/docs/platform/newsletter) for sending to the subscribers you collect * [Newsletter builder](/docs/platform/newsletter-builder) for designing the campaign * [Contacts](/docs/platform/contacts) for what a subscribed contact record holds * [User lists](/docs/platform/users/lists) for turning a tag into a reusable audience # Notifications Source: https://orgo.space/docs/platform/notifications In-app, push, and email notifications that keep members informed Notifications tell members that something happened to them or in a group they follow: a new discussion, a reply, a mention, an event invite, a role change, a published vote. **Built for** organizations whose members do not log in every day and would otherwise miss activity in their groups, local centers, and events. **Replaces** the "did anyone see my post?" follow-up email. It is not a broadcast tool: to email everyone deliberately, use the [Newsletter](/docs/platform/newsletter). Every notification is first an in-app record. Push and email are deliveries of that same record, so a member who has turned both off still sees everything under the bell. Your Notifications page listing file uploads, new events, connection requests, and mentions with relative timestamps *** ## Where members see them The bell in the header opens a side panel: 20 per page, newest first, loading more as you scroll. **Your Notifications** (`/notifications`) is the same list as a full page. Clicking an entry opens what it refers to; file notifications open the document in a new tab. The unread badge is per workspace, so a member of several organizations sees a separate count for each. It refreshes on a 180-second poll, and immediately when a notification is created: the badge increments and a toast appears in any open tab. Live delivery reaches members only, not [contacts](/docs/platform/contacts) on an event-app session. Opening the panel or the full page marks everything read, as does opening what a notification points at: a discussion, an event, or a drive file. *** ## What generates a notification | Shown as | Who receives it | | ------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- | | added a discussion / added a task | Followers of the group it was created in (all active members, for open-access local centers, all-member groups, and role groups) | | added an event | Followers of the event's group, or every active member if it has no group. Only for events that are published and not in the past | | added a file | Followers of the group whose drive it was uploaded to | | commented on discussion | Everyone following that discussion, except the commenter | | replied on your comment | The comment author | | mentioned you in a post / comment / reply | The mentioned members | | reacted to your post / comment | The author of the discussion or comment | | solved task / reopened task / commented on task | Assignees and the creator, except the person acting | | invited you to the event | The member an organizer adds to an event | | posted in / replied to your post / reacted to your post | Participants in that event feed | | published a new vote / closed the vote | Everyone eligible to vote (event attendees, group followers, or the named voter list) | | invited you to a 1:1 | The other party to a networking meeting requested, accepted, declined, or cancelled in the event app | | added you | The member added to a local center, group, or role group | | changed your role | The member whose roles an admin edited | | registered in the organisation | The member who completed their own registration | | accepted your invitation | The inviter, when an invited person joins | Inactive members are never notified, and nobody is notified about their own action. *** ## Channels | Channel | Applies to | Conditions | | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | In-app | Every notification | Always stored, whatever the member's other preferences say | | Push | Everything except file uploads | The member has **Push notifications** on and at least one registered device or browser | | Email | Discussions, comments and replies, mentions, events, votes, tasks and support tickets, and membership changes (added to a group or local center, roles changed, registration, invitation accepted) | Content notifications need the matching per-member toggle. Membership changes have no toggle and always email. Reactions, file uploads and networking 1:1 invitations never email. Moderation alerts are not emailed through this path either, but moderators do receive a separate email for each held post, capped at 50 moderators per post, with no toggle. See [Moderation](/docs/platform/discussion/moderation). | Membership and role changes are the surprising row. When an administrator gives a member a new role, the member gets an email as well as the in-app entry, and no notification preference switches it off. The single exception is a change to the member's **user type**, which is deliberately silent. Removing a role notifies nobody, and neither does editing your own roles. Task comments are the other category the preference screen does not cover. Comments on a project task email the assignees and the task creator through the task email path rather than through notification preferences, so the **Task** toggle does not stop them. That toggle governs support tickets and issues. *** ## Member preferences Members set their own under **Edit profile** → **Notifications**. Admins with `ADMIN_LOCAL` see the same tab on a member's profile and can change it for them. | Control | Effect | | -------------------------------- | --------------------------------------------------------------------------------------------------------------- | | **Push notification subscribed** | Master switch for browser and mobile push. Off means no device receives anything. | | **Newsletter (email)** | Subscription to newsletter campaigns, shown only when the newsletter module is on. Separate from notifications. | | **New discussion** | Email for new discussions, with a frequency chip: **Instant**, **Daily**, or **Weekly**. | | **New event** | Instant email when an event is published or you are invited. | | **Comment on my post** | Instant email when someone comments or replies. | | **Task** | Instant email for task and support-ticket activity. | | **Mentions** | Instant email when you are @mentioned. | | **Voting / Polls** | Instant email when a vote is published or closed. Shown only when the voting module is on. | Turning an email toggle off never hides the notification in the app. It only stops the email. Every notification email carries an unsubscribe link that switches off just that category, plus a `List-Unsubscribe` header that opens a page switching off everything. True one-click unsubscribe, where the mail client acts without opening anything, exists on campaign email only. ### Daily and weekly digests Setting **New discussion** to **Daily** or **Weekly** replaces instant discussion emails with a summary. * A discussion notification is what triggers a digest, but the email itself carries the ten most recent unread notifications of any type. A member who switched off event or mention email still sees those items listed in their digest, because nothing marked them read. * A digest carries at most 10 unread items. * Daily runs at 06:00 UTC looking back 25 hours; weekly runs at 09:00 UTC on its scheduled day looking back 7 days. * Sending a digest marks those notifications read, so the bell badge resets with it. *** ## Tenant defaults **Settings** → **Modules** → **Emails & Notifications** → **Notification Preferences**. Requires `ADMIN_TENANT`. Default Notification Preferences with switches for newsletter, push, comments, tasks, votes, events, mentions and a frequency selector for discussions | Setting | Default | | ------------------------------------ | ------- | | **Newsletter Notifications** | On | | **Push Notifications** | On | | **Email Notifications: Comments** | Instant | | **Email Notifications: Tasks** | Instant | | **Email Notifications: Votes** | Instant | | **Email Notifications: Events** | Instant | | **Email Notifications: Discussions** | Weekly | | **Email Notifications: Mentions** | Instant | These are seeds, not overrides. They are applied once, during onboarding, to members who have never set their own preference. Changing them does nothing to anyone already in the organization. *** ## Push notification setup **Browser push** is offered automatically: a supported browser asks for permission on first load, and allowing it registers that browser. Revoking permission removes the registration. Safari and the native app wrapper skip this path. **Mobile push** runs through OneSignal. The device registers when the member signs in to the Orgo app, tagged with the workspace so the right organization's messages reach it. A tenant with its own branded app sets its own OneSignal app ID and REST API key on its organization record; every other tenant uses the shared Orgo app. Registration is per member, per workspace, per device: someone in two organizations registers the same phone once for each, and the two never share notifications. Signing out removes that device's registration, which is why a member who never signs out on an old phone keeps receiving there. *** ## Muting a group Members can mute a group they cannot leave: an all-member group, a role group, or an open-access local center. The button reads **Mute** on the group card and **Subscribe** in the group header. Muting stops new discussion, event, and file notifications from that group, but not direct ones such as mentions. *** ## Retention Notifications older than two months are deleted nightly. The bell is a recent activity feed, not an audit trail: for a durable record of email, use the [email log](/docs/platform/emails/email-log). *** ## Troubleshooting Work on their profile, **Notifications** tab, not on the tenant defaults: the defaults are seeds applied once at onboarding and changing them does nothing for anyone already in the organization. Take the categories in this order. 1. Set **New discussion** to **Daily** or **Weekly**. Discussions are usually the bulk of the volume and the only category that batches. 2. Turn off the individual categories they object to. Each one only stops the email; the notification still appears under the bell. 3. If they are still unhappy, check whether the traffic is coming from something with no toggle: membership and role changes always email, and task comments email through the task email path. A member who is a member of several organizations sees these preferences separately in each one, so check the workspace they are complaining about. Work down the chain, because each link fails independently. 1. **Push notification subscribed** on their profile. Off means no device receives anything, whatever the browser says. 2. Permission at the operating system or browser level. Orgo cannot see a revoked permission, and revoking it removes the browser registration. 3. Whether a device is actually registered. Registration happens at sign-in, so signing out and back in is the reliable fix, and a member who never signs out on an old phone keeps receiving there instead. 4. The notification type. File notifications never push, in-app only. 5. For an organization with its own branded app, whether the OneSignal app ID and REST API key are set on the organization record. Without them the mobile sends are rejected and only browser push works. Registration is per member, per workspace, per device, so someone in two organizations has to be signed in to both on that phone to receive from both. In-app and email are separate deliveries of the same record, so the record existing proves nothing about the email. Check, in order: * the type, against the Channels table above. Reactions, file uploads and networking invitations have no email at all, and moderation alerts are emailed on their own path rather than this one; * the matching per-member toggle, and for discussions whether the frequency is **Daily** or **Weekly**, in which case the email is waiting for the next digest run; * whether they used an unsubscribe link, which switches a category off with no confirmation step and no trace on the profile other than the toggle itself; * the address on the account. An empty or malformed address is skipped silently, without an entry in the email log; * whether this is a demo organization. Demo tenants never send notification emails. Yes, and it is the most confusing behaviour on this page. Unsubscribe links match on the email address, not on the account, so one click switches that category off for every Orgo account sharing that address, in every organization. The one-click unsubscribe in the mail header does the same for all categories at once. The fix is to turn the categories back on per account, on each affected profile's **Notifications** tab. Start with the group type, because who receives is decided there and not by a setting on the discussion. * A restricted group notifies the members who follow it, and nobody else. An empty follower list means an empty notification run. * An open-access local center, an all-member group and a role group notify every active member except those who muted the group. * Inactive members are never notified in any group, and the person who posted is always excluded. If a single member is missing, check their status first and whether they muted the group second. More things than most admins expect, which is why the badge is a poor proxy for "has the member seen this". * Opening the bell panel or the notifications page marks every unread notification read, not just the ones on screen. * Opening the thing a notification points at (a discussion, an event, a drive file) marks the notifications for that item read. * Sending an instant email for a notification marks that notification read, so an unopened inbox still zeroes the badge. * Sending a digest marks every unread notification read for that member, not only the ones listed in the digest. A digest run only picks up members who have at least one unread **discussion** notification in the window. Comments, events, mentions, votes and task activity do not trigger a digest, so a member whose groups are quiet gets nothing even with the frequency set. Also check that the member is Active, that their address is valid, and the timing: the daily run is 06:00 UTC looking back 25 hours, and the weekly run is Wednesday 09:00 UTC looking back 7 days. A member who set **Weekly** on a Thursday waits almost a week for the first one. No. Notifications older than two months are deleted nightly, records and read state together. The bell is a recent-activity feed, not an archive. For a durable record of what was sent, use the [email log](/docs/platform/emails/email-log), which is not on this retention schedule. Live delivery goes to members only. People signed in through an event-app session as [contacts](/docs/platform/contacts) get the notification stored and pushed, but no live badge or toast: their count moves on the next refresh. The badge also polls every 180 seconds, so a member with a stale tab can be up to three minutes behind. *** ## Related * [Newsletter](/docs/platform/newsletter): Deliberate email campaigns to a chosen audience * [Discussions](/docs/platform/discussion): The activity that generates most notifications * [Mobile Apps](/docs/platform/mobile-apps): Branded apps and device setup * [Groups](/docs/platform/groups): Who follows what, and therefore who gets notified * [Permissions](/docs/platform/permissions): Which roles can change tenant-wide defaults # OAuth Server Source: https://orgo.space/docs/platform/oauth Use Orgo as an identity provider: let members sign in to your own apps with their Orgo account Orgo is an OAuth 2.0 provider. Members can use their Orgo account to sign in to your website, an internal tool or a partner application ("Login with Orgo") without a second set of credentials. **Built for** organizations running their own software alongside Orgo. **Replaces** duplicate user directories and manual account provisioning. OAuth Apps page listing registered applications with their App ID and redirect URI, with Create App and OAuth documentation buttons *** Use it when a person signs in to software you run: your website, a custom mobile app, an internal tool. For a script or a cron job that acts on nobody's behalf, use an [API token](/docs/platform/api) instead. To let people sign in to Orgo with Google or Microsoft, you want [SSO Authentication](/docs/platform/integrations), which points the other way. *** ## Registering an application **Settings → Developers → OAuth Apps → Create App**. Requires **ADMIN\_TENANT**. | Field | What to enter | | ------------------------------------ | --------------------------------------------------------------------------------------------- | | **Title** | The name members see on the consent screen | | **Redirect URL (including http(s))** | Where Orgo sends the member after they approve. Must match your authorization request exactly | | **Access level** | On: the app can act on the member's behalf (read and write). Off: read-only | On save, Orgo shows the **App ID** (your `client_id`) and the **App Secret** (your `client_secret`) once. Copy the secret then: it is not shown again. If it is lost, open the app and use **Generate new App Secret**, which invalidates the old one. Apps created here are confidential clients bound to your organization: only members of your organization can authorize them. A developer can also self-register a **public** client against your tenant, without an administrator, through the standard dynamic-registration endpoint. Those clients get no secret and are authenticated by PKCE alone. Registration is throttled to 10 clients per hour per IP address. See [Authentication](/docs/api-reference/concepts/authentication). *** ## What an app you register can never do A token issued to an app registered on this page is capped at **member level**, whoever authorizes it. If an administrator connects the app, it still cannot perform administrative actions. This is deliberate and not configurable. An app you register holds a long-lived shared secret and runs unattended, so it must not be able to inherit an administrator's authority. Self-registered public clients are treated differently, and on purpose. They hold no secret, PKCE binds the code to the one browser that started the flow, and the token is short-lived and tied to the member who approved it. Such a client stands in for that member's own session, so it carries their own authority rather than a member-level cap. An interactive tool an administrator connects to their own account, an AI assistant for example, therefore works with that administrator's permissions. On top of that cap, a read-only app (**Access level** off) may use `GET`, `HEAD` and `OPTIONS` only. Anything else is rejected with `403` and *"This application has read-only access and may not act on your behalf."* The read-only limit is by **HTTP method, not intent**. A few endpoints perform a read over `POST`, and a read-only app cannot call those either. If a partner reports being blocked on something that only reads data, this is usually why. The consent screen tells the member which of the two applies, along with the app's name, the scopes requested and the redirect URI, before they approve. *** ## The flow ``` 1. Your app sends the member to /authorize with a PKCE challenge ↓ 2. The member signs in to Orgo and approves (or denies) ↓ 3. Orgo redirects back to your redirect URI with ?code=…&state=… ↓ 4. Your server exchanges the code for tokens at /api/v1/oauth/token ↓ 5. Your app calls the API with the access token ``` Standard OAuth 2.0 authorization code flow. **PKCE (S256) is required for every client**, including confidential ones, which send both their secret and the `code_verifier`. ### 1. Authorization request ``` GET /authorize? response_type=code& client_id=YOUR_APP_ID& redirect_uri=YOUR_REDIRECT_URI& scope=profile email& state=RANDOM_STATE& code_challenge=BASE64URL(SHA256(verifier))& code_challenge_method=S256 ``` ### 2. Code exchange ``` POST /api/v1/oauth/token Content-Type: application/x-www-form-urlencoded Authorization: Basic base64(client_id:client_secret) grant_type=authorization_code& code=AUTHORIZATION_CODE& client_id=YOUR_APP_ID& code_verifier=ORIGINAL_VERIFIER& redirect_uri=YOUR_REDIRECT_URI ``` Send the secret either in the `Authorization: Basic` header or in the body, never both. ### 3. Identify the member ``` GET /api/v1/oauth/userinfo Authorization: Bearer ACCESS_TOKEN ``` Returns OIDC claims for the scopes granted: `sub` and `tenant_id` always, `name` / `given_name` / `family_name` / `picture` with `profile`, `email` and `email_verified` with `email`, `groups` and `roles` with those scopes. `GET /api/v1/me` returns the fuller Orgo profile. *** ## Lifetimes | Token | Lives | Notes | | ------------------ | ---------- | ----------------------------------------------------------------------------------------------------------- | | Authorization code | 10 minutes | Single use | | Access token | 1 hour | Bearer token for API calls | | Refresh token | 30 days | **Rotates**: each refresh returns a new one and invalidates the previous, so store the new value every time | An authorization session that is started and not completed expires after 30 minutes; the member simply restarts the flow. *** ## Endpoints and scopes Configure your client from the discovery document rather than hardcoding paths: ``` https://your-org.orgo.space/.well-known/oauth-authorization-server ``` Everything lives on your organization's own host, including your custom domain. `/.well-known/openid-configuration` serves the same document, and public signing keys are at `/api/v1/oauth/jwks.json`. | Scope | Grants | | --------- | ----------------------------------------- | | `profile` | Name and profile picture | | `email` | Email address and whether it is confirmed | | `groups` | The member's local center | | `roles` | The token's effective roles | Request only what you need: fewer scopes means a simpler consent screen and less data leaving Orgo. *** ## Built-in developer page Orgo ships an OAuth reference inside the app at **Settings → Developers → OAuth Apps → OAuth documentation**, filled in with your own organization's host so developers can copy working URLs. In-app OAuth documentation page showing the authorization code flow with the organization's own domain in the example URLs *** ## Legacy token exchange The older `request-token-sso` / `verify-success-token-sso` handshake is **deprecated**. Existing integrations keep working and its responses now carry a `Deprecation` header, but new ones must use the OAuth 2.0 flow above. A removal date will be announced separately. *** ## Troubleshooting The `redirect_uri` in your authorization request must match the one registered on the app exactly. Watch trailing slashes, http versus https, and port numbers. Wrong or missing App Secret, or a secret sent by two methods at once. Use either the Basic header or the body. The code was already used, it expired (10 minutes), or the `redirect_uri` differs from the one sent to `/authorize`. Too many failed secret attempts for that App ID: 10 within 5 minutes. Wait for `Retry-After`. A request with the correct secret is never throttled. The member is signed in to another workspace than the one the app was created in. They must switch workspaces before approving. Self-register as a public client rather than using an app created here: no secret to leak, PKCE authenticates it. Never ship the App Secret in browser or mobile code. Token exchanges belong on your server. *** ## Related * [API Access](/docs/platform/api) - tokens for server-to-server access * [Authentication](/docs/api-reference/concepts/authentication) - the full authentication reference * [Integrate OAuth login](/docs/api-reference/recipes/integrate-oauth-login) - end-to-end walkthrough * [Integrations](/docs/platform/integrations) - inbound SSO and third-party services * [Permissions](/docs/platform/permissions) - what member level means in Orgo # Official Gazette Source: https://orgo.space/docs/platform/official-gazette A dated, numbered register of your organization decisions and official documents The Official Gazette is a register of your organization's formal documents: board decisions, resolutions, statutes, minutes, anything your bylaws require you to record. Each entry has a type, a date, an optional number, searchable text, and one attached file. **Built for** associations, federations and professional bodies whose statutes require decisions to be recorded and made available to members. **Replaces** the shared folder of scanned PDFs that nobody can search and nobody can date reliably. The feature is called **Official Gazette** in Settings. In the member menu and on the page itself the English label is **Official documents**. Both refer to the same register. Official documents list with type filter, text search, and rows showing document date, download icon, title, type and who added it *** ## Turning it on **Settings** → **Modules** → **Files & eDocuments** → **Official Gazette** → **Enable Official Gazette Module** The toggle requires `ADMIN_TENANT` and is off by default. Once it is on, **Official documents** appears in the sidebar under **Organization**. *** ## Who can do what | Action | Permission | | ----------------------------------- | ----------------------------------------- | | Read the list and open any entry | Any signed in member of your organization | | Create an entry | `HR_TENANT` | | Edit an entry | `HR_TENANT` | | Upload or replace the attached file | `HR_TENANT` | | Delete an entry | `HR_TENANT` | `ADMIN_TENANT` includes all of these. The register is not public and not selectively private. There is no anonymous access to it, and every signed in member of your organization can open every entry. The **Private** / **Public** choice on the form records a status on the entry, it does not restrict who can read it. Do not put material there that some of your members should not see. *** ## Document types Every entry must be given a type, chosen from a list your organization already has ("Decision", "Resolution", "Minutes", or whatever your statutes use). Types are reference data: they are read only in the app, so there is no screen for adding or renaming one. If you need a new type, ask Orgo support to add it. *** ## Adding an entry **Official documents** → **Add Official Documents** The record is created first and the file is uploaded afterwards. The form says so: "You will be able to upload the file after you create the record". Saving takes you straight to the edit screen where the upload button appears. Official document form with Status radio buttons, Type select, Subject, Document number, Document date and Content fields | Field | Required | What it does | | ------------------- | -------- | -------------------------------------------------------------------------------------------------------------- | | **Status** | Yes | **Private** or **Public**. Recorded on the entry as a label. It does not change who can read it | | **Type** | Yes | One of your organization's document types | | **Subject** | Yes | The title, shown in the list and at the top of the entry | | **Document number** | No | A whole number. Use it for your own numbering series | | **Document date** | Yes | The official date of the document, which can differ from the day you upload it. This is what the list sorts by | | **Content** | No | Free text. The form labels it "For internal search purpose": it makes the entry findable by its wording | | **Document file** | No | One file per entry, added after saving. Uploading again replaces it | Numbering is yours to define. Orgo stores the number you type and never generates one, so an entry with no number simply shows none. *** ## Finding an entry The list opens newest first, by document date. Sort by **Document date** or **Type** by clicking the column header. | Tool | How it works | | ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------- | | **Type filter** | The dropdown beside the page title, defaulting to **Any** | | **Search by text** | Free text box. Searching starts at three characters. Choose **Title** or **Content** with the radio buttons beside it to pick which field is matched | | **Download** | The cloud icon in the list downloads the attached file without opening the entry | Searching matches anywhere inside the field, so "budget" finds "2025 budget approval". Single official document showing subject, who created it, document number and date, and a download link for the attached file Opening an entry shows the subject, who created it, the number (when one was given), the document date, a download link labelled with the original file name, and the content underneath. If the entry is tied to a chapter, that chapter is shown as a link at the top. *** ## Editing and deleting Open an entry and choose **Modify**, or use the pencil in the list's **Actions** column. Every field including the attached file can be changed, and there is no version history: an edit overwrites what was there. Deleting an entry from the edit screen also deletes its attached file. Nothing is archived and nothing is recoverable from the app afterwards. For a correction that has to stay auditable, publish a second entry that references the first rather than editing the original. The register has no built in amendment link, so say it in the subject: "Correction to Decision 14/2025". *** ## Common questions The module is off. Turn it on at **Settings** → **Modules** → **Files & eDocuments** → **Official Gazette**. The edit screen requires `HR_TENANT`. The pencil is also shown to the member who created the entry, so someone who added an entry before losing that permission still sees the icon without being able to use it. Ask an administrator to make the change. Your organization has no document types yet, and they cannot be created from the app. Contact Orgo support with the list of types your statutes use. Publishing an entry sends nothing. There is no notification, email or digest tied to the register. Announce new entries through a [newsletter](/docs/platform/newsletter) or a [discussion](/docs/platform/discussion) post and link to them. Use the register for documents that need a date, a number and a permanent public record inside the organization. Use [Files](/docs/platform/files) for working documents, drafts and anything you want scoped to a single group. *** ## Related * [Files](/docs/platform/files) - document storage with folder and group level permissions * [Contracts](/docs/platform/contracts) - documents that members sign * [Organizational Chart](/docs/platform/organisational-chart) - the officers who take these decisions * [E-Voting](/docs/platform/e-voting) - the votes behind a decision * [Newsletter](/docs/platform/newsletter) - announcing a new entry to members # Branding Source: https://orgo.space/docs/platform/organisation/branding Logos, login background, and the default interface theme for your organization. Branding controls three things: the four logo variants Orgo swaps between depending on where and on what background a logo is shown, the image behind your sign-in and registration screens, and the default interface theme members see. **Built for** organizations whose members should recognise the platform as theirs, including federations, professional associations, and youth organizations that put their mark on every member touchpoint. **Replaces** the assumption that a members' area has to look like the vendor's product. **Settings → Organization → Branding** Requires **ADMIN\_TENANT**. The page is unreachable and its contents are hidden for everyone else. Branding page showing the four logo slots filled with the organization's wide light, wide dark, square and square dark logos, above the PNG format hint *** ## The four logo slots Uploads accept **PNG and JPEG**. The page's own hint is: for best layout results, use PNG with a transparent background. | Slot | Where it appears | | -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Logo light theme** | App header and sidebar, the sign-in screen, registration screens, invoice emails, and the invoice PDF | | **Logo dark theme** | Substituted for the light logo whenever the surface behind it is dark | | **Squared logo** | Browser favicon, the favicon on public share pages, your organization's avatar in lists, the OAuth consent screen, and the centre of an event app QR ticket | | **Icon logo dark** | The favicon when the member is in dark mode, whether from their own theme choice or their operating system | Two behaviours are worth knowing: **The dark logo is not only for dark mode.** In the app header it is used whenever the chrome is dark, which includes a dark menu theme on an otherwise light interface. If you skip this slot, a dark-on-dark logo becomes invisible for those members. **The first upload fills the empty slots.** Upload the light logo while the other three are still empty and the same image is copied into all four. That is a starting point, not a finished setup: replace the dark and square variants so contrast and cropping are right. If a slot is empty and nothing was copied into it, that slot alone falls back to Orgo's own mark; the other three keep their own image. **Logo dark theme** falls back to the light logo first, both in its box here and in the app, so an empty dark slot shows your light logo rather than Orgo's. Give **Squared logo** and **Icon logo dark** a genuinely square image. They are used as a favicon and as an avatar, so a wide logo ends up either letterboxed or cropped. *** ## Login background Auth background image URL field holding a background image address, with a Save button below it **Auth background image URL** takes a URL, not a file upload. Paste a publicly reachable HTTPS address and click **Save**. It appears behind the sign-in screen and the registration screens, including the per-user-type and child registration forms. It does not appear on the password reset or password setup screens. It is a **desktop-only** treatment: on phones and in embedded iframes the form fills the frame and no background is drawn. Leave the field empty and members see Orgo's default animated background instead. Sign-in screen with the organization logo and a custom photographic background *** ## Default theme for your organization Below the logos, **Default theme for organization** sets the chrome: the sidebar, header, and surface colours. Your primary brand colour is not part of it and does not change. Theme picker showing the Light menu and Dark menu preset swatch rows, both hue sliders and the Reset to default button | Group | Presets | | -------------- | --------------------------------------------------- | | **Light menu** | Default Cool, Warm, Sage, Lavender, Rose, Sand | | **Dark menu** | Gray, Graphite, Midnight, Forest, Amber, Ruby, Plum | A dark menu preset gives you a dark sidebar and header with light content. That is not the same as full dark mode, which inverts the whole interface. Clicking a swatch saves immediately: there is no separate Save button for the theme. **Reset to default** puts the organization back on Default Cool. The **Or set a custom hue** sliders are a live preview on your own device only. A custom hue is never stored as the organization default. Only the named presets above become what other members see. The theme a member actually sees is resolved in this order: the member's own choice, then your organization default, then Orgo's built-in default. Members pick their own from the theme sidebar, and their choice is stored separately for desktop and mobile. Setting an organization default therefore changes what new members and members who never chose will see, not what everyone sees. If you are currently viewing Orgo in dark mode, the Light menu block is hidden and only the dark presets are offered. *** ## What is not customisable * **The primary brand colour.** It is a fixed design token with no per-organization input. Only the chrome hue is configurable. * **Fonts and layout.** * **The mobile app icon.** The shared Orgo app ships Orgo's own icons; the Squared logo slot does not change them. Branded per-tenant apps are a separate arrangement, covered in [Mobile Apps](/docs/platform/mobile-apps). * **Most email headers.** The light logo is used on invoice emails and the invoice PDF. Other system emails use a shared layout with no logo. *** ## Troubleshooting Check which slot the file is in. The two **Logo** slots expect a wide image; **Squared logo** and **Icon logo dark** expect a square one. A wide file in a square slot is what produces cropping in the favicon and avatar. Open the URL in a private window with no session. If it does not load there, the host requires authentication or is not public. If it does load, check you are not on a phone: the background is desktop only. The dark variant is missing or is the same file as the light one. Upload a light-coloured version to **Logo dark theme** and **Icon logo dark**. This also applies to a dark menu theme in an otherwise light interface. The file is a JPEG, which has no transparency, or a PNG exported on a white background. Re-export as PNG with transparency. Custom hues are not saved to the organization. Pick the closest named preset instead. The admin **Getting Started** checklist has a **Customization & Branding** step whose first task, **Add organisation's logo**, links straight to this page. *** ## Related * [Organization Info](/docs/platform/organisation/organisation-info) - Name, contact email, and financial details * [Custom Domain](/docs/platform/custom-domain) - Serve the community from your own address * [Modules](/docs/platform/organisation/modules) - Turn platform features on and off * [Labels and Terminology](/docs/platform/customization/labels) - Rename product vocabulary * [Mobile Apps](/docs/platform/mobile-apps) - Shared app and branded apps # Organization Settings Source: https://orgo.space/docs/platform/organisation/index The settings area: your organization identity, the modules you switch on, how the app is customized, and developer access. Settings is where you define what your workspace is and what it does: your legal and contact identity, which features members can see, how the app is worded and laid out, and who gets programmatic access. This page is the map. Open it from the cog icon in the top bar, or from your avatar menu, **Organisation Settings**. Settings area with the Organization, Modules, Customization and Developers sidebar next to a module configuration page The cog icon and the menu entry both require **ADMIN\_TENANT**, and so does nearly every page inside. Two exceptions: **Merge Records** is open to **HR\_TENANT** and **Billing** to **FINANCIAL\_TENANT**. *** ## Organization Who you are. | Page | What it covers | | ------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | | [Organisation info](/docs/platform/organisation/organisation-info) | Name, country, timezone, default language, office contact details, legal links, social URLs, currency, VAT and registration numbers, bank IBANs | | [Branding](/docs/platform/organisation/branding) | Logo variants and the login background | | **Usage & Billing** | Your workspace's resource usage and Orgo subscription | *** ## Modules What members can see and do. Each entry is a feature area with its own configuration page and its own on/off switch, and turning one off hides it across the app. Users & Profiles, Contacts, Events, Discussions, Groups & Teams, Files & eDocuments, Emails & Notifications, Professions, Payments & Fees, Gamification & Courses, Helpdesk, Projects, Voting, Identity Validation, Companies, Form Builder, and **All Modules** for the full switchboard. Files & eDocuments only appears in this list once the Drive module is active. See [Modules](/docs/platform/organisation/modules) for what each one turns on and the settings inside it. *** ## Customization How the app looks, reads and is filled with data. | Page | What it covers | | ------------------------------------------------------------------ | ------------------------------------------------------------------------------- | | **Workflows** | Automations you define | | **eDocuments templates** | Document templates, shown when the eDocuments module is on | | [Custom Domain](/docs/platform/custom-domain) | Serving Orgo on your own address, and verified email sending | | [Languages](/docs/platform/customization/languages) | Which languages members can pick | | [Texts](/docs/platform/customization/labels) | Renaming product vocabulary to match your organization | | [Menu Organizer](/docs/platform/customization/menu-organizer) | Reordering and hiding sidebar entries | | [Dashboard Organizer](/docs/platform/customization/dashboard-organizer) | Dashboard widgets and categories, shown when the custom dashboard setting is on | | [Dashboard Welcome](/docs/platform/customization/dashboard-welcome) | The welcome message on the member dashboard | | [Import](/docs/platform/customization/import) | Bringing members and other records in from a file | Demo workspaces get two extra entries here, Demo Data and AI Provisioning, for seeding a workspace with sample content. *** ## Developers | Page | What it covers | | --------------------------------------------------- | ------------------------------------------------------------ | | [Third-party Integrations](/docs/platform/integrations) | Connections to outside services | | [API Tokens](/docs/platform/api) | Machine access to your data, shown when the API module is on | | [OAuth Apps](/docs/platform/oauth) | Apps that sign members in, shown when the API module is on | | **Webhooks** | Outbound notifications when records change | | [Merge Records](/docs/platform/users/merging-duplicates) | Combining duplicate people | | **Logs** | Activity history for your workspace | | **API Documentation** | Opens the API reference in a new tab | *** ## Finding a setting There are several hundred individual toggles. Rather than hunt through the menu, use the **Search settings...** box at the top of the settings sidebar, or press `Cmd` + `K` (`Ctrl` + `K` on Windows and Linux) while you are anywhere inside Settings. It searches page names and individual setting labels and jumps straight to the one you pick. *** ## Setting up a new workspace Name, country, timezone, default language and office email first. Everything else reads from these, and Name and Office Email are required before the form will save. Upload your logos and login background so the app looks like yours before anyone signs in. Turn on what you use and leave the rest off. A module that is off does not appear in the sidebar, and its settings and email templates stay out of the way. Configure what you collect at registration and on member profiles, under Users & Profiles. If you will take money, finish the currency, legal name, VAT and IBAN fields on Organisation info before issuing the first invoice. Documents keep the values they were generated with. Rename vocabulary, reorder the menu and set the dashboard once the shape of the workspace is settled. *** ## Troubleshooting It renders for ADMIN\_TENANT only, and only on desktop. Local admins, HR and finance managers, and regular members do not get it. On a phone, use the avatar menu instead. Some entries are conditional: Files & eDocuments appears only when the Drive module is active, eDocuments templates only when eDocuments is on, Dashboard Organizer only when the custom dashboard setting is on, and API Tokens and OAuth Apps only when the API module is on. Turn the module on under **All Modules** and the entry appears. `Cmd` + `K` is only bound inside the settings area. Open any settings page first, then press it. *** ## Related * [Organisation info](/docs/platform/organisation/organisation-info) every field on the organization record * [Branding](/docs/platform/organisation/branding) logos and login background * [Modules](/docs/platform/organisation/modules) the full module reference * [Customization](/docs/platform/customization) languages, labels, menu and dashboard * [Permissions](/docs/platform/permissions) who can reach what # Modules Source: https://orgo.space/docs/platform/organisation/modules Turn features on and off. Configure exactly how each one behaves. A module is a block of settings stored on your organization that decides whether a whole area of Orgo exists for your members. Turn Events off and events disappear from the sidebar, the dashboard and search. Turn it back on and everything is exactly where it was, because switching a module off hides screens, it does not delete data. **Built for** organizations that need a slice of the platform rather than all of it: a federation running events and membership fees but no courses, an association running discussions and a helpdesk but no local centers. **Replaces** the choice between a product too bloated to trim and one you outgrow in a year. **Settings → Modules** Requires **ADMIN\_TENANT**. Every module settings route is guarded by `ROLE_ADMIN_TENANT`, and every save goes through `PATCH /tenants/{id}`, which the API only accepts from an admin of that same organization. Users and Profiles module page with the tab list on the left and the User Types and Roles settings section on the right *** ## How a module page works The Settings sidebar has a **Modules** group listing sixteen modules, then **All Modules** at the bottom for everything else. Press **Cmd+K** (**Ctrl+K** on Windows and Linux) anywhere inside Settings to search modules, tabs and individual settings by name; choosing a setting opens its page, scrolls to it and highlights it for a couple of seconds. Your last five searches are kept. Each page puts a sticky card on the left with the module name and its tabs, and the settings on the right. * **Enable X Module** is the first card on every Configuration tab. Switch it off and the rest of the page is replaced by "Module is currently disabled". * Tabs are tied to settings. Turn on **Enable Custom Statuses** in Events and an **Event Statuses** tab appears in the left card. * Flipping a switch saves about a second later and confirms with "Settings saved automatically" in the bottom right corner. Most pages have no Save button. The one exception is **Users & Profiles → Configuration**, which also carries a **Save All Settings** button in its sticky header. Individual switches there still save themselves as you flip them; the button writes the Users, Adhesion and Resignation blocks together in one request. *** ## Module reference Every module in the Settings sidebar, in the order it appears. | Module | What turning it on gives you | Tabs | | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | **Users & Profiles** | Member profiles, user types, roles, registration, family links, the member directory. Cannot be switched off: the toggle is permanently disabled. | Configuration, Custom Fields, Tags, Roles & User types, Registration Form, Profile Form, Adhesion Form, Adhesion Template, Referral Program, Registration Waitlist, Privacy Defaults, Security & Permissions | | **Contacts** | Records for people who are not members, contact statuses, and (with Local Centers on) contacts assigned to a chapter. | Configuration, Contact Statuses | | **Events** | Events, event types, event templates, reports, SDG tagging, attendance reminders, ticketing settings. | Configuration, Event Types, Templates, Event Statuses, Attendance Reminder | | **Discussions** | Discussions and comments, categories, the "who can post publicly" rule and the profanity hold queue. | Configuration, Discussion Categories | | **Groups & Teams** | Groups, role groups, organizational units, group tasks and the all-members group. The Local Centers module is configured from here too. | Configuration, Group Categories, Unit Types, Local Centers, Regions | | **Files & eDocuments** | Drive storage and optional personal drives. Its tabs also hold the Official Gazette and eDocuments modules. The sidebar entry only appears while Drive is on. | Drive, Official Gazette, eDocuments, eDocuments Templates | | **Emails & Notifications** | Email campaigns. Its tabs also hold notification defaults for new members, the system email switches and the email template editor. The page header reads "Notifications & Email Campaign". | Email Campaigner, Notification Preferences, Emails Config, Email Templates | | **Professions** | Industry, job and expertise fields on member profiles, plus a managed list of industries. | Configuration, Profession Industries | | **Payments & Fees** | Online payments for tickets, donations and products. Its tabs also hold membership fees and invoicing. | Online Payments, Payment Gateway, Membership fees, Donation Product, Invoice Product, Invoice Templates | | **Gamification & Courses** | Badges, badge categories, volunteer hours, points and tiers. Courses have their own switch on the Courses tab. | Gamification, Badges, Badge Categories, Courses | | **Helpdesk** | Member support tickets, a support team with per-member notification switches, issue statuses, issue types and default assignees. | Configuration | | **Projects** | Projects with tasks, boards and goals. | Configuration | | **Voting** | Votes and polls. | Configuration | | **Identity Validation** | Identity document upload and review, optionally required for members, for online payments, or both. | Configuration | | **Companies** | Company records, a rule for who may create them, and company-paid memberships. | Configuration | | **Form Builder** | Standalone forms for surveys, sign-ups and data collection. | Configuration | Several of those tabs only appear once their own setting is on. **Event Statuses** needs **Enable Custom Statuses**, **Attendance Reminder** needs **Enable Attendance Reminder**, **Group Categories** needs **Enable Group Categories**, **Unit Types** needs **Enable Organizational Units**, **Regions** needs Local Centers plus **Enable Regions**, **Contact Statuses** needs **Enable Contact Statuses**, **Discussion Categories** needs **Enable Discussion Namespaces**, **Profession Industries** needs **Enable Industry Tracking**, **Badges** and **Badge Categories** need Gamification on, **Invoice Templates** needs Invoices on, and the Users tabs for **Roles & User types**, **Registration Form**, **Adhesion Form**, **Adhesion Template**, **Referral Program** and **Registration Waitlist** each need their own feature switched on. **eDocuments Templates** is the odd one out: it leaves Settings and opens the eDocuments list in the main application. Requires **HR\_TENANT**. ### Where each module is documented * **Users & Profiles**: [Members](/docs/platform/users), [User types](/docs/platform/users/user-types), [Registration form](/docs/platform/users/registration-form), [Profile fields](/docs/platform/users/profile-fields), [Custom fields](/docs/platform/users/custom-fields), [Privacy settings](/docs/platform/users/privacy-settings), [Statuses](/docs/platform/users/statuses), [Family members](/docs/platform/users/family-members) * **Contacts**: [Contacts](/docs/platform/contacts) * **Events**: [Events](/docs/platform/events) * **Discussions**: [Discussions](/docs/platform/discussion) * **Groups & Teams**: [Groups](/docs/platform/groups), [Units](/docs/platform/groups/units), [Local groups](/docs/platform/groups/local-groups) * **Files & eDocuments**: [Files](/docs/platform/files), [Contracts](/docs/platform/contracts), [Official Gazette](/docs/platform/official-gazette) * **Emails & Notifications**: [Newsletter](/docs/platform/newsletter), [Notifications](/docs/platform/notifications) * **Payments & Fees**: [Membership fees](/docs/platform/fees/fees), [Products](/docs/platform/fees/products), [VAT](/docs/platform/fees/vat), [Stripe](/docs/platform/fees/stripe-integration), [Donations](/docs/platform/fees/donations) * **Gamification & Courses**: [Badges](/docs/platform/badges), [Courses](/docs/platform/courses) * **Helpdesk**: [Help desk](/docs/platform/help-desk), [Issues](/docs/platform/issues) * **Voting**: [E-voting](/docs/platform/e-voting) * **Identity Validation**: [Identity validation](/docs/platform/identity-validation) * **Companies**: [Companies](/docs/platform/users/companies) * **Adhesion, Referral, Waitlist, Resignation**: [Adhesion](/docs/platform/users/adhesion), [Referral](/docs/platform/users/referral), [Waitlist](/docs/platform/users/waitlist), [Resignation](/docs/platform/users/resignation) * **API & OAuth**: [API](/docs/platform/api), [OAuth](/docs/platform/oauth), [Integrations](/docs/platform/integrations) *** ## Modules configured somewhere else Several modules have no sidebar entry of their own. They are switched on from inside another module's page, or from **All Modules**. | Module | Where you switch it on | | ----------------------------------------------------- | ----------------------------------------------------------------------- | | Adhesion | Users & Profiles → Configuration → Adhesion & Membership | | Resignation | Users & Profiles → Configuration → Resignation & Membership Termination | | Referral | Users & Profiles → Referral Program | | Waitlist | Users & Profiles → Registration Waitlist | | Privacy defaults | Users & Profiles → Privacy Defaults | | Multi-Factor Authentication | Users & Profiles → Security & Permissions | | Local Centers | Groups & Teams → Local Centers | | Official Gazette, eDocuments | Files & eDocuments → the matching tab | | Membership fees, Invoices | Payments & Fees → Membership fees and Invoice Product | | Notification defaults, System emails | Emails & Notifications → Notification Preferences and Emails Config | | Courses | Gamification & Courses → Courses | | Languages | Customization → Languages | | Third-party integrations | Developers → Third-party Integrations | | Welcome message and default theme | Customization → Dashboard Welcome, and Organization → Branding | | API & OAuth, Analytics, Extra User Statuses, Realtime | All Modules only | Four of those deserve a note: * **API & OAuth** decides whether **API Tokens** and **OAuth Apps** appear in the Developers group. * **Analytics** turns the statistics dashboards on. Who may open each area (membership, geography, leaderboards, platform, finance) is set on **Users & Profiles → Security & Permissions**, not here. * **Extra User Statuses** is six independent switches (Suspended, Waiting list, Unreachable, Excluded, Helping hands, Contributor) deciding which optional statuses appear in the member status dropdown, member list filters and membership statistics. Open **Options** on the card to reach them. The card's own master switch gates nothing. * **Realtime** is on by default and drives live updates over Mercure in feeds, discussions, votes and networking. Switching it off does not break those screens, it just stops them refreshing on their own. *** ## The All Modules page **Settings → Modules → All Modules** shows every module as a card with a master switch, whether or not it has a page of its own. It is the fallback for anything the dedicated pages do not expose. All Modules page showing a search box and a View JSON Mode button above a grid of module cards, each with its name and an on or off switch The search box at the top matches both module names and the names of the settings inside them. The switch on a card saves immediately, except the Users card, which is deliberately locked on. Active modules with more than one setting get an **Options** button that expands every raw key as a switch, number box, text box or permission dropdown, with a **save** button underneath. **View JSON Mode** replaces the cards with a text editor holding the whole configuration as raw JSON. Saving invalid JSON is rejected with an error, but saving valid JSON with a wrong key or value is not: it is written straight through. Use the cards unless you are copying a known-good configuration. The Fees module card expanded on the All Modules page, showing its setting keys as switches, number boxes, text inputs and a permission dropdown, with save and cancel buttons underneath Two modules are hidden from this page on purpose, because editing them as raw keys causes more harm than good: **General** (welcome message and default theme) and **Integrations** (analytics IDs and single sign-on). Both have proper pages under Customization and Developers. The grid draws only the modules Orgo recognises. An organization set up years ago can still carry a key left over from an older release in its stored configuration; that key is skipped rather than drawn as a card of its own, so no module is listed twice. **View JSON Mode** shows the configuration as it is stored, leftover keys included. *** ## Dependencies worth knowing * **Event ticket settings** are greyed out until Online Payments is on. The page says so and offers a shortcut to enable it. * **Local center roles** such as `ADMIN_LOCAL` and `HR_LOCAL` only appear in permission dropdowns while Local Centers is on. * **Per-chapter contacts** and **Regions** both need Local Centers. * **Company fees** only appear on the Companies page while Membership fees is on. * **Enable Skills Field** creates a Skills custom field, seeded with a starter list, the first time you turn it on. Turning it back off keeps the values members already entered. * **Enable Weekly Availability** behaves the same way: existing values survive being switched off. * **Invoices** creates its invoice product for you the first time it is switched on, if you have not chosen one. *** ## Permission levels in module settings Many module settings are a dropdown of permission levels rather than a switch: who can create public events, who can send invitations, who can see member fee status. The list is `USER`, then the organization levels (`ADMIN_TENANT`, `HR_TENANT`, `FINANCIAL_TENANT`, `EVENT_TENANT`, `COMMUNICATION_TENANT`, `HR_ASSISTANT_TENANT`), then the chapter levels (`ADMIN_LOCAL`, `HR_LOCAL`, `FINANCIAL_LOCAL`, `EVENT_LOCAL`, `COMMUNICATION_LOCAL`, `HR_ASSISTANT_LOCAL`) when Local Centers is on. **Users & Profiles → Security & Permissions** collects every one of those dropdowns from every active module onto one page, grouped by module, alongside the MFA switch. See [Permissions](/docs/platform/permissions) for what each level unlocks. *** ## Troubleshooting Members carry a copy of your organization settings from when the app last booted in their browser. It refreshes on a full page reload, not on navigation inside the app, so a member who has left a tab open all day is working from the old copy. Ask them to refresh. Tabs are tied to settings. Check the Configuration tab for the switch that owns it: Event Statuses needs Enable Custom Statuses, Regions needs Enable Regions, Badges needs Gamification, and so on. Enable Local Centers first, from **Groups & Teams → Local Centers**. Online Payments is off. Turn it on from **Payments & Fees → Online Payments**, then come back. You need **ADMIN\_TENANT**. Without it the gear icon does not appear and the module routes bounce you to the login screen. No. The switch writes a flag on your organization and nothing else. Records stay in the database and reappear when you turn the module back on. *** ## Related * [Organization Settings](/docs/platform/organisation) for the four settings sections and what each one covers * [Organization Info](/docs/platform/organisation/organisation-info) for the details that flow into invoices, emails and public pages * [Branding](/docs/platform/organisation/branding) for logos, the login background and the default theme * [Permissions](/docs/platform/permissions) for what each permission level unlocks * [Customization](/docs/platform/customization) for languages, labels, menu and dashboard layout # Organization Info Source: https://orgo.space/docs/platform/organisation/organisation-info Your name, contact details, legal identity, currency and bank details: the record every invoice, email and registration page reads from. One form holds your organization's identity. Invoices, automated emails, registration pages and the member directory all read from it, so fill it in before you invite anyone. **Settings → Organization → Organisation info** Basic details card with organization name, short name, country, timezone, international organisation checkbox and default language Requires **ADMIN\_TENANT**. Open it from the cog icon in the top bar, or from your avatar menu, **Organisation Settings**. *** ## Basic details | Field | What it does | | --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Name** | Required. Shown in the sidebar, the browser tab, and as `organizationName` in emails. Rejects `<`, `>`, `{{`, `{%`, `javascript:`, `data:text/html` and inline event handlers with a "Display name contains characters that are not allowed" error. If Short Name is empty, it is filled with the same value. | | **Short Name** | Used where space is tight: browser tab title, sidebar and Drive labels, and the default sender name on a new newsletter. Same character rules as Name. | | **Country** | Sets the country line on invoices and the default country for member filters and the geography statistics map. | | **State** | Appears only when Country is United States. Sets the default drill-down state on the geography statistics map. | | **Timezone** | Type-to-search over the full IANA timezone list, shown with the current UTC offset. Becomes the default timezone for a new event when the organizer has no timezone of their own, and is passed to emails as `organizationTimezone`. If the field is empty when you open the form, it pre-fills with your browser's timezone and saves that value. | | **Is international organisation** | Relabels Country to **Country Headquarter** and switches the member directory, event attendance lists and geography statistics from state-level filters within your country to country-level filters worldwide. | | **Default language** | The interface language for anyone who has not set their own, and the language of server-sent emails. | Picking a **Default language** switches your own interface immediately, before you save. If you change your mind, pick the old one back and leave without saving. Two rules govern language. In the app, a member's own language wins, unless the Languages module is off, in which case the organization default overrides it; a `?lang=` parameter in the URL beats both; anything unavailable falls back to English. Server-sent email is narrower: templates render in Romanian, English or German only, and any other default language falls back to English. *** ## Contact information Contact card with office email, office phone country selector and number, and office address | Field | What it does | | ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------- | | **Office Email** | Required. The Reply-To on automated email, the contact address printed on invoices, and the organizer address on event calendar invitations. | | **Office Phone** | Pick the country code first: the number box stays disabled until you do, then shows a sample number for that country. Printed on invoices. | | **Office Address** | Printed in the organization block on every invoice. | Automated email is sent **from** `no-reply@orgo.space` and replies go to your Office Email. Orgo only sends from your own address once the sending domain has been verified, which happens as part of [Custom Domain](/docs/platform/custom-domain) setup. Changing Office Email on this page does not change the From address on its own. *** ## Legal links Three URL fields: **Privacy/GDPR URL**, **Terms of service for members, page URL** and **Internal rules, page URL**. Each URL you fill in adds a **required** consent checkbox to the registration form. A member cannot finish signing up without ticking it. The GDPR and Terms links do the same on the event checkout. Leave a field blank and no checkbox is shown. *** ## Social media URLs Social media card with Facebook, X.com, Youtube, Linkedin, Instagram and Tiktok URL fields Six fields: Facebook, X.com, Youtube, Linkedin, Instagram and Tiktok. Paste the full URL. Orgo stores them on the organization record and returns them in the tenant payload the API serves, but no built-in page or email template renders them, so treat them as data for your own integrations rather than as links members will see. *** ## Financial details Financial card with currency and symbol, legal name, registration number, VAT number and the bank IBAN block | Field | Where it shows up | | ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Currency** | Default currency for membership fee payments and for any product price that does not set its own. Choosing one rewrites **Symbol** with the narrow symbol for that currency; you can type over it. | | **Legal Name** | Printed as the organization name on invoices, falling back to Name when empty. Also the account holder on bank transfer instructions. | | **Registration Number** | Printed as the `Reg:` line on invoices. | | **VAT Number** | Printed as the `VAT:` line on invoices. | | **BANK IBAN** | The first field carries your currency code as its label. This is the only IBAN the product uses: it appears on bank transfer instructions, on the member fee payments page when **Allow Bank Transfer Payments** is on (Settings → Modules → Payments & Fees), and in the payment proof PDF. | Below it, Orgo renders one field each for USD, EUR and CHF, skipping whichever of the three your own currency has already claimed as the first field. So an organization on USD sees three boxes in total, labelled USD, EUR and CHF, while one on RON sees four. These extra fields are stored for your own record keeping. Nothing in the product prints them. Set these before you take a payment. Invoices and receipts store the values as they were when the document was generated, so later edits do not correct documents already issued. *** ## Saving Page header showing organization name, Stripe account tag, workspace slug tag and the Save button **Save** sits in a panel on the right that follows you as you scroll. **Name** and **Office Email** are required and the form will not submit while either is empty. The header carries two read-only badges: your connected Stripe account id, if there is one, and your workspace identifier in the form `slug-id`. The slug is fixed when the workspace is created, taken from the subdomain you chose at signup or derived from the name if you did not choose one, so it does not necessarily resemble your organization's current name. It is unique across Orgo and appears in links as `?workspace=`. It cannot be edited here. *** ## Troubleshooting Choose a country from the dropdown to its left first. Changing the country afterwards clears the number. It only renders when Country is United States. Pick United States and it appears under the country selector. Choosing a **Default language** loads that language straight away so you can preview it. Nothing is stored until you save. That is the default sender for every workspace. Your Office Email is used as the Reply-To. Sending from your own domain requires domain verification, which is part of [Custom Domain](/docs/platform/custom-domain) setup. Name or Office Email is empty; the browser blocks the submit and highlights the field. Only ADMIN\_TENANT can save this form, and only for their own organization. Sent emails and generated invoices keep the values they were built with. New documents pick up the new name. Members may also need to reload the app. *** ## Related * [Organization Settings](/docs/platform/organisation) overview of the whole settings area * [Branding](/docs/platform/organisation/branding) logos and login background * [Modules](/docs/platform/organisation/modules) turn platform features on and off * [Custom Domain](/docs/platform/custom-domain) your own address and verified email sending * [Languages](/docs/platform/customization/languages) the languages members can choose from # Public Website Source: https://orgo.space/docs/platform/organisation/public-website A public front page, chapter directory and events listing that anonymous visitors reach before they ever see a login screen Orgo ships a small public website that sits in front of the members' area: a homepage, a directory of your local centers, a page per local center, and a public events listing. Nobody has to sign in to see any of it. One setting decides whether a first-time visitor who types your address lands there or on the sign-in screen. **Built for** organizations whose address is handed out to people who are not members yet, including federations recruiting chapters, associations with an open events programme, and anyone whose "join us" link currently opens a login box. **Replaces** a separate brochure site you would otherwise host, keep in sync, and re-key every chapter and event into. **Settings → Modules → Users & Profiles → Configuration → Advanced Settings** Requires **ADMIN\_TENANT**. The setting is written through the tenant record, and the server checks both the role and that the tenant is your own, so the menu is not the only thing standing in the way. Public website homepage with the organization logo and About, Chapters, Events, Donate and Newsletter navigation across the top, a Login and Become a member button pair, and a centred hero holding an eyebrow badge, headline, sub-headline, Become a member and Donate buttons and three statistics *** ## The four pages All four exist and are reachable the moment your community does, whether or not you turn on the front door. They share one header and footer, both drawn from your organization. | Address | What it shows | | ------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | | `/homepage` | The front page: hero, about, a map of your local centers, your next three public events, a donation block and a newsletter sign-up | | `/chapters` | Every active local center as a card, with its town, a short description and a link through to its own page | | `/chapter/` | One local center: description, a map of where it meets, languages, meeting days, contact email and phone, social links | | `/community-events` | Your public events listing, embedded whole | The header carries your logo, links that scroll to each homepage section, a **Login** button and a **Become a member** button that opens your registration form. The footer repeats those links and prints your organization's contact email, name and the current year. Your logo is used if you have uploaded one under [Branding](/docs/platform/organisation/branding); without one, the header prints your organization's name as plain text. *** ## Turning it on **Settings → Modules → Users & Profiles**, stay on **Configuration**, and scroll to the **Advanced Settings** card at the bottom. Enter `/homepage`. It must begin with a forward slash. The field saves itself about a second after you stop typing, and a **Settings saved automatically** toast confirms it, so there is nothing to press. Open your community address in a private window or a browser you are not signed into. You should land on the public homepage instead of the sign-in screen. Signing out and reloading is not the same test: what changes is where a visitor with no session is sent. Users and Profiles module settings with the Advanced Settings card open, showing the Use Custom Dashboard switch, the empty Custom Homepage Route field and the Anonymous Homepage URL field holding /homepage | Setting | What it does | | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Anonymous Homepage URL** | Where a visitor with no session is sent when they open your bare address. Must be a **path**, starting with `/`. Empty by default, which sends them to the sign-in screen | | **Custom Homepage Route** | Where a **signed-in member** lands instead of the dashboard. Accepts a path or a Vue route name. It has no effect on visitors who are not signed in | | **Use Custom Dashboard** | Unrelated to the public site: it swaps the members' dashboard for the widget layout | The two homepage fields sit next to each other and do **not** accept the same thing. **Anonymous Homepage URL** takes a path only. **Custom Homepage Route** also takes a route name. Typing `Homepage` into Anonymous Homepage URL therefore does nothing visible in the settings screen and quietly sends every anonymous visitor to the sign-in page, because a value with no leading slash is discarded and the sign-in screen is the fallback. Write `/homepage`, not `Homepage`. The redirect only fires on your bare address. A visitor who follows a deep link into the members' area, say to a member profile, still meets the sign-in screen, which is the point. *** ## What is on the homepage A hero and five sections, stacked. The header links scroll between them. **About.** Three fixed pillars describing the shape of the organization. **Chapters.** A map with a pin on each active local center, and a **See all chapters** button through to the directory. The pins come from the map location on each local center, so a center with no coordinates is simply absent from the map. Find a chapter near you section showing a map of the organization's local centers with a pin on each one and a See all chapters button underneath **Events.** Your next three public events, soonest first, each linking to its own [public event page](/docs/platform/events/public-page). **See all events** opens the full listing. With nothing upcoming the section says so and points at the newsletter form rather than sitting empty. Upcoming events section showing three event cards with cover images, dates, titles and locations, above a See all events button **Donate.** Appears only when you have set a default donation product. It loads the same donation widget you can embed elsewhere, which is what adds the floating **Donate Now** button in the corner, and it adds a **Donate** link to the header and a **Donate** button to the hero. Without that product the whole section, the header link and the hero button are gone. See [Donation Pages & Widgets](/docs/platform/fees/donation-pages). **Newsletter.** An email field. Submitting it sends a confirmation email to that address; only when the link in it is clicked does the address become a subscriber, as a contact if it is not already a member. Unconfirmed sign-ups never reach your list. See [Newsletter signup widgets](/docs/platform/newsletter-widgets). *** ## What is yours and what is fixed This is a template, not a page builder. Knowing which half is which saves a long search for an editor that does not exist. **Drawn from your organization:** the logo, the organization name, the contact email in the footer, the interface language, your local centers and their descriptions, coordinates, languages, meeting days and contact details, your public events and their cover images, your donation product, and your newsletter. **Fixed in the product, the same for every organization:** the hero headline and sub-headline, the three statistics under it, the About pillars, every section heading and sub-heading, and the footer tagline. They are written in the general voice of a community organization and cannot be edited from Settings today. If that copy does not fit you, the honest options are to leave the front door on the sign-in screen and point your public traffic at a site you control, or to talk to support. *** ## Search engines and your address While your community runs on an `orgo.space` address, every page is served with a `noindex, nofollow` instruction, so search engines are told to skip the public site along with everything else. That is deliberate: it keeps members' area URLs out of search results. The instruction is tied to the address, not to the pages. Move your community onto a domain you own and it stops being added, which is what makes the public site indexable. Set that up under [Custom Domain](/docs/platform/custom-domain) before you promote these pages anywhere. *** ## Troubleshooting Almost always a missing leading slash. `/homepage` works, `homepage` and `Homepage` do not, and neither reports an error. Confirm the field reads exactly `/homepage`. If it does, check you tested the bare address in a private window: the redirect only applies to the bare address, and only to a visitor with no session. The path is right in shape but wrong in spelling, so it matches no page and falls through to the 404 screen. The four valid paths are `/homepage`, `/chapters`, `/chapter/` and `/community-events`. Almost every case is a typo in `/homepage`. The map plots the map location saved on each local center. A center with no coordinates, or one that is not active, does not appear. Fill in the map location on the chapter's own form, under [Local Centers](/docs/platform/groups/local-groups). The directory at `/chapters` is a separate list and does show a center with no coordinates, so a chapter visible in the list but absent from the map is missing its location. The section only shows events that are both public and in the future. An event that is not marked public is invisible here even to members who are signed in elsewhere. See [Sharing Events](/docs/platform/events/sharing). The donation block, the header link and the hero button all hang off one thing: a default donation product on the organization. Set one up under [Donation Pages & Widgets](/docs/platform/fees/donation-pages) and all three appear together. A display fault, not corrupted data. When a local center has a **Region** assigned, the directory card and the chapter page print the region as a placeholder instead of its name. Nothing else is affected, the region itself is stored correctly, and clearing the Region field on that chapter removes the stray text at the cost of losing the region grouping elsewhere. Report it to support rather than editing your data around it. `/community-events` embeds your public events listing rather than redrawing it, and the embedded list can come up blank while the calendar beside it still marks the dates. Open the events listing directly to confirm your events are there and reachable. Until it settles, link people to the homepage Events section, which builds its cards independently and is unaffected. Signing in takes them to the dashboard as usual. What keeps bringing a member back to the public site is a bookmark saved on one of these four pages, since they stay open to everyone. Ask them to open the bare address rather than the bookmark. If signed-in members are landing somewhere other than the dashboard, that is **Custom Homepage Route**, in the same settings card, not this feature. Expected while you are on an `orgo.space` address: those pages are served with a `noindex` instruction. Move to a domain you own under [Custom Domain](/docs/platform/custom-domain) first, then submit the address to the search engine. *** ## Related * [Custom Domain](/docs/platform/custom-domain) - Serve the site from an address you own, and make it indexable * [Branding](/docs/platform/organisation/branding) - The logo the site's header and footer use * [Local Centers](/docs/platform/groups/local-groups) - The chapters behind the map and the directory * [Sharing Events](/docs/platform/events/sharing) - What makes an event public enough to appear here * [Donation Pages & Widgets](/docs/platform/fees/donation-pages) - The donation product the Donate section needs * [Newsletter signup widgets](/docs/platform/newsletter-widgets) - Where the newsletter form's subscribers land * [Permissions](/docs/platform/permissions) - What ADMIN\_TENANT unlocks # Organizational Chart Source: https://orgo.space/docs/platform/organisational-chart A live map of who holds which position, built from your roles and their assignments The Organizational Chart draws your leadership structure from the roles you have defined and the members currently assigned to them. Nothing is drawn by hand: each box is a role, the number on it is how many active members hold it right now, and clicking it lists them. **Built for** organizations with named positions (president, treasurer, chapter coordinator, unit leader) that members and staff need to look up. **Replaces** the hand maintained org chart slide that is out of date the week after someone is elected. Organizational chart with Central, Parent local centers, Chapters and Team sections, each role shown as a box carrying the photos of its holders in the Central section and the number of members holding it elsewhere *** ## Turning it on **Settings** → **Modules** → **Users & Profiles** → **User Types & Roles** → **Enable Roles**. This is on by default. **Settings** → **Modules** → **Users & Profiles** → **Profile Settings** → **Organizational Chart**. This is off by default. Members open it from the sidebar under **Organization** → **Organisational Chart**. The menu entry only appears when both settings above are on. Both settings require `ADMIN_TENANT`. Once the chart is visible, every signed in member of your organization can open it. There is no anonymous or public version of the chart, and no per group visibility setting. *** ## How the chart is built Roles carry a **level** and a **position number**, and those two properties are the whole layout. The level decides which section a role lands in: | Section heading | Roles shown | Shown when | | ------------------------- | ----------------------------------------- | -------------------------------------------------------- | | **Central** | Roles set to the **Organisation** level | Always | | **Parent local centers** | Roles set to the **Parent chapter** level | Local centers are active and parent chapters are enabled | | **Chapters** | Roles set to the **Chapter** level | Local centers are active | | One section per unit type | Roles attached to that unit type | The unit type exists | The chart has these two chapter sections and no more, whatever the shape of your chapter tree. Chapters nest to any depth, but a role is either a chapter role or a parent-chapter role, so a district commissioner and a national officer at parent-chapter level land in the same **Parent local centers** section. The chart does not draw the layers of the tree; use the chapters list for that. The position number decides the row. Roles are grouped in blocks of one hundred: positions 0 to 99 form the first row of a section, 100 to 199 the second, and so on. Roles with no position number are placed in a final row at the bottom of their section. Empty rows are hidden unless you are editing. User types do not appear on the chart. They are a different kind of role (they describe what a member *is*, not a position held) and they are excluded from both the layout and the counts. ### What the numbers mean The count on a box is the number of assignments that are still open (no end date) held by members whose account status is **Active**, across the whole organization. Ending a member's role or deactivating their account removes them from the count on the next page load. In the **Central** section a box that has holders shows their photos instead of the number: up to three, stacked, each one linking to that member's profile, with `+N` beside them when more than three people hold the role. Boxes in the other sections show the number itself. A box with no holders is greyed out and cannot be clicked. *** ## Looking someone up Click a role box that has at least one holder to open the member list. Role member list showing the role name and holder count, a chapter filter, and rows with member name, group and date | Column | What it shows | | ---------- | ---------------------------------------------------------------------------------------------------------------- | | **Member** | Name and photo, linking to the member profile | | **Group** | The chapter or unit the assignment belongs to. Hidden for Organisation level roles, which are not tied to a unit | | **Date** | When the assignment was recorded | For chapter and parent chapter roles a dropdown at the top filters the list to one chapter, with a search box for organizations that have many. The list pages at 100 members at a time. *** ## Editing the structure Administrators with `ADMIN_TENANT` see an **Edit Positions** button. Everyone else sees a read only chart. Chart in edit mode showing Add level buttons, plus buttons on each row, a pencil on every role box and a drag handle at the end of each row In edit mode you can: * **Add level**, which appends an empty row to a section * **+**, which opens the role form with the section and row prefilled * Drag a role box onto another row or another section to move it, or onto another box to swap the two * Drag a whole row by its handle to reorder rows within a section * Click a role box to open its form, edit it, or delete it Deleting a role that still has members assigned to it is refused, with the message "Cannot delete role because it has users assigned to it". End the assignments first. The **Roles** button in the top right opens the full role list at **Settings** → **Modules** → **Users & Profiles** → **Roles & User types**. ### The role form | Field | What it does | | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | | **Title** | The role name, and the label on the chart box | | **Plural title** | Used where the product lists several holders | | **Level** | None, User type, Chapter, Parent chapter, Organisation, or a unit type. This is what places the role on the chart. A role set to **None** is not drawn | | **Permissions** | Checkboxes grouped as Organisation level, Local group level and Parent local center level. Members holding the role inherit them | | **URL Slug** | User types only. Used for the `/join/[slug]` registration URL | User types additionally expose **Not eligible for fee**, **Parent**, **Volunteer**, and font and background colours. Selecting the User type level clears any permissions on the role: user types never carry permissions. Permissions on a role are real access, not decoration. Adding `ADMIN_TENANT` to a role grants full administrative access to everyone holding it. See [Permissions](/docs/platform/permissions) before editing this field. *** ## Putting people on the chart Assignments are made on the member, not on the chart. Open a member, go to the **Roles** tab, and tick the roles they hold. | Role level | Permission needed to assign | | -------------- | ----------------------------------------- | | Organisation | `HR_TENANT` | | Parent chapter | `HR_PARENT_LOCAL` on the member's chapter | | Chapter | `HR_LOCAL` on the member's chapter | A parent-chapter assignment is filed against the member's own chapter when that chapter is flagged **It's a parent chapter**, and otherwise against the chapter directly above it. It is never filed further up, so a district officer's parent-chapter role stays with the district rather than moving to the region. The tab itself appears for `HR_TENANT`, or for `HR_LOCAL` on that member's chapter. When **Allow Local Admins to Modify User Permissions** is turned off, local administrators can see the tab but the checkboxes are read only, and only `HR_TENANT` can change assignments. A chapter's own page also shows its team, grouped by role in the same position order as the chart. *** ## Common questions A section only renders when at least one role is set to that level. Open **Edit Positions**, check that your roles have the right level, and confirm the chapter sections require local centers to be active. No member currently holds it with an open assignment and an active account. Boxes with no holders cannot be clicked. Their assignment has no end date. Open their profile, go to **Roles**, and untick the role. The count updates on the next load of the chart. No. The chart is only reachable by signed in members of your organization. Rows are blocks of one hundred position numbers. Use **Edit Positions** and drag one role down to another row, or add a level and drag it there. *** ## Related * [Permissions](/docs/platform/permissions) - what each permission on a role unlocks * [Assigning permissions](/docs/platform/permissions-assigning) - roles, role groups and direct permissions * [Members](/docs/platform/users) - member profiles and the Roles tab * [Local groups](/docs/platform/groups/local-groups) - chapters and their teams * [Official Gazette](/docs/platform/official-gazette) - the record of decisions your officers publish # Orgo Support Source: https://orgo.space/docs/platform/orgo-support The support chat inside your workspace: who sees it, who answers it, and what Orgo can see **Built for** organization admins with a question about Orgo itself. **Replaces** writing to [support@orgo.space](mailto:support@orgo.space) and waiting for a reply in your inbox. A chat launcher sits in the corner of the app for organization admins. It reaches Orgo, not your members. This is the opposite direction to the [Help Desk](/docs/platform/help-desk), which is where your own members write to you. *** ## Turning it on Nothing. There is no module to enable and no setting to configure. The launcher appears for the people described below and for nobody else. *** ## Who sees it | Who | Sees the launcher | | ----------------------------------------------------------------------- | ----------------- | | Holders of `ADMIN_TENANT` in your organization | Yes | | Orgo's own administrators and super admins | Yes | | Chapter and local admins (`ADMIN_LOCAL`, and the parent-chapter levels) | No | | Every other member | No | Members never see it, so it is not a route for them to reach you. Give them the [Help Desk](/docs/platform/help-desk) instead. *** ## Where it appears * Inside the signed-in workspace, on any page. * On desktop only. It is hidden at phone widths, so an admin looking for it on their phone will not find it. * Not on the login or register screens. You have to be signed in, which means a member who cannot sign in cannot use the chat to say so: they need [support@orgo.space](mailto:support@orgo.space), or you on their behalf. * Not in the [Event App](/docs/platform/events/event-app), which has its own separate sign-in and is meant for attendees. The launcher disappears while you are impersonating another member, so a question you raise is never attributed to the person whose account you were viewing. Stop impersonating first. *** ## Who answers **An AI agent answers first.** Fin is Orgo's agentic AI support assistant. It reads your question, works out what you are trying to do, and answers from the same documentation you are reading now, citing the pages it used so you can check them. It handles follow-up questions in context, so you can keep the conversation going rather than starting again. A real answer. The question was typed with a typo and still understood, the reply sets out each route in order, and the small numbers beside the steps are citations back to the documentation pages the answer came from. The Orgo Support chat open, headed Orgo Support with the subtitle The team can also help. An administrator has asked How can i register new members, and the AI has replied with four numbered routes: add them manually through the Member Directory using Register member, let them sign up themselves by enabling the Registration Form and sharing the register link, invite them by email, or create a user account from an existing contact record. Each route carries a small numbered citation back to a documentation page. Below the answer the assistant asks Is that what you were looking for, and the composer at the foot of the panel is labelled Powered by Fin Anything it cannot resolve is handed to a person on the Orgo support team, in the same conversation. You do not have to ask for the handover or repeat yourself, and the person picking it up can see what you already asked. You are talking to an AI first, and it will say so. If you would rather have a person, ask for one and the conversation is passed on. Treat its answers the way you would treat any assistant's: it is reliable on documented behaviour and worth double checking on anything specific to your own configuration or data, because it cannot see inside your workspace. *** ## What Orgo can see Opening the chat passes a small amount of context so that support knows who is writing and from which organization: | Shared | Not shared | | --------------------------------- | ------------------------------------------ | | Your name and email address | Any of your members' records | | The date your account was created | Their names, emails, payments or documents | | Your interface language | Anything held inside your workspace | | Your organization's name and plan | | The chat carries the account you are signed in as and the organization you are in. It does not give the support team a way to read your data. *** ## Common questions Direction. This chat is you writing to Orgo about the platform. The [Help Desk](/docs/platform/help-desk) is a ticket board inside your workspace where your members write to your own admins. They share nothing: a ticket raised in the Help Desk never reaches Orgo, and a message in this chat never appears on your ticket board. Expected. It is limited to `ADMIN_TENANT`, so chapter-level admins do not get it however wide their local permissions are. Either raise the question yourself, or write to [support@orgo.space](mailto:support@orgo.space). It is desktop only. Open the workspace on a computer, or email [support@orgo.space](mailto:support@orgo.space). Do it from your own account, not while impersonating theirs: the launcher is hidden during impersonation, and a question raised that way would carry the wrong identity. No. Only your own name, email, account creation date and interface language reach the conversation, along with your organization's name and plan. Member records are never part of it. *** ## Related * [Help Desk](/docs/platform/help-desk) - the other direction: your members writing to you * [Permissions](/docs/platform/permissions) - what `ADMIN_TENANT` covers * [Troubleshooting Access](/docs/platform/users/troubleshooting-access) - sign-in problems you can solve without support # Permissions Source: https://orgo.space/docs/platform/permissions Comprehensive guide to the permission system and access levels A permission grants access to a part of Orgo. Every permission is a pair: a **domain** (what area of the platform) and a **scope** (whose data). `HR_LOCAL` means member management, limited to one chapter. `FINANCIAL_TENANT` means money, across the whole organization. **Built for** organizations that delegate admin work across chapters, regions, or committees: professional associations, alumni networks, trade unions, and faith communities where different people manage different areas at different levels. **Replaces** shared admin logins and informal trust-based access. Permissions are not the same as [roles and user types](/docs/platform/users/user-types). A role like "President" is an organizational position; it grants access only if you attach permissions to it. *** ## Two separate things grant access Orgo has one account-level flag and one permission set, and they are not interchangeable. | | What it is | Where it is set | | ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | | **Orgo administrator** | An account flag on a member. Screens that configure the organization itself (Settings, modules, branding, imports, workflows, email templates) check for this flag, not for a permission. | The **Orgo administrator** switch at the top of a member's **Permissions** tab. Only a member who already holds it can see the switch. | | **Permissions** | The domain and scope grants described on this page. They govern everyday administrative work: members, fees, events, campaigns. | The permission checkboxes on the same tab, or attached to a role. | Granting the `ADMIN_TENANT` permission is not the same as making someone an Orgo administrator. `ADMIN_TENANT` passes every permission check in the product, but the organization Settings screens still require the Orgo administrator flag. If an admin reports that Settings is missing, this is almost always why. *** ## The six domains | Domain | UI label | What it unlocks | | ----------------- | --------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **ADMIN** | Admin | Everything in the other five domains at the same or lower scope, plus chapter settings, the waitlist, badges and badge types, roles, profile statuses, event types and statuses, invoices, API tokens and OAuth apps, and the email log | | **HR** | HR | Member profiles and their **Permissions** and **Roles** tabs, adhesions, resignation requests, chapter transfer requests, member exports and bulk actions, merging duplicates, e-documents, creating and editing gazette entries, the form builder | | **HR\_ASSISTANT** | HR Assistant | Awarding badges and logging badge hours, viewing admin-only custom fields, reviewing identity documents on a member profile, and (at organization scope) seeing members who hide themselves from the directory and map | | **FINANCIAL** | Financial | Products and product payments, subscribers, membership fee records and fee statistics, chapter fee settings, chapter online payment settings, your organization's own Orgo billing page | | **EVENT** | Event Manager | Creating events beyond the level set in **Settings → Events**, plus the organizer-only options on the event form: ticketing and payment fields, gamification tiers, restricting an event to one user type, and propagating an event to chapters | | **COMMUNICATION** | Communication Manager | Email campaigns, campaign templates, lists and segments, newsletter signup widgets, the discussion moderation queue | Sidebar menu entries are only entry points: individual actions inside a screen can require more, and a few require the Orgo administrator flag instead. ### Automatic inclusions Holding one permission can imply another. This is the complete list; nothing else is implied. | Holding this | Also grants | | ---------------------------- | ------------------------------------------------------------------------------ | | `ADMIN_TENANT` | Every permission check in the product | | `HR_TENANT` | `HR_ASSISTANT_TENANT` | | `FINANCIAL_TENANT` | `HR_ASSISTANT_TENANT` | | `HR_PARENT_LOCAL` | `HR_LOCAL`, `HR_ASSISTANT_LOCAL` | | `HR_LOCAL` | `HR_ASSISTANT_LOCAL` | | `FINANCIAL_PARENT_LOCAL` | `FINANCIAL_LOCAL`, `HR_ASSISTANT_LOCAL`, `HR_ASSISTANT_PARENT_LOCAL` | | `FINANCIAL_LOCAL` | `HR_ASSISTANT_LOCAL` | | `EVENT_PARENT_LOCAL` | `EVENT_LOCAL` | | `COMMUNICATION_PARENT_LOCAL` | `COMMUNICATION_LOCAL` | | `ADMIN_PARENT_LOCAL` | Every local and regional permission within the same branch of the chapter tree | | `ADMIN_LOCAL` | Every local permission within the same chapter | `HR_TENANT` does **not** imply `HR_LOCAL` as a separate grant. It does not need to: an organization-scope permission satisfies any check in the same domain at regional or local scope. Regional and local grants are the ones that need the chapter to match. *** ## The three scopes | Scope | Suffix | Whose data | | ------------ | --------------- | ----------------------------------------------------------- | | Organization | `_TENANT` | Everything in the organization | | Regional | `_PARENT_LOCAL` | One anchor chapter and every chapter below it, at any depth | | Local | `_LOCAL` | The member's own chapter | An organization-scope permission always satisfies a check for the same domain at regional or local scope. The reverse is never true. Regional and local scopes exist only when the **Local Centers** module is on, and regional scope also needs **Enable Parent Centers**. Without them, the only checkboxes shown are the organization-scope ones. ### What "regional" means when chapters nest Chapters chain to any depth, so regional scope is defined by an anchor chapter rather than by a fixed layer. The anchor comes from the holder's own primary chapter and cannot be pointed elsewhere: | The holder's own chapter | The anchor | | --------------------------------- | ----------------------------- | | Flagged **It's a parent chapter** | That chapter itself | | Has no parent at all | That chapter itself | | An ordinary chapter with a parent | The chapter directly above it | The grant then covers the anchor and every chapter beneath the anchor, however many layers down. It never reaches the chapter above the anchor and never crosses into another branch. A district officer whose district is flagged as a parent chapter therefore administers the district and its branches, and not the region above it. The full worked example is on [Local Groups](/docs/platform/groups/local-groups#what-a-parent-scope-permission-reaches). Nesting widens administrative reach only. What an ordinary member without a regional permission can see did not change: their own chapter, the chapter directly above it, and the chapters sharing that same direct parent. It does not follow the chain further up. Reading another member's User and Admin custom field values still requires being in the same chapter exactly, with no walk up the tree. *** ## Complete permission reference Twenty permissions exist. The UI shows them as six labels repeated under three headings: **Organization: (your organization)**, **Chapter: (chapter name)** and **Parent chapter: (region name)**. | Permission | Shown as | Shown when | | ---------------------------- | -------------------------------------- | ----------------------------------------------------- | | `ADMIN_TENANT` | Admin (Organization) | Always | | `HR_TENANT` | HR (Organization) | Always | | `HR_ASSISTANT_TENANT` | HR Assistant (Organization) | Always | | `COMMUNICATION_TENANT` | Communication Manager (Organization) | Always | | `FINANCIAL_TENANT` | Financial (Organization) | Fees module on | | `EVENT_TENANT` | Event Manager (Organization) | Events module on | | `ADMIN_PARENT_LOCAL` | Admin (Parent chapter) | Parent centers on | | `HR_PARENT_LOCAL` | HR (Parent chapter) | Parent centers on | | `HR_ASSISTANT_PARENT_LOCAL` | HR Assistant (Parent chapter) | Parent centers on | | `FINANCIAL_PARENT_LOCAL` | Financial (Parent chapter) | Parent centers on | | `EVENT_PARENT_LOCAL` | Event Manager (Parent chapter) | Parent centers on | | `COMMUNICATION_PARENT_LOCAL` | Communication Manager (Parent chapter) | Parent centers on | | `ADMIN_LOCAL` | Admin (Chapter) | Local centers on | | `HR_LOCAL` | HR (Chapter) | Local centers on | | `HR_ASSISTANT_LOCAL` | HR Assistant (Chapter) | Local centers on | | `FINANCIAL_LOCAL` | Financial (Chapter) | Local centers on | | `EVENT_LOCAL` | Event Manager (Chapter) | Local centers on | | `COMMUNICATION_LOCAL` | Communication Manager (Chapter) | Local centers on | | `USER` | Regular user | Not assignable; used by minimum access level settings | | `USER_LOCAL` | Regular user | Not assignable; used by minimum access level settings | `USER` and `USER_LOCAL` mean "any signed-in member". They never appear as checkboxes on a profile, only as the lowest option in the minimum access level dropdowns below. *** ## How a check is decided Orgo works through these steps in order. If the record belongs to a different organization than you, access is denied. No permission overrides this. If you are an Orgo administrator or hold `ADMIN_TENANT`, access is granted. This shortcut is skipped for the restricted sessions listed further down. Your permissions are expanded using the automatic inclusions above, then matched against what the action requires. For a local permission the record's chapter must be your own chapter, your anchor chapter, or a chapter you were separately granted through **Multi local center access**. For a regional permission it must sit inside your anchor's branch, at any depth. If **Restrict events by user type** is on and the event names an allowed user type, a regional or local manager whose user type does not match is denied, even with the right permission. Lists apply the same rules when they load, so a chapter HR manager opening the member directory sees their chapter's members, not an error. *** ## Minimum access levels Some behaviour is not a permission you hold but a bar your organization sets, at **Settings → Users & Profiles → Security & Permissions**. It lists every switched-on module and the permission level each one requires. | Setting | Default | Controls | | ----------------------------------------------------- | ------------ | ---------------------------------------------------------------- | | **Minimum access level** (Analytics) | Regular user | Opening the analytics area at all | | **Membership** (Analytics) | HR | The membership section of analytics | | **Geography** (Analytics) | Regular user | The geography section | | **Leaderboards** (Analytics) | Regular user | The leaderboards section | | **Platform** (Analytics) | Admin | The platform usage section | | **Finance** (Analytics) | Financial | The finance section | | **Who can create public posts** (Discussions) | Regular user | Starting a discussion in the whole community rather than a group | | **Who can create public posts** (Drive) | HR | Uploading to the community drive rather than a group's | | **Who can create public posts** (Events) | HR | Publishing an event to the whole community | | **Who can see user fee status** (Fees) | Regular user | Seeing whether another member's fee is paid | | **Who can create** (Groups) | Regular user | Creating a group | | **Who can see members in general unit group** (Users) | Regular user | Browsing the full member directory | | **Who can see members in local center** (Users) | Regular user | Browsing a chapter's members | | **Who can see user type** (Users) | Regular user | Seeing another member's user type | The same screen carries **Enforce MFA for administrators**. With it on, administrators must enter a code sent by email and are asked again every 48 hours. Security and Permissions settings page with the Enforce MFA for administrators switch and per-module minimum access level dropdowns *** ## Sessions that carry fewer permissions Four situations narrow a session below what the member actually holds. In all four the organization administrator shortcut is switched off. * **Permission impersonation.** An administrator previews the product as a lower permission set. See [Assigning Permissions](/docs/platform/permissions-assigning). * **Event app sign-in.** A ticket holder or host signing in with a one-time email code gets member-level access plus the Event Manager family only. Organization-wide administration is never reachable that way, even for an administrator. * **Scoped API tokens.** A token is limited to the categories chosen when it was created, and cannot inherit the organization administrator shortcut. See [API](/docs/platform/api). * **Connected apps.** An app acting with its own credentials is capped at plain member access. *** ## Related * [Assigning Permissions](/docs/platform/permissions-assigning) - who may grant what, and how to test it * [User Types & Roles](/docs/platform/users/user-types) - positions you can attach permissions to * [Role Groups](/docs/platform/groups/role-groups) - groups that fill themselves from roles * [Modules](/docs/platform/organisation/modules) - the switches that make permissions visible * [Local Groups](/docs/platform/groups/local-groups) - chapters, parents, and what local scope means # Assigning Permissions Source: https://orgo.space/docs/platform/permissions-assigning Who to give which permission, how to assign it, how to test it, and how to audit who holds what Working with permissions day to day. For what each domain and scope actually controls, see [Permissions](/docs/platform/permissions). *** ## Where a member's permissions come from A member's effective permissions are the union of three sources, recalculated whenever a role or a checkbox changes. Only active roles count: a role with an end date in the past contributes nothing. | Source | Set where | Best for | | ------------------------ | -------------------------------------------------------------------- | ------------------------------------------------------------------ | | **Role** | Permissions attached to a role, then the role assigned to the member | Ongoing responsibilities. Ending the role removes the permissions. | | **Direct** | Checkboxes on the member's **Permissions** tab | One-off exceptions that do not match any role. | | **Multi chapter access** | The **Roles** tab, when **Multi local center access** is on | One person who administers more than one chapter. | *** ## Recommended assignments | Position | Permission | Why | | ----------------------------- | ------------------------------- | --------------------------------------------------------------- | | President, executive director | Orgo administrator | Full control, including Settings | | Vice president | `ADMIN_TENANT` or `HR_TENANT` | Depends on their remit | | Secretary general | `HR_TENANT` | Members across the organization | | Treasurer | `FINANCIAL_TENANT` | Fees, products, payments, billing | | Communications lead | `COMMUNICATION_TENANT` | Campaigns, templates, lists, moderation | | Regional director | `ADMIN_PARENT_LOCAL` | Their anchor chapter and every chapter beneath it, at any depth | | Regional membership officer | `HR_PARENT_LOCAL` | Members across that same branch | | Chapter president | `ADMIN_LOCAL` | Their chapter only | | Chapter secretary | `HR_LOCAL` | Chapter members | | Chapter treasurer | `FINANCIAL_LOCAL` | Chapter fees and payments | | Event coordinator | `EVENT_LOCAL` or `EVENT_TENANT` | Match the reach of their events | | Membership assistant | `HR_ASSISTANT_LOCAL` | Badges, hours, identity checks | | Regular member | none | Member access is the default | *** ## Attaching permissions to a role **Settings → Users & Profiles → Roles & User types**. Give it a name and a plural, then pick a level: None, User type, Chapter, Parent chapter, Organization, or one of your unit types. Only the levels your modules support are offered. The checkboxes are grouped **Organization level**, **Local group level** and **Parent local center level**. Only the groups your modules support appear. On a member's **Roles** tab. They pick up the role's permissions immediately. A role marked as a **user type** cannot carry permissions. Ticking the user type level clears the permission list. Use a separate role for the responsibility, or assign the permission directly. A **Parent chapter** role attaches to the member's own chapter when that chapter is flagged **It's a parent chapter**, and otherwise to the chapter directly above it. It never attaches further up than that, so giving a district officer a parent-chapter role never files them against the region. A member whose chapter is neither a parent nor has one cannot be given a parent-chapter role at all, and the assignment is refused with "Members is not part of any parent local center". Roles list with Level and Permissions filters, a Level column showing Organisation, Parent chapter, Chapter and User type badges, and a Permissions column of permission tags *** ## Assigning directly on a member Open **Members**, the person, **Edit**, then the **Permissions** tab. It is visible if you hold HR or higher for that member's chapter and local administrators have not been restricted (below). Checkboxes are grouped under **Organization**, **Chapter** and **Parent chapter**, each heading naming the actual organization, chapter or region. Changes apply on the member's next page load, so ask them to reload if they had Orgo open. A permission that comes from a role shows a second, locked checkbox beside it with the role's name on an orange tag. You cannot untick that one here; end the role instead. Member Permissions tab showing the Orgo administrator switch and permission checkboxes grouped by Organization and Chapter, with a role-derived permission locked *** ## Rules on who may grant what These are enforced on save, not just hidden in the interface. | Rule | What it means | | ------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | Nobody edits their own permissions | Your own checkboxes and the Orgo administrator switch are disabled on your own profile, and a save is rejected if attempted another way. Another administrator has to make the change. | | You cannot grant above your own level | You only see checkboxes at or below your own level, and only within your own scope. A chapter administrator does not see organization-scope checkboxes at all. | | Organization-scope changes need `ADMIN_TENANT` | Adding or removing any `_TENANT` permission is rejected unless you hold `ADMIN_TENANT`. This applies to removals as well as grants. | | Only an Orgo administrator can create another one | The **Orgo administrator** switch is only rendered for members who already hold it. | | Local admins can be locked out entirely | Turn off **Allow Local Admins to Modify User Permissions** (**Settings → Users & Profiles → Configuration**, under Privacy & Visibility) and permission changes, status changes and chapter role changes are restricted to `HR_TENANT` and `ADMIN_TENANT`. Local administrators can still manage roles on units below chapter level. The setting is on by default. | ### Worked example: what at or below your own level means Your own level is a rank, and the rank comes from the permission's family first and its scope second. Families, highest first: | Rank | Family | | ---- | ----------------------------------------------- | | 1 | Admin | | 2 | HR | | 3 | Financial | | 4 | HR Assistant | | 5 | Events and Communication, level with each other | Within a family, organisation beats parent chapter beats chapter. Across families it does not: the whole Admin family sits above the whole HR family, and so on down. Separately, you can never grant at a wider scope than your own, whatever your rank. Two things fall out of that, and both surprise people: * **Being organisation-wide does not put you above every chapter permission.** The organisation's secretary general holding `HR_TENANT` ranks below `ADMIN_LOCAL`, so they cannot tick **Chapter administrator** on anyone's Permissions tab: the checkbox is simply not rendered for them. Nor can the treasurer holding `FINANCIAL_TENANT` tick `HR_LOCAL`. The communications lead holding `COMMUNICATION_TENANT` ranks at the very bottom and can hand out nothing except Events and Communication permissions. * **A chapter-scope person cannot reach out of their scope at all**, whatever their rank. A chapter president holding `ADMIN_LOCAL` can grant every chapter permission up to and including `ADMIN_LOCAL`, and nothing at parent chapter or organisation scope, because scope is checked before rank. The **Orgo administrator** flag skips the whole comparison, which is why appointing chapter administrators usually lands back with an Orgo administrator. Assigning a **role** is not gated this way. Any role, including one carrying `ADMIN_LOCAL`, can be assigned by anyone holding `HR_LOCAL` on that member's chapter. So attaching a permission to a role and letting chapter secretaries hand that role out delegates the permission far more widely than ticking the same box directly ever would. Review the Permissions column on **Settings → Users & Profiles → Roles & User types** and decide deliberately which permissions are allowed to travel by role. *** ## Giving one person access to several chapters Turn on **Multi local center access** in **Settings → Groups & Teams → Local Centers**. A **Multi chapter access** section then appears on each member's **Roles** tab, visible to `HR_TENANT` and `ADMIN_TENANT`. Each row pairs a chapter with a permission level: User, HR, Admin, Financial, HR Assistant, Event Manager or Communication Manager, all at chapter scope. Use **Add Local Center Access** for each extra chapter; the grant applies only to that chapter, so someone can be an HR manager in one and a plain member in another. *** ## Testing permissions with impersonation Impersonation lets an administrator browse Orgo with a reduced permission set, to see what a chapter treasurer or a plain member actually sees. Your profile menu, **Permission Impersonation**. It is offered to Orgo administrators, and hidden while a session is already running. Tick domains and scopes, or choose **Regular user**, which excludes everything else. You can also pick a user type, on its own or alongside permissions. The page reloads and a banner reads **Permission Impersonation Active** with the simulated permissions listed. Click **Exit** in the banner. Permission Impersonation dialog listing Regular user plus Admin, HR, HR Assistant, Financial, Events and Communication with Organization, Regional and Local checkboxes `ADMIN_TENANT` cannot be impersonated, and the administrator shortcut is switched off for the whole session. That is the point: while impersonating you genuinely lose your own access, so plan to exit before doing admin work. A session lasts 60 minutes, starting a new one ends the previous one, and starts are limited to five per minute. Every start and end is recorded with the simulated permissions, your real permissions, your IP address and your browser. *** ## Auditing who holds what Open **Members** and use the **Permissions** filter: it lists **Orgo administrator** first, then every permission grouped under Organization, Chapter and Regional. Tick several to see everyone holding any of them. It reads effective permissions, so it catches role-derived grants as well as those ticked directly on a profile, and it is `ADMIN_TENANT` only; anyone else asking is refused. For the other direction, which roles carry which powers, **Settings → Users & Profiles → Roles & User types** has a **Permissions** filter and a Permissions column showing each role's grants as tags. Run the member filter whenever someone leaves. Ending a member's role removes the permissions it carried, but a directly ticked checkbox survives a role ending and survives a change of chapter. *** ## Troubleshooting Settings screens require the **Orgo administrator** flag, which is a separate switch above the permission checkboxes. Turn it on. Either the module it belongs to is off (Financial needs Fees, Event Manager needs Events), or the scope is unavailable (chapter permissions need Local Centers, parent chapter permissions need Enable Parent Centers), or it is above your own level. Check their chapter on the profile, and check the **Multi chapter access** rows on their Roles tab. A regional permission covers an anchor chapter and every chapter beneath it at any depth, so with a three-layer structure it can reach further than the layer you had in mind. Work the anchor out from their own chapter using [What a parent-scope permission reaches](/docs/platform/groups/local-groups#what-a-parent-scope-permission-reaches). Ranking is by permission family, not by reach. `HR_TENANT` outranks `HR_LOCAL` but not `ADMIN_LOCAL`, because Admin sits above HR in the family order. `FINANCIAL_TENANT` does not reach `HR_LOCAL`. `COMMUNICATION_TENANT` reaches almost nothing. This is the intended rule, not a bug, and it is enforced on save as well as in the interface, so working around it by other means fails too. Worked through in [What at or below your own level means](#worked-example-what-at-or-below-your-own-level-means). If you need someone to be able to appoint chapter administrators, either give them the **Orgo administrator** flag or make the appointment yourself. Impersonation switches off your Orgo administrator status for the whole session, and every Settings screen requires it. Because starting a session reloads the page you are on, starting it from anywhere under Settings immediately fails the check and lands you on the login page. You are not signed out. Navigate back to a page your simulated permissions can open, such as the dashboard, and the **Permission Impersonation Active** banner with its **Exit** button is there again. That banner is part of the normal application layout, so it is not drawn on the login page, which is what makes this look worse than it is. Start impersonation from an ordinary page and this does not arise. **Settings → Users & Profiles → Roles & User types** checks the `ADMIN_TENANT` permission, while every other Settings screen checks the **Orgo administrator** flag. Someone who holds the permission but not the flag has no way into Settings from the interface, since both entry points (the cog in the header and the item in the profile menu) are drawn only for the flag. Send them a direct link, though, and Roles & User types opens while every neighbouring link on that same sidebar bounces them to the login page. Treat it as one page having a looser gate than intended, not as a supported way to delegate role editing. If someone needs to manage roles, give them the Orgo administrator flag knowingly, or make the change yourself. When a route refuses you, Orgo sends you to the login page rather than showing an access denied message. Your session is intact and the page you wanted is remembered, so this reads as a random sign-out when it is really a permission refusal. If a colleague reports being logged out at a specific link, do not start with their session. Compare the permission the page requires against what they actually hold, using the **Permissions** filter on the member list to confirm their effective permissions rather than trusting the checkboxes on one profile. *** ## Related * [Permissions](/docs/platform/permissions) - the permission model itself * [User Types & Roles](/docs/platform/users/user-types) - creating the roles you attach permissions to * [Role Groups](/docs/platform/groups/role-groups) - groups that fill themselves from roles * [Local Groups](/docs/platform/groups/local-groups) - chapters, parents, and what chapter scope means * [Troubleshooting Access](/docs/platform/users/troubleshooting-access) - when someone cannot sign in at all # Professional Network Source: https://orgo.space/docs/platform/professional-network Let members record what they do for a living, browse each other by industry, and connect The Professional Network turns your member list into a searchable directory of what people actually do: a headline, an industry, optionally a job title and an area of expertise, and the company they work for. Members browse it by industry or by keyword and send each other connection requests. **Built for** business networks, alumni associations, chambers of commerce, and any community whose members want to find each other by expertise. **Replaces** a spreadsheet of "who knows about what" and a separate LinkedIn group. Professional network page with the interests and industry lists in the left column, each row showing its member count, next to a grid of member cards with name and profession headline *** ## How to access The directory lives at `/professional-network`. It is not in Orgo's default sidebar, so add a **Professional network** item through the [Menu Organizer](/docs/platform/customization/menu-organizer). Clicking an industry on someone's profile also lands here, pre-filtered. Being signed in is the only requirement, subject to [Who can see whom](#who-can-see-whom). Admins configure it under **Settings** → **Modules** → **Professions**, which requires `ADMIN_TENANT`. *** ## Turning it on Four switches, saved the moment you flip one. Professions module settings with the master Enable Professions Module switch and a Professional Information section holding Enable Industry Tracking, Enable Job Information and Enable Expertise | Setting | What it does | | ----------------------------- | ------------------------------------------------------------------------------------------------------ | | **Enable Professions Module** | Master switch. Off removes the profession block from member profiles. | | **Enable Industry Tracking** | Adds the **Profession industry** picker and the **Profession Industries** admin screen. On by default. | | **Enable Job Information** | Adds the **Profession job** picker, from a global catalogue of about 490 job titles. Off by default. | | **Enable Expertise** | Adds the **Profession expertise** picker, from a global catalogue of about 157 areas. Off by default. | Headline, sector and the current-organisation fields are not switches here. They are rows on the [profile form](/docs/platform/users/profile-fields). *** ## What members fill in The **Profession** tab on a profile shows only the fields you have enabled. Members edit their own; an admin needs `ADMIN_LOCAL` or higher over that member. Profession tab of a member profile with profession headline, job and expertise pickers, industry, a public private non-governmental sector choice and a Current profession card | Field | Enabled by | Notes | | ---------------------------------------- | ------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | | **Profession headline** | Profile form | Free text. The line under the name in the directory, and the only field the keyword search looks at. | | **Profession job** | *Enable Job Information* | Global catalogue. **Other** shows a free-text box. | | **Profession expertise** | *Enable Expertise* | Same pattern, with its own **Other** box. | | **Profession industry** | *Enable Industry Tracking* plus the profile form's *Profession industry* row, both required | Drives the industry filter. | | **Profession sector** | Profile form | Public, Private or Non-governmental. | | **Current company/organization name** | Profile form | Heads the **Current profession** card. | | **Current Company/organization website** | Profile form | Rendered as a link on the company name. | | **Current role in company/organization** | Profile form | | The billing fields on the same tab (company identifier, legal name, address, commerce registry number) are for invoicing, not for the directory. See [Companies](/docs/platform/users/companies). The three company fields are shown as one **Current profession** block, and that block is keyed to **Current company/organization name**. If you remove that field from the profile form, the website and role fields disappear with it even while they are still selected. Keep the name field on the form whenever you want either of the other two. *** ## Browsing the directory Unfiltered, the directory lists every active member with a profession headline, newest profession update first. Your own card comes first, carrying **Add profession** and **Add industry** prompts while yours is empty. Cards show photo, name, user type, headline, industry, a supporter badge if the member subscribed to your support product, and a LinkedIn icon when their LinkedIn URL is set. Three filters, which combine: | Filter | What it matches | | ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Search by profession** | The headline text, and nothing else. | | **Industry** | One industry, each listed with its member count. | | **Interests** | Appears only once you designate a [custom field](/docs/platform/users/custom-fields) as the interest field under **Settings** → **Modules** → **Users & Profiles** → **Custom Fields**. Only dropdown, checkbox and radio fields are eligible. | *** ## Managing the industry catalogue **Settings** → **Modules** → **Professions** → **Profession Industries**, visible only while **Enable Industry Tracking** is on, lists roughly 148 industries Orgo ships globally plus any you add. Industries admin table with Industry Name, type tagged Custom or Global, an enabled checkbox per row, and bulk buttons for enabling or disabling all custom and all default industries Unticking hides an industry without deleting it, and members who already picked it keep the value. **Disable All Default** clears the shipped list at once, the usual start for a short bespoke list. **Create Industry** takes a name plus optional translations per interface language; custom industries are tagged **Custom**, belong only to your organisation, and are the only ones you can rename or delete. The job and expertise catalogues are read-only global reference data: you cannot add to them or hide entries. Every write on this screen, creating, renaming, deleting and the bulk enable and disable buttons, is refused unless your account carries the tenant administrator **role**. An admin who holds `ADMIN_TENANT` as a permission rather than as the role can open the screen and read the list, and gets Access Denied on the buttons. *** ## Connections Connections have their own switch, **Settings** → **Modules** → **Users & Profiles** → **Profile Settings** → **Has Connections**, on by default and working whether or not the Professions module is on. **Connect** on the other member's profile, or on a Discover members card. The button is only there when the other account is active, you are not already connected, neither of you has a request pending with the other, and you are not inside a cooldown. They get an in-app notification and an email. Only they can respond: the sender's button becomes **Request pending** and does nothing until they do. From the profile, or from **Requests received** on the **Connections** tab of their own profile, which carries a dot while anything is waiting. Accepting notifies and emails the sender; declining tells them nothing. Under accepted connections on each side, searchable and sortable by most recent, least recent or name, and counted on the tab. Either side can remove an accepted connection later. That deletes it outright, with no notification to the other person, and either of them can send a fresh request afterwards. Two server-side limits apply. * **20 connection requests per hour** per member. The 21st is refused until the hour is up. * **A 21 day cooldown**, which starts when a *pending* request is cancelled, not when one is declined. A member who sends a request and then withdraws it cannot ask that person again for three weeks. A member whose request was declined can ask again immediately, and the declining party is never told either way. Requests to accounts that are not active are refused outright. My Network tab on your own profile listing accepted connections as rows with a count, a search box and a sort dropdown *** ## Discover members **User Recommendations**, on the same Profile Settings screen, gives members a **Discover members** carousel of suggested people, also placeable on the [dashboard](/docs/platform/customization/dashboard-organizer) as a widget. Suggestions score out of 150 points across five signals: | Signal | Max points | | ------------------------------------- | ---------- | | Same county, region or country | 40 | | Age within five years | 30 | | Recently joined, decaying over a year | 30 | | Mutual connections, 10 points each | 30 | | Recent login, decaying over 30 days | 20 | Excluded: members already connected, already asked, in a decline cooldown, under 18, or with a private profile. At most 50 suggestions are produced, cached for 48 hours and refreshed sooner when a connection is sent or accepted. Recommendations are deliberately not based on profession. Industry, expertise, job title and the interest custom field play no part in the score, so filling the professional profile in will not change who a member is shown. *** ## Who can see whom **Individual privacy.** Each member has a **Profession & social media** toggle in their privacy settings. Set to admin-only, it blanks their headline and industry for everyone except tenant admins, HR staff, and staff in their own local center. The organisation-wide default is **Settings** → **Modules** → **Users & Profiles** → **Privacy Defaults**. Signed-out visitors never see profession data. See [Privacy Settings](/docs/platform/users/privacy-settings). **Directory visibility.** **Who Can See Members in General Groups**, under **Privacy & Visibility** in the same module, applies here too. Raised above ordinary members, plain members can still browse and filter by industry, but keyword and interest filters are refused and recommendations fall back to their own local center. *** ## Common questions The unfiltered directory lists only members who have a **Profession headline** and status Active. Industry, job title and expertise on their own do not put anyone in the list, which is the usual cause: the member filled in the pickers and skipped the free-text line. A useful way to confirm it: filter by their industry. The industry filter drops the headline requirement, so someone who appears under their industry but not in the unfiltered list is missing a headline and nothing else. The tab renders only when there is something to put on it. It needs **Enable Professions Module** on, plus at least one available field, which can come either from the module switches (industry, job, expertise) or from the profile form (headline, sector, the current organisation fields). Switching the module on while every field is off leaves the tab empty and hidden. Check the [profile form](/docs/platform/users/profile-fields) as well as the module screen. That is **Who Can See Members in General Groups**, under **Privacy & Visibility**, set above ordinary members. The rule is about which member lists a plain member is allowed to pull, not about the professional network as such, and it hits the keyword and interest filters because those ask for a list of members with no group or industry attached. Two things still work for those members: browsing unfiltered and filtering by industry. So the practical workaround is to pick an industry first and then type in the search box, since the request then carries the industry and is allowed. Guests are refused in every case. The button is hidden rather than disabled, so its absence is the error message. It means one of: * **Has Connections** is off for the organisation; * the other account is not Active; * a request is already pending in one direction or the other; * the two are already connected; * the member cancelled an earlier request to this person and the 21 day cooldown is still running. Only the last one expires on its own. The interface shows one generic toast for every refusal, so read it as "the server said no" and work through the four possible reasons: the sender has sent 20 requests in the last hour, the sender is in a cooldown with that person, the recipient's account is not Active, or the recipient has already sent them a request that is waiting to be accepted. The last one is the most common and the least obvious: the member should look at **Requests received** on their own **My Network** tab, where the person they were trying to reach is probably already waiting. A decline does not block anything. If the recipient used **Decline**, the sender can ask again straight away. What does block for 21 days is cancelling your own pending request. If the member withdrew the request rather than being declined, the cooldown is running and the Connect button stays hidden until it expires. So the question to ask is not "were they declined" but "did they cancel". Suggestions are cached for 48 hours per member, and only rebuilt earlier when that member sends or accepts a connection. Nothing else refreshes them, so a member who fills in their profile and reloads sees the same list. Also check what the score is actually made of: location, age proximity, how recently the person joined, mutual connections and recent logins. Profession plays no part, so telling members to complete their professional profile in order to get better suggestions is not true. Members who are already connected, already asked, in a cooldown, under 18 or on a private profile are excluded entirely, which is why a small or young organisation can run out of suggestions long before the 50-suggestion ceiling. Expected. Unticking an industry removes it from the pickers and from the directory's industry list, but the value stays on the member records that already had it. Cards resolve the name from the enabled list, so those members show an empty industry line rather than the old name. Tick it back on to make the name reappear, or edit those members onto an industry you kept. Deleting is only possible for industries you created yourself, which is the safer reason to disable rather than delete. Skills are separate: **Enable Skills Field**, on the same **Profile Settings** screen, adds a Skills custom field seeded with a predefined catalogue. It is not part of the Professions module and does not appear in the directory filters, so use expertise if you want people to be findable by it here. *** ## Related * [Profile Fields](/docs/platform/users/profile-fields) for adding the headline, sector and company fields * [Custom Fields](/docs/platform/users/custom-fields) for designating the interest field * [Privacy Settings](/docs/platform/users/privacy-settings) for what members can hide * [Members](/docs/platform/users) for the main member directory and its filters * [Companies](/docs/platform/users/companies) for company records and billing details # Projects Source: https://orgo.space/docs/platform/projects Run projects inside Orgo with tasks, a kanban board, a Gantt timeline and goals A project is a workspace for a piece of work your organisation is delivering. It holds tasks, its own set of task statuses and task types, an optional list of goals and objectives, and its own member list. Every project has five views: Overview, Tasks, Board, Gantt and (when it has a description) About. **Built for** committees, working groups and staff teams that plan work in Orgo rather than in a separate tool, so the people, groups and permissions are already there. **Replaces** a spreadsheet of action items or a standalone task tracker for internal work. It is not a client-facing or billable project tool: there is no time tracking, no budget and no external sharing. Projects page showing Active and Archived tabs and project cards with a coloured tile, a description and a completed task count with a progress bar *** ## Turning it on Projects is a module, **off** by default: **Settings** → **Modules** → **Projects** → **Enable Project Management** (`ADMIN_TENANT`). The same switch also enables project groups, described at the end of this page. A **Projects** section then appears in the sidebar listing the projects you can open, with a search box past two. Its label can be renamed in the menu organiser. Projects module settings with the Enable Project Management switch turned on and its helper text *** ## Who can do what | Action | Who | | -------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | Create a project | Any signed-in member, from the plus button on the sidebar **Projects** section. The Projects page **Create project** button shows only to `HR_TENANT` and above. Guests cannot create projects when a guest user type is configured. | | Open a project | The owner, individual members, members of a group it grants access to, `ADMIN_TENANT` and `HR_TENANT`. Everyone else gets a not-found and never sees it in the sidebar. | | Rename, restyle, archive, delete, manage members, statuses and types | `ADMIN_TENANT` or the owner in the interface. The API also accepts a member of one of the project's access groups. | | Create tasks | Anyone who can open the project. Editing an existing task is narrower: see [Tasks](/docs/platform/tasks). | *** ## Creating a project **Projects** → **Create project**. Everything on the form can be changed later in project settings. | Field | What it does | | --------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Project name** | Required. Shown in the sidebar, on the card and in the header. | | **Emoji** / **Color** | Pick one or the other. It identifies the project everywhere it is listed. | | **Description** | Free text. Filling it in adds the **About** tab. | | **Project owner** | Defaults to you; search any member to hand it over. The owner always has full rights. | | **Group access** | One or more groups whose members can all open the project. | | **Task options** | Five checkboxes controlling which fields and filters appear on tasks here: **Goals** (off by default), **Priority**, **Due date**, **Task types** and **Custom statuses** (all on). | Saving creates three task statuses: **To do**, **In Progress** and **Done**, with **Done** marked as a closed status. ### Giving people access Owner, individual members and group access stack. Add **individual members** one at a time under **Settings** → **Members**: only active accounts qualify, and nobody twice. A member of an access group counts as an editor to the API, so use group access for the people running the project and individual members for people who only follow it. `ADMIN_TENANT` and `HR_TENANT` see every project regardless. Project settings Members tab showing the project owner, an individual members list with avatars and a group access tag input *** ## The project views | Tab | What it shows | | ------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Overview** | **Status distribution** and **Priority breakdown** pie charts, a **Needs attention** panel (overdue, unassigned, due in 3 days, no dates), recent tasks, a completion ring, **Team** workload by assignee, and **Upcoming** due dates and goals. Clicking a slice or counter filters the Tasks tab. | | **Tasks** | The full task list with filters, grouping and column options. See [Tasks](/docs/platform/tasks). | | **Board** | Kanban: one column per task status, plus optional **Overdue** and **No status** columns. Drag a card between columns to change its status. | | **Gantt** | Tasks and goals on a timeline at **Day**, **Week** or **Month** scale, with zoom and a **Tasks** / **Goals** / **Both** filter. Drag a bar to move it, or its edges to change start and due dates. | | **About** | The project description, edited in place by anyone who can edit the project. Appears once a description exists. | Dropping files anywhere on a project opens the new task form with those files attached. Project Overview tab with status and priority pie charts, a needs attention panel, recent tasks and a team workload list *** ## Goals and objectives Switch on **Goals** in the project's task options, then open **Objectives & Goals** from the project header. A **goal** groups tasks into a phase or milestone: a name, an optional description, an optional parent objective, optional start and end dates. Tasks then carry a **Goal** field, the task list groups and filters by goal, and goals get their own Gantt bars. An **objective** sits a level above goals, for projects with several strands of work; turn them on with the **Objectives** switch on the goals screen. An objective has a name, description, colour and date range, and goals are dragged into it. With objectives off you get one flat list. Both reorder by dragging, and deleting a goal leaves its tasks in place without a goal. Objectives and goals screen with two expandable objective sections, each with a colour dot, its goals nested underneath, and add objective and add goal buttons *** ## Project settings The cog in the project header opens **General** (the create-form fields plus the danger zone), **Members** (owner, individual members, group access) and **Statuses & types**. Statuses and types are specific to this project: each status has a name, a colour and a **Mark as closed** switch deciding whether tasks in it count as complete; each type has a name and a colour. **Archive project** moves it to the **Archived** tab, still readable and unarchivable from there. Its tasks stop sending assignment, status, comment and reminder emails and drop off the dashboard **My Tasks** card, but still appear in the daily task digest. **Delete project** is permanent and takes the tasks, goals, objectives, statuses and types with it. *** ## Projects and project groups The same module switch also turns on an older feature that uses the word project. A **project group** is an ordinary group with issue tracking switched on, created from **Issues** → **New**: it gains an **Issues** tab with its own issue statuses and types, lives with the group rather than on the Projects page, and issue tracking can only be set at group creation. See [Issues](/docs/platform/issues). A project in the sense of this page is a separate record with its own members, tasks, board, Gantt and goals, listed under **Projects** in the sidebar. It can grant access to groups, but it is not one. Starting fresh, use Projects; project groups remain for organisations already tracking issues inside their groups. *** ## Related * [Tasks](/docs/platform/tasks) - everything a task holds and how the reminders work * [Issues](/docs/platform/issues) - the group issue tracker and project groups * [Groups](/docs/platform/groups) - the groups a project can grant access to * [Permissions](/docs/platform/permissions) - what `ADMIN_TENANT` and `HR_TENANT` unlock * [Notifications](/docs/platform/notifications) - the member-side notification switches # Reports Source: https://orgo.space/docs/platform/reports Build a report from your members, payments, events or votes, and download the whole result set as a CSV **Reports** is a builder for the exports your organisation runs again and again. You pick what the report is about, tick the columns you want, add filters, check the preview, and download a CSV. Nothing is typed as a query and nothing is capped at a page: the file holds every row that matched. **Built for** admins who need the same extract every month, or a one-off list with exactly the columns a colleague, an auditor or a funder asked for. **Replaces** exporting the member directory a page at a time, stitching several spreadsheets together, and asking a developer for a data pull. *** ## Where to find it The Reports screen before any report exists, showing the heading Reports, a New report button, and an empty state reading No reports yet with the line Build a custom spreadsheet from your members, payments, events and more, above a Create your first report button | Surface | Route | Who can open it | | ---------------- | ------------------------------------------------------------------------------ | ------------------- | | **Reports** list | `/reports`, sidebar item **Reports** under Administration, beside **Ask Orgo** | `ADMIN_TENANT` only | | Build a report | `/reports/create` | `ADMIN_TENANT` only | | Edit a report | `/reports/edit/:item` | `ADMIN_TENANT` only | There is no module switch and no setting to turn on. Reports is available to every organisation on the platform, and the sidebar entry appears as soon as you hold `ADMIN_TENANT`. `ADMIN_TENANT` is the only way in, for every part of the feature: building, previewing, exporting and downloading. There is no HR, finance or chapter version, so an `HR_TENANT` or `ADMIN_LOCAL` administrator cannot open Reports at all, and cannot be given a read-only or chapter-scoped copy of one. A report covers the whole organisation, so treat access to Reports as the same reach as access to every member record. [Scoped API tokens](/docs/platform/api) are refused too: a scoped token never carries `ADMIN_TENANT`, whoever minted it. *** ## Building a report The report builder with Members selected from the row of seven starting points, the Members field group expanded showing four of sixteen columns ticked including first name, last name, email and date joined, the related record groups collapsed below it for local center, user type, town and membership fee tier, and a preview table underneath listing real member rows with a Local Center Name column pulled in from the related record Pick one of seven starting points: members, contacts, payments, event attendees, votes, companies or member roles. Everything else follows from that choice, and one report has exactly one starting point. Each row in your file will be one of these records. Each starting point offers its own list of fields. Tick the ones you want and they become the columns of the file, in the order you picked them. Alongside the record's own fields you can reach one step outwards, into a record it belongs to: a payment's product and payer, a member's chapter and membership type, an attendee's event. Those fields appear as extra columns with the relation named in front of them, so the chapter's name arrives as **Local Center Name** rather than a second column called **Name**. Add conditions until the report describes the group you mean. Filters are typed to the field you chose, so a date field offers dates and a status field offers its real list of values rather than a free text box. The preview runs as you build and shows the first 10 rows with the same column headers the file will carry. Use it to confirm the shape before you commit to a download. Give the report a name and save it. From there, **Download** starts the export. ### Filters The Filters tab of a saved report named Payments export by date, with the note that only rows matching every filter are included, two stacked conditions on Date created reading after 01/01/2026 and before 01/07/2026 joined by an AND label, an Add filter link, and an empty preview panel offering a Run preview button The operators you are offered depend on the type of the field, so you never have to know what a field is stored as. | Field | Operators | | ----------------------------------------------------- | ---------------------------------------------------------------------- | | Text | **contains**, **equals** | | Number and amount | **equals**, **greater than**, **less than**, **at least**, **at most** | | Date | **on**, **after**, **before** | | Yes or no | **is** | | A field with a fixed list of values, such as a status | **is**, choosing from the real list | Every filter you add narrows the report further: they are combined with **and**, always. There is no **or**, no bracketing of one group of conditions against another, and no way to say "members in Berlin or Munich" in a single report. Run that as two reports, or filter on something the two have in common. The builder also has no sorting and no totals. A report is the rows and the columns you asked for; ordering, subtotalling and charting are things to do in your spreadsheet once the file has downloaded. *** ## What you can report on The Main entity tab of a report named Member export by chapter, asking what do you want to report on with Members selected from the seven chips, and beneath it five collapsed field groups: Members with five columns chosen, Local center this user belongs to with one, then user type, town and membership fee tier, each its own group Each starting point is its own group, with the records it can reach shown as further groups beneath it. The count beside a group is how many of its columns you have picked. Seven starting points, each with its own fields and its own related records. | Report is about | Fields on the record | Related records you can add columns from | | ------------------- | -------------------- | ---------------------------------------------------------------------------------------------------------------- | | **Members** | 16 | Local Center, Type, Town current, Fee Tenant Product Price | | **Contacts** | 8 | Local Center | | **Payments** | 17 | Product, Subscription Profile, Contact, User, Price, Manual Fee Payment, Accepted By, Identity, Invoice, Company | | **Event Attendees** | 6 | Event, User, External contact, Product Payment, Product Price, Invoice | | **Votes** | 5 | Owner, Event | | **Companies** | 10 | Fee Tenant Product Price | | **Member Roles** | 4 | Role, User, Unit | Every related record in that table is one the row belongs to: a single product, a single chapter, a single event. That is the whole of what a report can reach. Lists of related records are deliberately left out. A member has many payments, many roles and many course enrolments, and adding one of those to a member report would turn one member into one row per payment, with the member's own details repeated down the file and every total inflated. So you cannot put members and their payments in one report, and you cannot step twice, from a payment to its payer to that payer's chapter. Turn it around instead: to see payments with member details, start the report from **Payments** and add columns from **User**. One payment has exactly one payer, so the row count stays honest. The same trick covers roles (start from **Member Roles**) and attendance (start from **Event Attendees**). *** ## Downloading the file **Download** hands the report to a background worker rather than making you wait at the screen, so a report matching a hundred thousand members behaves the same as one matching ten. A progress window opens and counts the rows as they are written. It updates live, and keeps checking on its own if the live connection drops, so the count keeps moving either way. You can leave it open or press **Continue in background** and carry on working. An export moves through **pending**, then **processing**, then **completed**, or **failed** if something went wrong. When it finishes you get the file two ways: | Where | How long the link lasts | | ---------------------------------------------------------------------------------- | ----------------------- | | **Download** in the progress window | About 15 minutes | | The **report is ready** email, sent to you whether or not the window is still open | 3 days | The email arrives every time, which is what makes a long export safe to walk away from. Come back to it tomorrow and the link still works. ### The file itself * **CSV**, comma separated, UTF-8 with a byte order mark, so accented names and non-Latin alphabets open correctly in Excel without an import step. * **Every matching row.** There is no row limit and nothing is truncated. Rows are fetched 500 at a time behind the scenes and written straight to the file, which is how a very large report stays within the worker's memory, but that paging never reaches the file. * **Readable headers.** Field names are turned into words, and a column from a related record is prefixed with the relation, for example `Local Center Name` or `Product Name`. The headers match what the preview showed you. * **Named after the report**, so a saved report downloads under the same file name every month. Every download is written to the [activity log](/docs/platform/logs) with the report name and who asked for it. *** ## Saving, editing and re-running The Reports list showing three saved reports named Member export by chapter, Event attendee contact list and Payments export by date, with columns for name, what each is based on, and when it was last updated, and download, edit and delete actions on each row. There is no owner column Saving a report stores the definition, not the data. Open it again next month, press **Download**, and it runs against today's records. The list at `/reports` shows each report's name, what it is about, and when it was last updated, with actions to open, edit or delete it. Editing a saved report changes what the next export contains. It does not touch files you have already downloaded, and it does not reach back into an export that is already running. **Saved reports belong to the organisation, not to you.** Every report is visible to every `ADMIN_TENANT` administrator in your organisation, and any of them can open it, run it, edit it and delete it. The list shows no owner column, so there is no way to tell from the screen who built a report, and a report you rely on every month can be changed or removed by a colleague without warning. This is how the feature is meant to work: reports are a shared library of the organisation's standard extracts rather than private saved searches. Name them so their purpose is obvious to somebody who did not build them, and treat a report you depend on as shared infrastructure. **Download exports the last saved version of the report.** If you change columns or filters on screen and press **Download** without saving first, you get the file the saved report describes, not what is in front of you. Save, then download. *** ## Limits | Limit | Value | | ---------------------------- | -------- | | Columns in one report | 20 | | Filters in one report | 20 | | Steps out to related records | 1 | | Related records joined | 6 | | Rows in the downloaded file | No limit | | Rows in the preview | 10 | *** ## How Reports differs from Ask Orgo and Database Queries Three features look adjacent on the sidebar and answer different questions. | | What you do | What comes back | | ------------------------------------------ | ----------------------------------------------------------- | ---------------------------------------------------------------------- | | **Reports** | Fill in a form: one of seven record types, columns, filters | A CSV of the whole result set, downloaded again whenever you need it | | **[Ask Orgo](/docs/platform/insights)** | Type a question in your own words | A one-off answer on screen, as a table or chart, from a language model | | **[Database Queries](/docs/platform/insights)** | Re-run a statement Ask Orgo wrote earlier and you saved | The saved query's results, exported a page at a time | **Database Queries** stores the statement Ask Orgo produced and replays it, so what it can answer is whatever the assistant managed to build that day. Reports is something you fill in yourself, from a fixed set of starting points, and its export walks the entire result set instead of one 500-row page. **Ask Orgo** is the right tool for a question you have not asked before, or one that needs grouping, a chart or arithmetic the report builder does not do. It involves a language model, which means it can reach further and can also misread you. Reports involves no model at all: you choose the columns, so the same report gives the same shape of file every time. Use Ask Orgo to explore, and a report for the file you download every month. *** ## Common questions No. Every route and every endpoint behind Reports requires `ADMIN_TENANT`, and the sidebar entry is placed in code rather than drawn from your configurable menu, so it cannot be moved onto another role's menu. There is no chapter-scoped version and no read-only version. If a colleague needs the numbers regularly, build the report, download it and send them the file, or give them the [analytics dashboards](/docs/platform/insights) if a total is enough. Because a member has many payments, and a row can hold only one. Joining them would give you one row per payment with the member's details repeated, which is a fine list of payments and a badly wrong list of members: totals and counts computed from it come out several times too high. Start from **Payments** instead and add columns from **User**. You get every payment with its payer's name, email and chapter beside it, and one row means one payment. Roles and event attendance work the same way round. A report reaches one step out and stops. From a payment you can add the payer's own fields, but not the payer's chapter, because that is a second step. Pick the starting point that puts what you need one step away. If the answer genuinely needs two hops, run two reports and join them in a spreadsheet on an id column, or ask the question in [Ask Orgo](/docs/platform/insights), which can follow a longer path. Not in the builder. A report produces rows and columns; sorting, subtotals, pivots and charts are spreadsheet work once the file is open. The one thing worth deciding in Orgo is the filtering, because that is what keeps the file to a size you can work with. No. Filters are always combined with **and**, and there is no grouping. A report asking for members in Berlin or Munich has to be two reports. Often there is a single condition that means the same thing: a chapter, a tag, a membership type or a date range that both groups share. Look for that before splitting the report in two. That is how saved reports work: they belong to the organisation, and every organisation admin can open, edit and delete any of them. There is no owner column and no per-report permission. Rebuild it and give it a name that says what it is for and who relies on it. If your organisation runs several standard extracts, agree a naming convention so nobody tidies away a report they did not recognise. Nothing is lost. The export carries on running on its own, and the **report is ready** email arrives when it finishes with a link that stays valid for 3 days. Open the report again afterwards if you would rather download it from the screen. The link in the progress window is deliberately short lived, about 15 minutes, and the emailed one lasts 3 days. Both are meant to expire so a forwarded link does not become a permanent open door to your organisation's data. Once a link has expired, open the report and press **Download** again. The report re-runs against today's records, so the new file may differ from the old one, which is usually what you wanted anyway. The second press joins the run already in progress rather than starting a second one, so you get one file and the report is not queried twice. Not yet. A report runs when somebody presses **Download**. The email you get is the delivery of that run, not a subscription. *** ## Related * [Insights & Ask Orgo](/docs/platform/insights) for questions in plain language and the analytics dashboards * [Members](/docs/platform/users) for the directory, its own filters and its paged export * [Membership fees](/docs/platform/fees/fees) for the payment screens a payments report draws from * [Permissions](/docs/platform/permissions) for what `ADMIN_TENANT` unlocks * [Activity log](/docs/platform/logs) for the record of who downloaded what * [Email lists](/docs/platform/emails/email-lists) for building a segment to send to, rather than a file to download # Tasks Source: https://orgo.space/docs/platform/tasks Create tasks with assignees, statuses, checklists and dependencies, and see them on a list, board or timeline Tasks are the unit of work inside a project. A task carries a title, a rich description with attachments, a status, a type, a priority, one or more assignees, start and due dates, a checklist, dependencies on other tasks, comments and a change history. **Built for** the day to day work of a committee or staff team: who is doing what, by when, and what is blocking it. **Replaces** action-item spreadsheets and email chases. Tasks always belong to a project, so there is no standalone personal to-do list. Project Tasks tab with assignee avatars, group by and status filters, and a table of tasks with status and priority tags *** ## Creating a task Open a project and use **Add task** on the Tasks, Board or Gantt tab. Anyone who can open the project can create tasks. Dragging files onto a project also opens the form with those files attached. | Field | What it does | | ------------------------------- | ---------------------------------------------------------------------------------------------------------------------- | | **Task title** | Required. | | Description | Rich text with images, video and file attachments. | | **Checklist** | A list of sub-items with tick boxes. Pasting a bulleted list creates several at once. Items are reordered by dragging. | | **Goal** | Only when **Goals** is on for the project. Puts the task under a goal. | | **Type** | Only when the project has task types defined, for example Bug, Feature, Task. | | **Assignees** | One or more members. Search is limited to people who can access the project. | | **Priority** | **Highest**, **High**, **Medium**, **Low**, **Lowest**. New tasks start at **Medium**. | | **Status** | One of the project's statuses. Defaults to the first one, normally **To do**. | | **Start date** and **Due date** | Each optional. The pickers keep the start on or before the due date. | | **Blocked by** | Other tasks in the same project that must be closed first. | The task list, board and Gantt only show the fields the project has switched on under **Task options**, so a project without priorities or due dates gets a simpler form. New task modal with a title, a description, a two item checklist and a side panel holding goal, type, assignees, priority, status and dates *** ## Statuses and types Both are defined per project under **Settings** → **Statuses & types**, so two projects can run entirely different workflows. A status has a name, a colour and a **Mark as closed** switch. Closed is what makes a task count as complete: it removes the task from open filters, from the daily digest and from reminder emails, and it satisfies any dependency on that task. A new project starts with **To do**, **In Progress** and **Done**, with **Done** marked as closed. A type has a name and a colour only. It is a label for grouping and filtering. *** ## Assignees and completion A task can have several assignees, each with their own tick box, and the task shows a counter such as 2/3. Only that assignee can tick their own box; `ADMIN_TENANT` can tick anyone's. Completing every assignee's part does not close the task automatically: someone still has to move it to a closed status. Editing a task is open to `ADMIN_TENANT`, the project owner, any assignee, and whoever created the task. Deleting a task is limited to `ADMIN_TENANT`, the project owner and the task creator. *** ## Dependencies **Blocked by** lists tasks that must be finished first. Orgo enforces three rules when you add one: * the blocking task must be in the same project, * a task cannot block itself, and the chain cannot loop back on itself, * a dependency chain deeper than 100 levels is rejected. While a blocking task is still open, moving the dependent task to a closed status is refused and the response names the tasks still in the way. *** ## Comments and history Comments sit at the bottom of the task. They take rich text, images and files, support threaded replies and emoji reactions. Posting a comment notifies the task assignee and the task creator in the app, and emails everyone assigned plus the creator, skipping whoever wrote the comment. On an archived project the comment is saved but nothing is sent. Every status change, assignee change, priority change and due date change is written to the task history with who made it and when. Task detail page showing status, priority and type controls, two assignees with completion ticks, a three item checklist and a comment thread *** ## Finding tasks The **Tasks** tab is the full list. It shows 20 tasks a page, or the whole set when grouping is on. | Control | What it does | | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | | **Search task** | Matches the title. | | Assignee row | Click an avatar to filter to that person, or **unassigned**. A search box appears once the project has more than ten members. | | **Group by** | **assignee**, **status**, **Type**, **Goal**, **priority** or **Month**. **By assignee** adds a second level of columns inside each group. | | **Status** | Filter by **Open tasks**, **Closed tasks** or individual statuses. | | **Goal** | Filter to one goal, when goals are on. | | **Columns** | Show or hide the **created**, **Type**, **Goal**, **Due date** and **Priority** columns. | | **Reset filters** | Clears everything at once. | The Overview tab's counters are shortcuts into the same list: clicking **overdue**, **unassigned**, **due in 3 days** or **no dates** applies that filter. The **Board** tab is a kanban view with one column per status plus optional **Overdue** and **No status** columns; dragging a card changes its status. The **Gantt** tab plots tasks and goals over a day, week or month scale, and dragging a bar or its edges changes the dates. Kanban board with Overdue, To do, In Progress, In Review and Done columns holding task cards with avatars, priority icons and due dates *** ## My tasks The dashboard carries a **My Tasks** card listing your open tasks from active projects, soonest due date first and then by priority, with a link through to **Projects**. Archived projects and tasks in a closed status are left out. *** ## Emails about tasks | Email | When it is sent | Who gets it | | ------------------- | ----------------------------------------------------------- | -------------------------------------------------------------------------------------- | | Task assigned | A task is created with an assignee, or its assignee changes | Everyone assigned, except the person who made the change | | Task status changed | The status changes | Everyone assigned plus the creator, except the person who made the change | | Task comment added | A comment is posted | Everyone assigned plus the creator, except the commenter | | Daily task digest | Every day at 06:00 UTC | Members with at least one overdue, due today, due this week or high priority open task | The digest groups your work into overdue, due today, due this week and high priority, and adds up to five tasks with no due date. If none of the first four groups has anything in it, no digest goes out that day. Archiving a project silences the first three emails for its tasks. The digest is the exception: it still lists tasks from archived projects. The daily digest is the one task email a member can switch off, using the **Task** toggle in their profile notification settings. The organisation default for new members is **Email Notifications: Tasks** under **Settings** → **Modules** → **Emails & Notifications** → **Notification Preferences**, and it ships set to Instant. The assigned, status changed and comment emails have no member-level switch and are not in the Email Templates catalogue, so they cannot be edited or turned off from Settings. Orgo also has due soon and overdue task emails, but the job that sends them is not on the automatic schedule, so members do not receive them today. Use the daily digest, which lists the same overdue and upcoming work. *** ## Related * [Projects](/docs/platform/projects) - projects, access, goals and the project views * [Issues](/docs/platform/issues) - the separate issue tracker inside groups * [Notifications](/docs/platform/notifications) - the notification switches and defaults * [Emails](/docs/platform/emails) - how system emails are built, sent and logged * [Permissions](/docs/platform/permissions) - what `ADMIN_TENANT` and `HR_TENANT` unlock # Orgo for member communication Source: https://orgo.space/docs/platform/templates/communication A setup playbook for running member communication on Orgo: which modules to enable, in what order, and which channel to use for what This page is for the person who has decided to run their organization's member communication on Orgo and now has to configure it. It routes you: what to switch on, in what order, and which page documents each step. **Built for** organizations replacing a mailing list tool plus a Facebook group plus a folder of copy-pasted announcement emails. **Replaces** the guesswork about which of those Orgo covers. One of the [setup templates](/docs/platform/templates/index). Read it alongside whichever one describes your core operation, since every organization communicates. Everything below leads to one screen: **Administration** → **COMMUNICATION** → **Email campaigns**, where campaigns are written, sent and measured. Email campaigns page with Total sent, Avg. open rate, Avg. click rate and Total recipients tiles above a table of draft and sent campaigns with recipient counts and open rates *** ## Before you start Have these ready. Each one blocks a step further down, and finding out late means resending mail. * [ ] A sender address you control on your own domain, not a personal mailbox * [ ] Access to your domain's DNS, if you want mail to leave as your address instead of `no-reply@orgo.space` * [ ] A written answer to "who should receive what": what goes to everyone, what to one chapter, what to a saved segment * [ ] A decision on language, knowing that automatic email is written in the organization's default language and only English, Romanian and German exist * [ ] `ADMIN_TENANT` on your own account, because every setting below lives in Settings *** ## What to turn on Everything in this table needs `ADMIN_TENANT`, because all of it lives in Settings. | Setting | Where | What it does | | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Enable Email Campaign Module** | Settings → Notifications & Email Campaign → Email Campaigner | Turns on campaigns, campaign templates, Lists & Segments, signup widgets and the email log, and adds the **COMMUNICATION** section to the administration sidebar | | **Default Newsletter Widget UUID** | Settings → Notifications & Email Campaign → Email Campaigner | Which [signup widget](/docs/platform/newsletter-widgets) is served when a page asks for your organization's widget without naming one | | **Notification Preferences** (Newsletter Notifications, Push Notifications, Email Notifications: Comments / Tasks / Votes / Events / Discussions / Mentions) | Settings → Notifications & Email Campaign → Notification Preferences | The defaults new members are created with. They are seeds applied once, not overrides. See [Notifications](/docs/platform/notifications) | | **Emails Config** category switches | Settings → Notifications & Email Campaign → Emails Config | Switches whole categories of automatic email on or off. See [System emails](/docs/platform/emails/system-emails) | | **Email Templates** | Settings → Notifications & Email Campaign → Email Templates | Rewrites the subject and body of one automatic email, with a per-template **Enabled** switch. See [Email templates](/docs/platform/emails/email-templates) | | **Enable Discussions Module** and **Who Can Create Public Discussions** | Settings → Discussions | The in-app forum, and whether the organization-wide feed is open to everyone or an announcement channel. See [Discussions](/docs/platform/discussion) | | **Enable Profanity Check** | Settings → Discussions | Holds flagged posts for review and adds **Moderation queue** to the COMMUNICATION menu for `COMMUNICATION_TENANT`. See [Moderation](/docs/platform/discussion/moderation) | | **Enable Multi-language Support** and the default language | Settings → Customization → Languages | The interface languages members can choose, and the language automatic email is written in. See [Languages](/docs/platform/customization/languages) | | **Contact email** | Settings → Organisation | Becomes the Reply-To on every email, and the From address once Orgo has verified it for sending. See [Emails](/docs/platform/emails) | ### Who does the day-to-day work The module settings above are admin work you do once. Sending is a separate set of permissions, assigned per person. See [Assigning permissions](/docs/platform/permissions-assigning). | Permission | What it unlocks | | ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `COMMUNICATION_TENANT` | Campaigns for the whole organization, campaign templates, Lists & Segments, signup widgets, moderation queue. Covers everything `COMMUNICATION_LOCAL` does | | `COMMUNICATION_LOCAL` | **Email campaigns** for the local centers they manage, and only the **Members from a group** audience. Lists, tenant-wide audiences and event audiences are hidden from them | | `COMMUNICATION_PARENT_LOCAL` | The same as `COMMUNICATION_LOCAL`, extended to every center below their anchor center, at any depth | | `EVENT_TENANT` | Campaigns attached to an event, and signup widgets | | `HR_TENANT` | Creating and editing lists, alongside `COMMUNICATION_TENANT` | | `ADMIN_TENANT` | All settings above, the [email log](/docs/platform/emails/email-log), and adding or removing individual people on a manual list | Adding and removing people on a manual list needs `ADMIN_TENANT`, one level higher than everything else on the Lists screen. A `COMMUNICATION_TENANT` holder sees the **Add**, **Add CSV** and remove buttons and gets refused when using them. If someone maintains manual lists, give them `ADMIN_TENANT`. *** ## Setup order Do these in order. Steps 1 and 2 change what every later email looks like, so doing them last means resending things. The three settings screens in steps 3, 5 and 6 have no Save button. Each switch saves as you flip it and a **Saving** indicator appears while it does. Set your contact email under **Settings** → **Organisation**, then ask support to verify it for sending. Verification needs DNS records on your domain, so it is not a switch you can flip in Settings yourself. Until it is verified, mail leaves as `no-reply@orgo.space` with your contact address as Reply-To. See [Emails](/docs/platform/emails). **Done when** mail your members receive arrives from your own address rather than `no-reply@orgo.space`. **Settings** → **Customization** → **Languages**. Automatic email is written in the organization's default language, not the recipient's, and only English, Romanian and German exist. Anything else falls back to English. See [Languages](/docs/platform/customization/languages). **Done when** the default language on that screen is the language you want every automatic email written in. **Settings** → **Notifications & Email Campaign** → **Emails Config** groups every automatic email into categories (User Lifecycle, Membership & Fees, Adhesion and the rest) with a switch each. Walk them before you invite anyone, so members do not receive a reminder ladder you have not read. See [System emails](/docs/platform/emails/system-emails). Emails Config screen with the Notifications and Email Campaign menu on the left and switch rows grouped under User Lifecycle, Membership and Fees, and Adhesion or Applications **Done when** every category is on deliberately or off deliberately, rather than on because nobody looked. **Email Templates**, in the same menu, gives you the subject and body of one automatic email at a time, with placeholders and a per-template **Enabled** switch. Note that a customized template has no language: your version is used for every recipient. See [Email templates](/docs/platform/emails/email-templates). **Done when** the emails a new member meets in their first week read like your organization wrote them. **Notification Preferences**, same menu. These are the settings new accounts are created with: newsletter, push, and email for comments, tasks, votes, events, mentions and discussions. They are applied once, at account creation. Changing them later does nothing for anyone who already exists, so get them right first. See [Notifications](/docs/platform/notifications). Default Notification Preferences with switches for newsletter, push, comments, tasks, votes, events and mentions, and a Daily frequency selector for discussions **Done when** the switches describe what a brand-new member should be signed up for. Everyone already imported keeps whatever they have. **Settings** → **Notifications & Email Campaign** → **Email Campaigner** → **Enable Email Campaign Module**, then grant `COMMUNICATION_TENANT` to whoever writes campaigns. See [Newsletter](/docs/platform/newsletter). Email Campaigner settings with the Enable Email Campaign Module switch turned on and a Newsletter Management section holding the Default Newsletter Widget UUID field **Done when** a **COMMUNICATION** section appears in the administration sidebar for the people you granted the permission to. **Administration** → **COMMUNICATION** → **Lists & Segments**. A saved list is the only audience you can define by a question about the people themselves. See [Lists & Segments](/docs/platform/users/lists) for the criteria, and [Email lists](/docs/platform/emails/email-lists) for how a list behaves once email starts moving. Lists and Segments page with All, Dynamic and Static filters and a table of lists showing type, audience, and separate Subscribed and Total columns **Done when** each list shows a **Subscribed** count beside its **Total**. The subscribed number is the one a campaign actually sends to. Embed a [signup widget](/docs/platform/newsletter-widgets) so new subscribers land in Orgo as contacts rather than in a spreadsheet. Set **Default Newsletter Widget UUID** on the Email Campaigner screen to decide which widget is served when a page asks for your organization's widget without naming one. **Done when** a test signup on your own site appears in Orgo as a contact. Open any draft campaign and switch to the **Content** tab: that is the drag-and-drop [newsletter builder](/docs/platform/newsletter-builder). Build the house style once, then save it as a campaign template so month two is a copy rather than a rebuild. Newsletter builder on the Content tab with the design canvas in the middle, a palette of Columns, Button, Heading, Image and other blocks on the right, and Save, Send test to your email and Send in the header **Done when** the design is listed under **Campaign templates** and the Content tab shows **Saved** rather than **Saving**. **Send test to your email**, in the campaign header, renders the placeholders against your own record, which is the only reliable way to catch an empty field. Then **Send**, or set a time on the **Schedule** tab at least 2 minutes ahead on a 15-minute boundary. See [Newsletter](/docs/platform/newsletter). **Done when** the campaign shows **Sent** and its Report tab starts filling in as delivery events arrive. *** ## Choosing the right channel The most useful table on this page. Find the row that matches what you are about to send, then check the last column before you write it. | Channel | Use it for | Who receives it | Can a member opt out | | ------------------------ | ----------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- | | **Newsletter campaign** | A deliberate one-way announcement to a chosen audience | Active members with an email address and newsletter email on, plus subscribed contacts, narrowed by the audience you picked | Yes. Every campaign carries an unsubscribe link and one-click unsubscribe headers | | **Discussion post** | Two-way conversation inside a group, role group or local center | Members who can see that group. Notification email depends on their own preference | Yes. Mute the group, or set discussions to Daily, Weekly or off | | **Notification, in-app** | Telling someone that something happened to them | The people the event concerns, and followers of the group | No. The record is always stored and always visible under the bell | | **Notification, email** | The same events, in an inbox | The subset of notification types that email at all: discussions, comments and replies, mentions, events, votes, tasks and membership changes | Partly. Each category has a member toggle, except membership and role changes, which always email | | **Notification, push** | Time-sensitive nudges to a phone or browser | Members with **Push notification subscribed** on and a registered device. Everything except file uploads | Yes, one master switch | | **System email** | One person's own membership, payment, ticket, document or account | The person the event is about, whatever their subscription state | No. Only an admin can silence one, per category or per template | Two rules follow from that table. Anything that is about the individual (their fee, their ticket, their password) is a system email and must not be reproduced as a campaign. Anything that is a conversation belongs in discussions, because a campaign has no reply path beyond your Reply-To mailbox. *** ## Recipes Worked examples, not defaults. Adapt the criteria and names. ### Example 1: a monthly member newsletter to a saved segment **Administration** → **COMMUNICATION** → **Lists & Segments** → create an **Automated by criteria** list, profile type **Members Only**, member status **Active Only**. Add criteria; they always combine with AND. Needs `COMMUNICATION_TENANT` or `HR_TENANT`. Build the layout once in the [builder](/docs/platform/newsletter-builder) and save it under **Campaign templates**, so month two is a copy rather than a rebuild. **Email campaigns** → new campaign. On the **Configure** tab, campaign title is internal and email subject is what members see. In **Recipients**, choose **From a list** and pick your segment. The number next to the option is the subscribed count, not the list total. Campaign Configure tab with campaign title, email subject, sender name and reply-to fields above a Recipients card offering All members and contacts, Members from a group, All subscribed contacts, From a list, and Event attendees Only one option can be selected. Audiences cannot be combined, which is the reason the segment exists. **Send test to your email**, then schedule at least 2 minutes ahead on a 15-minute boundary. Because the list is automated, it is resolved again at send time, so members who joined since you drafted are included. **Duplicate campaign** on last month's send, or **Start Campaign** from the template. Both keep the settings so only the content changes. ### Example 2: an announcement to one chapter only They see **Email campaigns** and nothing else in the COMMUNICATION section, and inside a campaign only the **Members from a group** audience. Tenant-wide audiences, saved lists and event audiences are hidden. A local center, group or role group they manage. Members outside their center cannot be reached: the center boundary is applied again when the send is resolved, on top of whatever audience was chosen. A `COMMUNICATION_TENANT` holder gets the same result two ways: **Members from a group** pointed at that local center, or **All members and contacts** narrowed with the local center dropdown. ### Example 3: an event follow-up to the people who did not open it **Send email for participants** on the event files the campaign under that event's messages and unlocks the event placeholders (`{eventTitle}`, `{eventDateBegin}`, `{eventRegisterUrl}` and the rest). Needs `EVENT_TENANT`, or a communication permission. A sent campaign opens on its **Report** tab: Sent, Opened, Clicks, Bounce and Unsubscribed, each with the percentage underneath, over a campaign details card recording the subject, sender, audience and send date. Campaign report showing Sent 50 at 100 percent delivered, Opened 25 at 50 percent of sent, Clicks 6 at 12 percent of sent, Bounce 1 at 2 percent and Unsubscribed 0, above a campaign details card with subject, sender, recipients, author and sent date Open rates need the mail client to load images, so give it a day or two before treating an unopened message as unread. On the sent campaign, **Follow up with non-openers** (the count is in the button) creates a draft named "Follow-up: ..." locked to people who received the original and never opened it, minus anyone who bounced, complained or unsubscribed. The button sits in the campaign header next to **Duplicate campaign**, and only while that count is above zero. A campaign everyone opened does not offer it. The audience is recalculated at send time, so late openers drop out. If nobody is left, Orgo refuses both the copy and the send. An **Event attendees** audience does not check the newsletter subscription flag. Registered members and external registrants receive it even if they unsubscribed from campaigns, because event mail is treated as informational. Use it for logistics, not for marketing. *** ## Deliverability and consent Four things a customer has to get right. **Verified sender identity.** The From address is your contact email only after Orgo has verified it, which needs DNS records on your domain and is done by support rather than in Settings. Until then mail leaves as `no-reply@orgo.space`. Reply-To is your contact email either way, verified or not. A [custom domain](/docs/platform/custom-domain) hands you the DKIM records and the two `bounce.` records that make SPF align with your own domain; the DMARC policy and the SPF record on your apex remain yours to maintain. **Unsubscribe handling.** Campaign email carries one-click unsubscribe headers, so a member can opt out from the mail client without opening the message. If your design contains no `{unsubscribeUrl}`, Orgo appends an unsubscribe footer before sending. You cannot re-subscribe someone on their behalf. An unsubscribe applies to every account sharing that email address, in every Orgo workspace, because it matches on the address rather than the account. **Which sends ignore subscription flags.** Three cases, all deliberate: * **System emails.** A renewal reminder, invoice or ticket confirmation goes to the person it concerns whether or not they unsubscribed and whether or not they are in any list. Only the Emails Config category switch or the per-template **Enabled** switch stops one. * **Event attendee campaigns.** As above, the subscription flag is not consulted. * **Membership and role change notifications.** When an admin adds someone to a group or changes their roles, the member is emailed and no preference switches it off. **Language.** Automatic email follows the organization's default language, clamped to English, Romanian or German, and a template you customize yourself has no language at all: your version reaches every recipient. The [invoice email and the PDF it carries](/docs/platform/fees/invoices) are the exception: they cover all 14 interface languages, falling back to English only when the organization default is not one of them. Campaigns are whatever language you wrote them in, so a bilingual organization either writes both versions into one email or sends one campaign per language segment. A `?lang=` parameter on a link opens the platform in that language regardless. *** ## Limits worth knowing before you start | Limit | Detail | | ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------ | | One audience per campaign | Audiences are single-choice and cannot be combined. To reach two groups, send twice or build a list | | List criteria are AND only | No OR and no grouping, and no criterion for name or email address | | No automation and no A/B testing | Campaigns are composed and sent or scheduled. There are no drip sequences, no variants and no send-time optimization | | Send pacing | Recipients are resolved in chunks of 2,000 and dispatched at three emails per second per worker, so a large send lands over minutes | | Scheduling granularity | At least 2 minutes ahead and on a 15-minute boundary (:00, :15, :30, :45), because the scheduler runs every 15 minutes | | Digests cover discussions only | A digest carries at most 10 unread items and only discussion notifications. Events, mentions, votes and tasks are instant or nothing | | Notification retention | Notifications older than two months are deleted nightly. The [email log](/docs/platform/emails/email-log) is the durable record | | Customized templates are single-language | Saving your own version of a system email replaces it for every recipient in every language | | Manual list membership is ADMIN\_TENANT | Higher than the rest of the Lists screen | | Demo organizations never send notification email | Expected on a trial workspace, not a fault | *** ## Troubleshooting Take these in order. * Open the campaign's **Report** tab. Sent counts recipients with a delivered or bounced event from the mail provider, so a Sent figure of zero means nothing left the platform, and a high bounce figure means it left and was rejected. * Check the recipient count on the audience. A list of 900 with 620 subscribed sends to 620, and an audience whose members are all inactive or have no email address resolves to nobody. * If the campaign belongs to a local center, remember the center boundary is applied on top of the audience, so a tenant-wide list can resolve to a handful of people. * Check whether the send is still in flight. Recipients go out at three per second per worker, so a large campaign is still arriving for several minutes after the status changes. Answer it with the [email log](/docs/platform/emails/email-log) rather than by reasoning about settings. A campaign writes one log entry per recipient, tagged Newsletter and linked to the campaign. * No row at all: they were not in the resolved audience. Check the account is Active, has an email address, and has newsletter email on in their notification settings, since all three are required for every audience except event attendees. * A row with the wrong address: an old address, a typo, or a placeholder address left by a data import. * A row with the right address: it left Orgo. Ask them to check spam and quarantine, and check the campaign report for a bounce or complaint against them. * Subject starting with FAILED: it was queued and could not be delivered after repeated attempts, and the entry records why. Expected, and the most confusing behaviour in this area. Unsubscribe links match on the email address, not on the account, so one click switches that category off for every Orgo account sharing the address, across organizations. The one-click header does the same for all categories at once. The fix is to turn the categories back on per account, on each affected profile's **Notifications** tab. Nothing else is needed: the person is not removed from any list, and list membership and subscription state are independent of each other. Worth knowing while investigating: opening an unsubscribe URL with a plain GET never unsubscribes anyone. It redirects to the preferences page, so link prefetchers in mail clients cannot opt someone out by accident. A digest run only picks up members with at least one unread **discussion** notification in the window. Comments, events, mentions, votes and task activity never trigger one, so a member whose groups are quiet gets nothing however the frequency is set. Then check, in order: that the member is Active, that their address is valid, that the frequency on their profile actually matches the run (daily looks back 25 hours, weekly looks back 7 days, so someone who chose Weekly just after the weekly run waits almost a week), and that this is not a demo organization, which never sends notification email at all. Also note that sending a digest marks every unread notification read for that member, not only the ones listed in it, so the bell badge clearing is not evidence that they read anything. Work on the individual profile's **Notifications** tab, not on the tenant defaults: the defaults are seeds applied once at account creation and changing them does nothing for anyone who already exists. Set **New discussion** to Daily or Weekly first, since discussions are usually the bulk and the only category that batches. Then switch off the individual categories they object to. If the volume persists, the traffic is coming from something with no toggle: membership and role changes always email, and system email follows the Emails Config switches instead of member preferences. There is no override, by design. Unsubscribing stops campaigns, and no audience except event attendees ignores it. If the message is genuinely about the recipient's own membership (a fee change, a governance obligation), it belongs in the system email that already covers that event, or in a new one, rather than in a campaign that consent rules exclude people from. *** ## Setup checklist The setup order above, in the form you can tick off. Two lines are conditional: the manual-list permission only matters if you keep manual lists, and the widget only matters if you collect subscribers from a website. * [ ] Contact email set under **Settings** → **Organisation**, and verification requested from support * [ ] Default language set under **Settings** → **Customization** → **Languages** * [ ] Every **Emails Config** category reviewed and switched on or off deliberately * [ ] Templates that did not sound like you rewritten under **Email Templates** * [ ] **Notification Preferences** set before any member import, since they apply only at account creation * [ ] **Enable Email Campaign Module** on, and `COMMUNICATION_TENANT` granted to whoever writes campaigns * [ ] `ADMIN_TENANT` given to anyone who maintains manual list membership * [ ] The lists and segments you will reuse built, each showing a subscribed count * [ ] A signup widget embedded on your website, and **Default Newsletter Widget UUID** pointed at it * [ ] One house-style design saved under **Campaign templates** * [ ] A test send checked in your own inbox, with every placeholder filled in *** ## Related * [Newsletter](/docs/platform/newsletter) - composing, audiences, sending and campaign reporting * [Emails](/docs/platform/emails) - sender identity, language and how a message gets sent * [Notifications](/docs/platform/notifications) - in-app, push and email delivery, and member preferences * [Lists & Segments](/docs/platform/users/lists) - building the audiences campaigns send to * [Discussions](/docs/platform/discussion) - the two-way channel, and where most notifications come from # Orgo for federations and multi-tier organizations Source: https://orgo.space/docs/platform/templates/federations A playbook for associations whose members are companies and institutions: the company record, seats, company billing and invoices, and an optional chapter tier **Built for** associations whose members are organizations rather than individuals: trade associations, chambers of commerce, industry bodies, employer federations, and federations of member organizations. **Replaces** the member-company spreadsheet, the separate invoicing tool, and the manual list of "who at each member company should get our emails". In Orgo a member company is a **company** record. It holds one membership, it is billed as one customer, and the people who work there attach to it and inherit its membership validity. Everything on this page is built on that: the company record first, then billing and invoices, then a geographic tier only if your federation has one. Your member roster lives under **Companies** in the sidebar. Each row carries the status, the seats used against the allowance, and the valid-until date, so the health of your membership is one screen. Companies list with search, status filters showing counts for All, Active, Pending and Inactive, and rows showing member count and valid-until date *** ## Before you start Five decisions carry the whole setup. Settle them on paper first: each one becomes a field, a switch or a price row later, and reversing some of them means re-billing your members. * [ ] Legal entity details collected for every member company: legal name, registration number, VAT number, billing address, town and country * [ ] Seat policy decided: how many named people each corporate tier includes, and which tier (if any) is unlimited * [ ] Invoicing direction agreed: your organization bills each member company centrally, because company fees never route to a region * [ ] Payment method chosen: card through Stripe, bank transfer against an invoice, or an administrator recording money received elsewhere * [ ] Primary contact named per company, plus the financial contact email that will receive the renewal ladder The one that bites later is the seat policy. Seats are not typed in on a company: they arrive from the price the company buys. The tier list you design now is the seat list you live with, and changing a company's allowance means moving it to another tier and taking a payment. *** ## Who this is for Use this playbook when the entity that joins, pays and renews is an organization, and the people are attached to it: * a trade or industry association billing member firms an annual corporate fee; * a chamber of commerce with tiered corporate memberships and a seat allowance per tier; * an employer federation or umbrella body whose members are other associations; * any body that sells team or corporate memberships alongside, or instead of, individual ones. If your members are individuals who happen to be grouped by geography, you do not need this page. Start at [Chapters](/docs/platform/groups/local-groups) instead. *** ## Modelling your members as companies ### The company record **Companies** in the sidebar, then **Create**. One form, three groups of fields. Only **Company Name** is required to save, but the billing block has to be complete before a payment can start. | Group | Fields | | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Identity | **Company Name**, **Description**, **Website**, **Company Logo** | | Billing Details | **Legal Name**, **Registration Number**, **VAT Number**, **Billing Address**, **Town**, **Country** | | Financial Contact | **Financial contact full name**, **Financial contact email**, **Financial contact phone**, **Additional contact email 1 (Cc)**, **Additional contact email 2 (Cc)** | A company starts at **Pending** and flips to **Active** on its first recorded membership payment. `ADMIN_TENANT` can also set the status by hand. **Delete Company** is a soft delete: the record moves to **Deleted** and disappears from every list, and only `ADMIN_TENANT` can do it. Once saved, the company page becomes the single screen your staff and the member's own primary contact both work from. Reading down the left column and then the right: the status header, the seat counter with the current plan, the **Billing Details** and **Financial Contact** cards, the member list, and the **Payment & Plan** panel. Company record page showing the Active status header, a member counter of 5 of 25 with the plan name, Billing Details and Financial Contact cards, and the Team Members panel ### One company, many people, one membership A membership row inside a company points at either a **User** (someone with an account) or a **[Contact](/docs/platform/contacts)** (a record in your database with no account). Both appear in the member list and both occupy a seat. Only user memberships inherit the company's validity date, because a contact has no fee date to write to. Team Members panel listing five people, one carrying a Primary Contact badge, with Add Member and Invite buttons in the panel header Roles are stored per membership, and one person can hold more than one. | Role | What it grants | | ------------------------- | ------------------------------------------------------------------------------------- | | **Member** | The default. Sees the company page and inherits the membership validity | | **Primary Contact** | Edits the company, manages members and invitations, and pays. At most one per company | | **Voting Representative** | A label marking who speaks for the company. At most one per company | | **Financial Rep** | Legacy. Same rights as Primary Contact, but no longer assignable from the interface | Assigning **Primary Contact** or **Voting Representative** takes it from whoever held it before, in the same action. An ordinary member belongs to at most one company, and a member cannot be added to a second one. Administrators who create companies on behalf of others are exempt from that rule and are not enrolled in what they create. ### Seats, and what happens when they run out Seats are not typed in on the company. They come from the fee price the company bought: every **Company only** price carries a **Company slots** number, and paying for that price writes the number onto the company. **0 means unlimited.** The count is active members plus pending invitations, so an outstanding invitation holds a place. Memberships that have ended, and those whose user was deleted, are not counted. When the allowance is full, **Invite** and **Add Member** disappear from the company page. ### How an employee joins Three routes, and you will use all three: invitations for new names, **Add Member** for people already in your database, and automatic domain matching for the ones who turn up at your events. Open the company, then press **Invite** in the header of the **Team Members** panel. Fill in the email, first name, last name and role, and add a message if you want one. Both names are labelled optional in the dialog but the server rejects the invitation without them, so treat them as required. The email links to `/company-invitation/{hash}`. Accepting joins the person to the company and emails them a one-time login code, creating the account first if they have none. Invitations expire after **30 days** and can be resent (which resets the 30 days) or revoked. **Done when** the person appears in the **Team Members** panel with a pending invitation, and the seat counter at the top of the company has gone up by one. Invite Member dialog with Email, First Name and Last Name fields, a Role dropdown and a Message box, over the company page Press **Add Member** in the same panel header and search. The picker only returns users and contacts that are not already in a company. The button is shown to `ADMIN_TENANT` only, and only while seats are free. **Done when** the person is listed as **Active** in **Team Members** straight away, with no invitation email involved. Nothing to press. With the Companies module on, somebody registering for an event whose email domain matches the **Website** of an **Active** company is added to that company automatically. Common free providers (gmail.com, outlook.com and similar) are excluded, subdomains are reduced to the base domain, and the company's validity date is copied onto them if it has one. This runs on event registration only, and it does not check seats. **Done when** an event registrant from a member firm shows up in that company's member list without anyone inviting them. An invitation is refused up front when there are no free seats, when one is already pending for that email, or when the person already belongs to any company. The seat check runs again at acceptance, so an invitation sent before the company filled up can still fail. *** ## What to turn on Every switch below needs `ADMIN_TENANT`, and the Settings screens themselves also need the **Orgo administrator** flag on your profile. See [Permissions](/docs/platform/permissions). ### Companies, first **Settings** → **Modules** → **Companies** → **Configuration** | Setting | What it does | | ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Enable Companies Module** | Adds **Companies** to the sidebar and a **Company** tab to a member's own profile | | **Who can create companies** | **Any member**, **Local center admins and above**, or **Organization admins only**. This also decides who administers companies they do not belong to (see [Permissions](#permissions) below) | | **Enable Company Fees** | Lets companies pay membership fees on behalf of their people. Only appears while the Payments and Fees module is active | Companies module configuration with the Enable Companies Module switch on, a Who can create companies dropdown set to Organization admins only, and Enable Company Fees on with an explanatory note ### Payments and fees **Settings** → **Modules** → **Payments & Fees** | Setting | Tab | What it does | | ------------------------------------------------------------- | --------------- | -------------------------------------------------------------------------------------------------------- | | **Payment Gateway** | Payment Gateway | Connects your organization's Stripe account. See [Stripe Integration](/docs/platform/fees/stripe-integration) | | **Enable Membership Fees** | Membership fees | The master switch for dues | | **Membership Fee Product** / **Default Membership Fee Price** | Membership fees | The product companies are billed against | | **Enable VAT on Fees** | Membership fees | While off, no VAT is added, whatever a price row stores. See [VAT](/docs/platform/fees/vat) | | **Allow Bank Transfer Payments** | Membership fees | Shows your bank details as a payment option | | **Enable Membership Payments via Bank Transfer** | Membership fees | Required, together with Invoices, for the **Get invoice for bank transfer** button on a company | | **Allow Mark as Paid** | Membership fees | Lets an administrator record money received outside the platform | | **Company Fee Payment Mandatory** | Membership fees | Locks company people out of the platform while the company's fee is unpaid | ### Invoices Switch **Invoices** on in **Settings** → **Modules** → **All Modules**, then set **Manual Invoice Product** under **Payments & Fees** → **Invoice Product**. Without that product, invoice creation fails. The same tab holds **Send invoice emails automatically** (on by default) and **Invoice membership fee payments**. ### Chapters, only if you have a geographic tier **Settings** → **Modules** → **Groups & Teams** → **Local Centers** → **Enable Local Centers Module**. Skip this unless the answer to "does a region of ours hold its own members, events and budget?" is yes. See [Adding a geographic tier](#adding-a-geographic-tier-if-you-need-one). *** ## Setup order Work through these in order. Steps 1 to 4 build the money side, 5 turns the member companies on, and 6 to 9 get your real data in and the enforcement switched on last. Go to **Settings** → **Modules** → **Payments & Fees** → **Payment Gateway** and connect your organization's Stripe account. Set a **country** under **Settings** → **Organisation info** first, because Stripe fixes the country when the account is created and it cannot be changed afterwards. **Done when** the Payment Gateway tab shows your account as connected rather than offering the connect button. See [Stripe Integration](/docs/platform/fees/stripe-integration). Go to **Finance** → **Products** → **Create Product** and choose **Membership Fee**. Set **Period** and **Cycle beginning** now: both are locked once saved. A federation billing an annual corporate fee usually wants **Period** annually and a fixed **Cycle beginning** month, so every member company renews together instead of on its own separate anniversary. **Done when** the product opens on its own page with a **Prices & Options** tab, and the period you chose can no longer be edited. On the product's **Prices & Options** tab, press **Add** and create one price per tier. In the price dialog, switch **Company only** on and enter the **Company slots** that tier buys. `0` slots means unlimited. Prices without **Company only** stay available to individual members, so a federation with associate individual members can run both from one product. **Done when** each corporate tier is listed on **Prices & Options** carrying a **Company price** tag, and opening one shows the slot number you typed. Price dialog for a corporate tier with the Company only switch on and a Company slots field set to 25, above the hint that 0 means unlimited slots Go to **Settings** → **Modules** → **Payments & Fees** → **Membership fees**. Switch **Enable Membership Fees** on, then pick your **Membership Fee Product** and a **Default Membership Fee Price**. Nothing charges until the product is selected here, however complete the product itself looks. **Done when** the **Product Configuration** card names your product and a default price, and a company's **Payment & Plan** panel starts listing tiers instead of sitting empty. Membership fees settings with Enable Membership Fees on, a Product Configuration card naming the membership fee product and default price, and the payment options below Go to **Settings** → **Modules** → **Companies** → **Configuration**. Switch **Enable Companies Module** on, choose **Who can create companies**, then switch **Enable Company Fees** on. Read [Permissions](#permissions) before you pick the **Who can create companies** value: it quietly decides who can administer companies they do not belong to. **Done when** **Companies** appears in the sidebar and the **Enable Company Fees** switch shows its "How company fees work" note underneath. Switch **Invoices** on under **Settings** → **Modules** → **All Modules**, then set a **Manual Invoice Product** under **Payments & Fees** → **Invoice Product**. Do this before you import companies, so the first renewal round can attach invoices. Without that product, invoice creation fails outright. **Done when** the **Invoices** list is reachable and creating a manual invoice no longer errors. See [Invoices](/docs/platform/fees/invoices). Go to **Settings** → **Import**. It offers **Companies** (with membership details) and **Company Members** (assigning users to companies with roles), each with an example CSV. Run **Companies** first, then **Company Members**, so every membership has a company to attach to. **Done when** the **Companies** list shows your real roster with the expected **All** count, and opening one shows its people in **Team Members**. See [Import](/docs/platform/customization/import). On each company, give one person the **Primary Contact** role: that is who pays and who manages the seats. Fill in **Financial contact email** on the **Financial Contact** card too, because it is the address the renewal ladder writes to. **Done when** every company shows a **Primary Contact** badge on exactly one member row, and no company is left with an empty **Financial Contact** card. Leave **Company Fee Payment Mandatory** off until your companies are actually billed and paid. Switching it on with unpaid records blocks their people out on the next page load. **Done when** your first billing round has settled and you have deliberately chosen whether to enforce, rather than discovering the lockout through support tickets. *** ## Billing companies The **Payment & Plan** panel on a company lists every non-archived **Company only** price on your organization's fee product, with its slot count and amount. It is visible to the Primary Contact (and any legacy Financial Rep) and to `ADMIN_TENANT`. The tier the company is on is marked **Current** and carries the action buttons; the others offer **Select** to move the company across. Payment and Plan card listing three corporate tiers with their seat allowance and annual price, Select buttons on the unselected tiers and Pay plus Mark as Paid on the current one ### Where the money goes A company fee checkout always charges **your organization's Stripe account**. There is no chapter routing for company fees and no revenue split: the full amount lands in one account, and any onward distribution to regions or member bodies happens in your own accounting, not in Orgo. Orgo takes no commission of its own; the platform application fee is present in the code but forced to zero on every charge, so what you lose is Stripe's processing fee. ### The three ways a company pays | Route | What happens | Needs | | --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------- | | **Pay online** | Stripe checkout. Membership activates as soon as the payment lands | A connected Stripe account | | **Get invoice for bank transfer** | Generates an unpaid invoice, emails it, and shows a reference to quote on the transfer | **Enable Membership Payments via Bank Transfer** and the Invoices module, both on | | **Mark as Paid** | Records money received outside the platform. Asks for a period start, defaulting to the current expiry so it extends rather than overwrites, and voids any pending bank-transfer invoice | `ADMIN_TENANT` | Before any of them, Orgo checks that **Legal Name**, **Billing Address**, **Financial contact full name** and **Financial contact email** are filled in, and sends you to the edit form if one is missing. **Renewal opens 60 days before the current period ends.** Before that window a company with a valid membership has no Pay button, and the bank-transfer invoice endpoint refuses with "Membership can only be renewed closer to its expiry date." On a calendar-anchored cycle a mid-cycle payment buys only the remainder and is prorated: the panel shows the list price struck through beside the real charge, plus " of months". The amount is always recomputed on the server at checkout, so a stale quote can never undercharge. VAT is added on top of the net price as its own line when **Enable VAT on Fees** is on and the price is not marked exempt. ### Invoices A company only ever has one open renewal invoice. The renewal reminder flow and the **Get invoice for bank transfer** button share it: an unpaid membership invoice matching the current period and plan is reused, a stale one is voided and replaced, and a new one is created otherwise. While the Invoices module is active, the renewal reminder emails carry that invoice as a PDF attachment. Marking a membership invoice paid is what extends the company's membership, which is why the **Membership** switch on a manual invoice matters: an invoice without it is just a document. Every invoice carries a number (the highest used in your organization plus one, never reset) and a five-character series. Voided and refunded invoices keep their number. Full detail in [Invoices](/docs/platform/fees/invoices) and [Cancelling invoices](/docs/platform/fees/cancelling-invoices). ### What a company payment does to its people When a payment lands, Orgo: 1. sets the company's valid-until date, never shortening one that is already further out; 2. sets the company **Active** if it was **Pending**; 3. writes the plan's **Company slots** onto the company; 4. copies the valid-until date onto every active member who has an account. Somebody who joins an already-paid company inherits the date on joining. Somebody removed from a company has their fee date and fee price cleared. A refunded payment rolls the company back to the previous non-refunded period, or clears it entirely, and re-syncs everyone. With **Enable Company Fees** on, anyone who belongs to a company loses their individual fee screen entirely. Their profile **Fee** tab shows "Membership managed by company" with a link to the company, in place of both the organization fee card and the chapter fee card. This happens as soon as they are attached to a company, whether or not the company has paid anything yet. ### When a company fee lapses Companies have their own reminder ladder, separate from the individual one: about a month before expiry, 7 days before, 1 day before, on the expiry day, then 7, 14 and 30 days after. Each goes **To** the **Financial contact email**, copying the active Primary Contacts and the two **Additional contact email** addresses. Without a financial contact email, the first Primary Contact is promoted to the To line, and a company with nobody reachable is skipped. Only **Active** and **Pending** companies are reminded, so setting one to Inactive stops both the reminder and the renewal invoice attached to it. The post-expiry rungs are exact day counts, so a company 3 days lapsed hears nothing that day. With **Company Fee Payment Mandatory** on and the membership lapsed: | Who | Where they land | | --------------------------------------- | ------------------------------------------------------------------------------------------------------ | | Primary Contact or legacy Financial Rep | `/company-fee-payment`, a guided three-step page: Billing Information, Select a Plan, Complete Payment | | Everyone else in the company | `/company-fee-required`, which names the company and points them at the financial contact | The company pages themselves stay reachable, so a locked-out Primary Contact can still edit billing details and pay. The gate exempts `ADMIN_TENANT` and fee-exempt user types, and nothing else. The company gate is stricter than the individual one. The individual mandatory-fee gate lets `HR_TENANT` and `FINANCIAL_TENANT` through; the company gate does not. A staff member of yours who happens to belong to a member company with a lapsed fee is locked out unless they hold `ADMIN_TENANT`. *** ## Adding a geographic tier, if you need one Chapters (called **local centers** in the data model, the API and the permission names) are optional. Turn them on when a region genuinely holds its own members, events, files and budget, and skip them otherwise: they add a permission scope, a second fee, and a second set of admin screens to every screen you already run. **Settings** → **Modules** → **Groups & Teams** → **Local Centers** → **Enable Local Centers Module**. What it changes: | Area | With chapters on | | ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | Members | Every member has exactly one primary chapter. Moving someone is a [transfer request](/docs/platform/groups/transfers), approved by the receiving chapter | | Permissions | The `_LOCAL` family appears on the profile permission panel, scoped to the holder's chapter. **Enable Parent Centers** adds the `_PARENT_LOCAL` family on top | | Structure above a chapter | **Enable Parent Centers** lets a chapter sit under another chapter, to any depth. A national body holding regions holding member bodies is three layers of one tree, not three products | | Fees | **Local Center Fees Enabled** gives each chapter its own fee product, default price and validity date, independent of the organization fee. See [Chapter Fees](/docs/platform/local-group-fees/create-local-fees) | | Money | A chapter that connects its own Stripe account receives its own chapter fee payments. Without one, they fall back to the organization account | | Structure below a chapter | **Enable Organizational Units** adds typed, nestable teams inside a chapter. See [Units](/docs/platform/groups/units) | Chapters and companies do not meet. A company record has no chapter field, a company fee is never routed to a chapter Stripe account, and chapter fee screens work on individual members, not on companies. If your regions need their own income from member companies, either bill it centrally and distribute it in your accounting, or give each region its own corporate tier and reconcile from the payment records. If your federation has tiers (a national body, its regions, their member bodies), build them as chapters nested inside each other rather than as regions or groups. **Enable Parent Centers**, flag each chapter that holds others with **It's a parent chapter**, then set **Belongs to parent chapter** on the ones below it. A chapter can be both at once, which is what makes a middle tier possible. Moving a chapter later requires `HR_TENANT`, because the link decides who administers the branch. Two grouping tools that are not chapters and are worth knowing before you build a hierarchy you cannot undo: * **Regions** (**Enable Regions**) are a flat label on a chapter, used for filtering and grouping. They grant nothing on their own, and they are not a layer of the chapter tree. * **[Role groups](/docs/platform/groups/role-groups)** are spaces whose membership is a query over roles, age, gender, region or fee tier, recalculated as your data changes. They are the right tool for "every Primary Contact" or "every company representative in the north", and the wrong tool for a permanent tier of your organization. *** ## Permissions Company access is decided by a company-specific check, not by the chapter permission family. | Action | Who | | ----------------------------------------------------- | ------------------------------------------------------------------------------------------------------ | | See a company | Any active member of that company | | Edit the company record | Primary Contact, legacy Financial Rep | | Add, remove and re-role members | Primary Contact, legacy Financial Rep. **Add Member** in the interface is shown to `ADMIN_TENANT` only | | Send, resend and revoke invitations | Primary Contact, legacy Financial Rep | | Select a plan, pay, request the bank-transfer invoice | Primary Contact, legacy Financial Rep | | **Mark as Paid** | `ADMIN_TENANT` | | Change company status | `ADMIN_TENANT` | | Delete a company | `ADMIN_TENANT` | | Open **Settings** at all | `ADMIN_TENANT`, plus the **Orgo administrator** flag | On top of that there is one bypass, and it is the setting people get wrong: **Who can create companies** also decides who administers companies they do not belong to, floored at `ADMIN_LOCAL`. | **Who can create companies** | Who can then view, edit, manage members and pay on *every* company | | --------------------------------- | --------------------------------------------------------------------------------------------------------------- | | **Any member** | Anyone holding `ADMIN_LOCAL` or above (the floor keeps ordinary members out of companies they do not belong to) | | **Local center admins and above** | Anyone holding `ADMIN_LOCAL` or above | | **Organization admins only** | `ADMIN_TENANT` only | Because a company has no chapter, that `ADMIN_LOCAL` check is not scoped to anything: a chapter admin who qualifies reaches every company in the organization, not the ones "in their area". Set **Who can create companies** to **Organization admins only** if that is not what you want. Two more things worth knowing before you delegate: * The **Company** tab appears on a member's **own** profile only. An administrator looking at somebody else's profile cannot see which company they belong to from there; go through the company record, or read the fee column on the members list. * Renewal correspondence follows the company record, not permissions. Whoever is in **Financial contact email** and **Additional contact email 1 and 2** receives the ladder, regardless of what they can do in the platform. *** ## Reporting | Question | Where | | --------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | How many member companies, by status | **Companies** list. The **All**, **Active**, **Pending** and **Inactive** filters carry live counts, and each row shows seats used against the allowance and the valid-until date | | Which companies have lapsed | The same list: sort or scan the **Valid until** column, and filter on **Active** to separate paid from **Pending** | | Who is in a company, and which of them are contacts | The company page member list. Contacts are tagged and link to the contact record | | What a member is billed at | **Members** list, **fee** column. For anyone in a company it shows the *company's* tier rather than their own, even while the company is **Pending** or its fee is unpaid | | Invoices and their state | **Invoices** list, searchable by customer name, invoice number, series and internal id, filterable by status | | Anything else, in plain language | **Ask Orgo** (`ADMIN_TENANT`). Its catalogue includes companies and company membership, payments, invoices and subscription profiles, and results export to CSV. See [Insights](/docs/platform/insights) | | Who voted, by company | Vote exports carry a **Company** column while the Companies module is on. See [E-voting](/docs/platform/e-voting) | The Analytics dashboards have no company dimension. Members, geography, leaderboards, platform and finance all count individuals and money, not member organizations. For "revenue by member company" or "companies renewed this quarter", use Ask Orgo or the invoice list. If you also run chapters, **Finance** → **Stats** (route `/fee/stats`, `FINANCIAL_TENANT`) adds a fees-by-chapter table: chapter, status, active member count and fees paid for a chosen period, with chapters under **Minimum Members per Local Center** or **Minimum Active Members Percentage** highlighted for `ADMIN_TENANT`. *** ## Limits worth knowing before you start * **A person belongs to at most one company.** There is no way to attach somebody to two member companies, and an invitation to a second one is refused. * **Companies are organization-wide.** A company has no chapter field, so it cannot be owned by a region, filtered by one, or billed through one. * **Voting Representative is a label.** Nothing in the voting module reads it: every employee with an account votes as an individual, and there is no one-company-one-vote weighting. * **Contacts occupy seats but inherit nothing.** A contact has no fee date, so company membership sync skips them. Use contacts for people you communicate with, not for people who need to sign in. * **Domain matching ignores the seat allowance.** An event registration that matches a company's website domain adds the person even when the company is full, so a company can end up over its allowance without anyone acting. * **Company fees replace individual fees entirely for those people.** There is no "company pays half" arrangement, and no way to leave an individual fee in place beside a company one. * **One Stripe account for company money.** Company fees never route to a chapter account, and Orgo performs no split between tiers. * **Renewal is windowed.** A company cannot pay several periods in advance: the Pay button and the bank-transfer invoice both wait for the 60 day window. * **The company gate is all or nothing.** With **Company Fee Payment Mandatory** on, only `ADMIN_TENANT` and fee-exempt user types are spared. *** ## Setup checklist Work down this list once and your federation is live. Each line is an outcome you can see on screen, in the same order as [Setup order](#setup-order) above. * [ ] Organization country set under **Organisation info**, and Stripe connected on the **Payment Gateway** tab * [ ] Membership fee product created with the right **Period** and **Cycle beginning** (both lock on save) * [ ] Company fee prices created on that product: one **Company only** price per corporate tier, each carrying its own **Company slots** allowance * [ ] Organization pointed at the product: **Enable Membership Fees** on, with a **Membership Fee Product** and a **Default Membership Fee Price** selected * [ ] Companies module on, **Who can create companies** deliberately chosen, and **Enable Company Fees** on * [ ] Invoices module on and a **Manual Invoice Product** set, so renewal reminders can carry a PDF * [ ] Member companies imported, each with legal name, billing address and VAT number filled in * [ ] One **Primary Contact** named per company, and a **Financial contact email** on every **Financial Contact** card * [ ] Employees invited or added, with each company's seat counter below its allowance * [ ] First billing round settled, then **Company Fee Payment Mandatory** switched on or left off as a decision *** ## Troubleshooting Three separate causes, in the order worth checking. The payment may not have been recorded as one: a **Get invoice for bank transfer** invoice sits unpaid until somebody marks it paid, and nothing propagates before that. The people may be contacts rather than users. Membership sync writes the company's valid-until date onto members who have an account, and skips contact rows, which have no fee date to write to. They still occupy seats and still show in the member list. Or they joined after the payment through a path that did not sync. Invitations, **Add Member** and domain matching all copy the company's date on joining, so this should be rare; if you see it, re-record the payment with **Mark as Paid** starting at the current expiry, which re-syncs everybody. The most common reason is the renewal window. Renewal opens 60 days before the current period ends, so a company that paid two months ago has no Pay button and is not meant to. After that, check that a plan is selected: the panel needs a **Company only** price chosen before it can quote or charge. And check who is looking. The panel renders for the Primary Contact, the legacy Financial Rep and `ADMIN_TENANT`; an ordinary employee never sees it. It needs four things at once: **Enable Membership Payments via Bank Transfer** on, the Invoices module active, a plan selected on the company, and the renewal window open. Each missing one produces its own refusal message rather than a silent failure. If it works but the company says nothing arrived, check the addresses on the company record. The invoice email goes to the company contact address with the two **Additional contact email** addresses copied in, and if none is set, nothing is sent. The seat allowance is full. The count is active members plus pending invitations, so outstanding invitations are the usual culprit: revoke the ones that will never be accepted and the buttons come back. Seats come from the plan, not from a field you can edit. To give a company more room, move it to a tier with a larger **Company slots** value and take the payment; the new number is written on when the payment is recorded. A tier with `0` slots is unlimited. That is email domain matching. When somebody registers for an event and their email domain matches the **Website** of an **Active** company, Orgo attaches them to that company and copies its validity date onto them. It is deliberate, and for a federation it is usually what you want: an employee of a member firm registering for a conference is recognised as covered by that firm's membership. It has two edges. It ignores the seat allowance, so a full company can go over. And it depends entirely on the **Website** field being right, so a company whose website is recorded as a shared portal or a marketing domain can collect people who do not work there. Correct the **Website** on the company, then remove the wrong memberships. Free email providers are excluded, so nobody is ever matched by a gmail.com or outlook.com address. The company lockout exempts `ADMIN_TENANT` and fee-exempt user types, and nobody else. The individual mandatory-fee gate is more forgiving (it lets `HR_TENANT` and `FINANCIAL_TENANT` through), which is why this only bites on the company side. If the person genuinely belongs to a member company, the honest fix is to settle that company's fee. If they were attached to a company by mistake, or by domain matching, remove the membership: that clears their fee date and fee price, and the individual rules take over again. They cannot, and the platform is deliberate about it. With **Enable Company Fees** on, anyone attached to a company sees "Membership managed by company" in place of the whole fee area, including the chapter fee card when chapters are on. If a company covers only some of its people, do not attach the rest to the company record. Keep them as ordinary members on an individual price, and use a [private group](/docs/platform/groups/private-groups) or a [role group](/docs/platform/groups/role-groups) if you still want them grouped by employer for communication. Not as a company fee. Chapter fees are individual: they resolve from a member's own chapter and their chapter fee tier, and a company has no chapter at all. A chapter's own Stripe account receives chapter fee payments from members, never company fees. Two workable shapes. Bill everything centrally and distribute in your accounting, which is what most federations end up doing. Or create a corporate tier per region on the organization fee product, so the payment record itself names the region and you can report on it, while the money still settles in the organization account. No. **Voting Representative** is a label on a company membership and nothing outside the company screens reads it. Voting eligibility is per person, so every employee with an account can vote on a session they are eligible for. The closest you can get is procedural: name the representative on the company so the record is unambiguous, and restrict the vote's audience to a [role group](/docs/platform/groups/role-groups) or private group holding one person per company. Vote exports carry a **Company** column, so you can check afterwards that nobody's firm voted twice. The **Company** tab is rendered on your own profile only, so an administrator opening somebody else's profile does not get it. This is a display rule, not a permission: nothing is hidden from them elsewhere. Two ways round it. The **fee** column on the members list shows the company's tier for anybody in a company, so the tier name is a reliable tell. And Ask Orgo has both companies and company memberships in its catalogue, so "which company is X in" and "list every member with their company" both answer. Deleting is a soft delete: the record moves to **Deleted** and drops out of every list, but the memberships attached to it are not unwound, so the people keep the validity date they inherited until it expires on its own. Remove the members first, which clears each person's fee date and fee price, then delete the company. If it is already done, correct the affected people from their own fee tab or with a recorded payment. *** ## Related * [Companies](/docs/platform/users/companies) - the full company record, roles, seats and invitations * [Membership Fees](/docs/platform/fees/fees) - cycles, proration, validity and the mandatory-fee settings * [Products](/docs/platform/fees/products) - fee products, **Company only** prices and **Company slots** * [Invoices](/docs/platform/fees/invoices) - numbering, templates, and getting the document to the payer * [Stripe Integration](/docs/platform/fees/stripe-integration) - which account receives what, and what breaks without it * [Chapters](/docs/platform/groups/local-groups) - the optional geographic tier and its permission scopes # Orgo for fundraising Source: https://orgo.space/docs/platform/templates/fundraising Which modules to enable, in what order, to run one-off gifts, recurring giving, campaign pages and donor reporting on Orgo This template is for organisations whose money comes from supporters giving voluntarily, whether or not those supporters are members: nonprofits, foundations, faith communities, alumni networks, advocacy groups. It assumes you already have an Orgo workspace and want to know which parts of it fundraising actually uses. It routes rather than explains. Each step links to the page that covers it in depth, so read this once to get the order right, then work from the feature pages. *** ## Before you start Gather these before you open Orgo. Every one of them is asked for during setup, and stopping halfway to find a bank statement or write a thank-you message is how half-built campaigns end up published. * [ ] A Stripe account you can sign into, or the legal entity and bank details to create one during setup * [ ] Your organisation's country, which Stripe fixes at account creation and cannot change afterwards * [ ] Campaign copy written: a title, a short story, and the thank-you message donors read after paying * [ ] A hero image, or the URL of a hero video * [ ] A decision on suggested amounts: the figures you want offered, or a plan to press **Generate** and start from what Orgo proposes * [ ] A decision on frequency: one-off gifts, monthly giving, or both * [ ] Someone with `ADMIN_TENANT` to change the settings, and someone with `FINANCIAL_TENANT` to build the campaign *** ## What to turn on Everything in this table lives under **Settings**. Module settings pages all require `ADMIN_TENANT`, which is what the permission column says when the setting itself is what you are changing. | What | Exact label | Where | Permission | | ------------------------------------------- | ----------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------- | | Country on the organisation profile | **Country** | **Settings → Organisation info** | `ADMIN_TENANT` | | The payments module | **Enable Online Payments** | **Settings → Modules → Payments & Fees → Online Payments** | `ADMIN_TENANT` | | Stripe account | **Connect existing Stripe account** or **Generate Stripe Account** | **Settings → Modules → Payments & Fees → Payment Gateway** | `ADMIN_TENANT` (organisation), `ADMIN_LOCAL` (chapter) | | Accounts for donors who are not members | **Create Accounts for External Buyers** | **Settings → Modules → Payments & Fees → Online Payments** | `ADMIN_TENANT` | | Phone on the donation form | **Collect Phone at Checkout** | **Settings → Modules → Payments & Fees → Online Payments** | `ADMIN_TENANT` | | Forced confidentiality notice | **Confidentiality Agreement Mandatory** | **Settings → Modules → Payments & Fees → Online Payments** | `ADMIN_TENANT` | | Chapter designations on a campaign | **Products with Local Center Option** | **Settings → Modules → Payments & Fees → Online Payments** | `ADMIN_TENANT` | | Chapters taking their own money | **Local Center Payments**, then **All Local Centers Eligible** or per chapter | **Settings → Modules → Payments & Fees → Online Payments** | `ADMIN_TENANT` | | The default `/donate` campaign | **Donation Product** | **Settings → Modules → Payments & Fees → Donation Product** | `ADMIN_TENANT` | | The campaign that grants the Supporter flag | **Recurring Donation Product** | **Settings → Modules → Payments & Fees → Donation Product** | `ADMIN_TENANT` | | Stripe's own receipt email | **Stripe Email Receipts** | **Settings → Modules → Payments & Fees → Online Payments** | `ADMIN_TENANT` | | The campaign itself | **Create Product**, then the **Donation** card | **Finance → Products** (or **Finance → Local products** for a chapter) | `FINANCIAL_TENANT`, or `FINANCIAL_LOCAL` for a chapter campaign | | Appeal emails | **Enable Email Campaign Module** | **Settings → Modules → Emails & Notifications → Email Campaigner** | `ADMIN_TENANT` to switch on, `COMMUNICATION_TENANT` to send | | Wording of the thank-you email | **Donation thank you** template | **Settings → Modules → Emails & Notifications → Email Templates** | `ADMIN_TENANT` | | Revenue dashboards | analytics module, then **Minimum access level** | **Settings → Modules → All Modules** for the module, **Settings → Modules → Users & Profiles → Security & Permissions** for the access level | `ADMIN_TENANT` to configure, `FINANCIAL_TENANT` to read the Finance tab | Nothing here needs the **Invoices** module. Donation payments cannot be turned into Orgo invoices: see [Limits](#limits-worth-knowing-before-you-start). *** ## Setup order Do these in order. The main reason is Stripe: several controls stay greyed out until an account is connected, and a campaign saved without them needs revisiting. Each step says where in the interface it happens and how you can tell it worked, so you can follow along with Orgo open beside you. Open **Settings → Organisation info**, set **Country**, and save. Stripe needs the country at account creation and it cannot be changed afterwards, so the connect buttons stay disabled until **Settings → Organisation info** has one. **Done when:** the connect buttons on the Payment Gateway page below are clickable rather than greyed out. See [Organisation info](/docs/platform/organisation/organisation-info). Go to **Settings → Modules → Payments & Fees → Payment Gateway** and either **Connect existing Stripe account** or **Generate Stripe Account**. Stripe runs its own onboarding and returns you to this page. Payment Gateway settings showing a connected Stripe account id, a Fully connected badge, a Complete account status, one outstanding requirement, and buttons for View Stripe Dashboard and Change Stripe account **Done when:** the page reads **Fully connected** and **Complete**. Build nothing before it does, because **One-off** and **Recurring** are both unavailable on the campaign form while no account is linked. An entry under **Requirements needed** with a future deadline is normal and does not stop you charging. See [Stripe integration](/docs/platform/fees/stripe-integration). **Settings → Modules → Payments & Fees → Online Payments** holds the switches that shape every donation form you will ever build. Online Payments module settings with the Enable Online Payments switch, Payment Features, a Local Centers group holding Local Center Payments and Products with Local Center Option, and Checkout Settings holding Create Accounts for External Buyers, Collect Phone at Checkout and Confidentiality Agreement Mandatory **Create Accounts for External Buyers**, **Collect Phone at Checkout**, **Confidentiality Agreement Mandatory** and **Products with Local Center Option** are organisation-wide, not per campaign. Setting them now saves rebuilding forms later. **Done when:** each switch reads the way you want it for every campaign, not just the first one. See [Modules](/docs/platform/organisation/modules). **Finance → Products → Create Product**, pick **Donation**, name it, check the URL slug, and turn on **One-off**, **Recurring**, or both. Create Product form with the Donation card selected next to Membership Fee, a campaign title, the URL slug generated from it with the public address preview beneath, the Recurring and One-off frequency cards both ticked, custom amount minimum and maximum fields, and the start of the Campaign block The frequency choice is the one that is awkward to undo: a saved campaign must keep at least one of the two. **Done when:** the campaign opens on its own detail page with **Prices & Options**, **Landing page**, **Widgets** and **Stats** tabs and an **Active** badge. See [Donations](/docs/platform/fees/donations). On **Prices & Options**, add a price row per suggested amount and mark one default. These are the buttons a donor sees before they type anything. Prices and Options tab of a donation campaign listing suggested amounts by name, value and description, one tagged default and four tagged Recurring, with an Add button above the table On a campaign with no prices yet, **Generate** proposes three A/B variations of three amounts each from your country, currency and campaign title, registers them in Stripe and switches A/B testing on. It disappears once any price exists, so use it before you add the first row by hand. **Done when:** every amount you want offered has a row, and exactly one carries the **default** tag. See [Donations](/docs/platform/fees/donations). **Product options** on the same tab are what the donor picks under **Designate to**: one option per fund, project or purpose you take restricted gifts for. Each one has its own link that pre-selects it, which is what you put behind a button on your own site or in an appeal email. **Done when:** the option list holds one row per restricted purpose, and its link opens the donation page with **Designate to** already filled in. See [Products](/docs/platform/fees/products). Under **Campaign**, choose **Total goal** (cumulative one-off gifts) or **Monthly goal** (recurring revenue), a **Goal value**, and optionally a **Target date**, which replaces the completion percentage on the public progress bar. | If you want | Choose | | ------------------------------------------- | ------------------------------------- | | A running total that climbs toward a number | **Total goal** | | Monthly recurring revenue tracked per month | **Monthly goal** | | A visible deadline instead of a percentage | Any goal type, plus a **Target date** | The goal type selector only appears when both **Recurring** and **One-off** are enabled, since with one frequency there is nothing to choose between. Goals are unavailable on multi-currency campaigns. **Done when:** the public page prints an amount raised, a goal and a progress bar. See [Donations](/docs/platform/fees/donations). The **Landing page** tab edits hero media, colours, the campaign story, the thank-you message and the social share image against a live preview. Landing page tab of a donation campaign, with a Hero media card holding Image and Video tabs over the uploaded hero photo, an Appearance card with logo header bar and title switches for desktop and mobile plus named primary colour presets, and a live preview on the right showing the campaign page on a phone with its progress bar and suggested amounts Work down the left column and watch the preview: it renders the real public page, so it shows what a donor will see on the phone most of them are holding. **Done when:** the preview shows your hero, your story and your amounts, and you have pressed **Save** in the preview header. See [Donation pages and widgets](/docs/platform/fees/donation-pages). **Settings → Modules → Payments & Fees → Donation Product** sets which campaign answers `/donate`, and which one grants the **Supporter** flag on member profiles. Donation Product settings with both the Donation Product and the Recurring Donation Product selector naming the campaign Support Northwind's Mission, beside a Manage Products link The first donation campaign you create claims the first of those automatically, which is rarely the one you want six months later. The two selectors can name the same campaign, as they do above, when that one campaign has both **One-off** and **Recurring** switched on. **Done when:** **Donation Product** names the campaign you are currently promoting, and **Recurring Donation Product** names the monthly programme if you run one. See [Donations](/docs/platform/fees/donations). Open **Settings → Modules → Emails & Notifications → Email Templates** and edit **Donation thank you**. This is the only message a one-off donor receives, so it carries the whole relationship: what the gift does, and what happens next. Your version has no language of its own. It goes to every donor as written, whatever language they read the platform in, so pick the language most of your donors share. Leave the template untouched if you would rather each donor got the built-in wording in your organisation's default language. **Done when:** the template reads in your own voice, and you have decided which language your donors get. See [Email templates](/docs/platform/emails/email-templates) and [System emails](/docs/platform/emails/system-emails). **Settings → Modules → Emails & Notifications → Email Campaigner**, then **Enable Email Campaign Module**. You need the campaign live before you can link to it from an appeal. **Done when:** a newsletter draft can link to the campaign page you just published. See [Newsletter](/docs/platform/newsletter). *** ## What you get Everything below lands on one public page or one click from it. This is a campaign mid-flight: story and progress on the left, the donation form pinned on the right, recent gifts underneath it. Public donation page showing the amount raised against the goal with a progress bar and donation count, an About this campaign story, a Words of support list of donor messages, and a sticky donation form with suggested amount buttons, a custom amount, Cover the processing fee, a confidentiality checkbox, Donate now and a recent donations panel | What you need | What Orgo gives you | Where it is documented | | ------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------- | | One-off gifts | A donation campaign with **One-off** on: suggested amounts, a custom amount with optional minimum and maximum, **Cover the processing fee**, 19 currencies | [Donations](/docs/platform/fees/donations) | | Recurring giving | The same campaign with **Recurring** on: a **Give once / Monthly** toggle on the page, a **Subscribers** tab, and a personal cancel link in the donor's subscription emails | [Donations](/docs/platform/fees/donations) | | A campaign page | A public page at `/pay/`, no login needed, with hero media, story, goal progress bar, donor wall and share button | [Donation pages and widgets](/docs/platform/fees/donation-pages) | | Giving from your own website | Embed and popup widgets with their own colours, language, preset amounts and statistics | [Donation pages and widgets](/docs/platform/fees/donation-pages) | | Restricted or designated gifts | **Product options** under **Designate to**, each with its own deep link, filterable on the payments list | [Products](/docs/platform/fees/products) | | Donor recognition | The donor wall (**Display top 50 recent donations**), **Words of support** messages, and the **Supporter** tag on profiles and in the member directory for active recurring donors | [Donation pages and widgets](/docs/platform/fees/donation-pages) | | Anonymous giving | **Enable payment confidentiality**: the gift counts toward the goal, the name shows as "anonymous" | [Donation pages and widgets](/docs/platform/fees/donation-pages) | | Receipts | The **Donation thank you** email, plus optional **Stripe Email Receipts** from your own Stripe account | [System emails](/docs/platform/emails/system-emails) | | Offline gifts (cash, cheque, bank transfer) | **Record payment** on the donor's **Payments** tab, or on the campaign's **Payments** tab | [Recording a payment](/docs/platform/fees/record-payment) | | Refunds | **Refund** on the payment row, which returns that row's amount through Stripe | [Stripe integration](/docs/platform/fees/stripe-integration) | | Appeal emails | Newsletter campaigns, with **Follow up with non-openers** to re-mail the people who did not read the first one | [Newsletter](/docs/platform/newsletter) | | Donor segments | Lists with **Has Payment** and **Has Recurring Payment** criteria, both of which reveal a **Product** selector so you can narrow to one campaign | [Lists and segments](/docs/platform/users/lists) | | Campaign reporting | The campaign's **Stats** tab: views, device split, widget versus public page, and UTM source, medium and campaign breakdowns for both views and gifts | [Donations](/docs/platform/fees/donations) | | Revenue reporting | The **Donation Revenue** tile on the Analytics **Finance** tab, and free-form questions in Ask Orgo | [Insights and Ask Orgo](/docs/platform/insights) | ### Where you read the results Two tabs on the campaign answer different questions. **Payments** is the ledger: one row per gift. **Stats** is the campaign view: money over time above the page analytics. Stats tab of a donation campaign with the range buttons above the chart and 12 months selected, showing a payments total and an amount line with a seven-day moving median The range buttons above the chart matter more than they look: an appeal that ran last autumn is invisible on the default 90-day window. *** ## Recipes Three worked configurations. **These are examples, not defaults.** Nothing below is preconfigured, and none of it is the only way to set the feature up. ### Example: a year-end appeal A six-week campaign with a published target, tested ask amounts, and two emails. | Step | Setting | | ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Frequency | **One-off** only, so the page does not split attention with a monthly toggle | | Suggested amounts | Press **Generate** on the empty **Prices & Options** tab. It creates three variations of three amounts, registers them in Stripe and switches **Pricing A/B Testing** on | | Goal | **Total goal**, **Goal value** set to your target, **Target date** 31 December. The progress bar then prints the date instead of the completion percentage, which is what creates the deadline | | Page | Hero image, a short story in **Description**, and a **Thank you message** that names what the money does | | Recognition | **Display top 50 recent donations** and **Messages of support from donors** both on, so the page fills up with activity as the appeal runs | | First email | A newsletter to **All members and contacts**, or to a list of everyone who has given before (**Has Payment**, then the **Product** selector on last year's campaign) | | Second email | **Follow up with non-openers** on the first campaign, roughly a week later. The set is recalculated at send time, so people who opened late drop out | | Reading the result | Each A/B variation reports total raised, average gift and transaction count on the **Prices & Options** tab. A variation that has collected money cannot be deleted | A week in, the recognition settings are what make the page look busy. The sidebar lists recent gifts, and **See all** opens the full donor wall with an **All** and a **Top** tab. Donations dialog opened from the donor wall of a public donation page, with All and Top tabs over a list of gifts showing donor first name and surname initial, anonymous entries, amounts and how long ago each was given, above the campaign page and its Words of support list Two things to know before you rely on this. The A/B test is on the suggested amounts, not on the email: newsletter campaigns have no A/B testing. And a variation that is winning cannot be promoted to "the default" while A/B testing is on, because **Make default** is hidden in that mode. Turn A/B testing off and mark the winning amount default once the appeal closes. ### Example: a monthly giving programme | Step | Setting | | ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Frequency | **Recurring** and **One-off** both on, so the page shows the **Give once / Monthly** toggle and the "Boost your impact by giving monthly" prompt | | Goal | **Monthly goal**, so the progress bar tracks recurring revenue per month rather than a cumulative total | | Suggested amounts | Price rows tagged **Is recurring**, at monthly rather than annual figures | | Supporter flag | Point **Recurring Donation Product** at this campaign under **Settings → Modules → Payments & Fees → Donation Product**. Members with an active, non-confidential subscription then carry a **Supporter** tag on their profile and in the directory | | Website widget | Create a widget, set **Default Donation Type** to monthly, leave **Show Monthly Upsell** on, and set separate preset amounts for one-time and monthly | | Running it | The **Subscribers** tab lists every recurring donor with status, chapter, designation and amount, and **Unsubscribe** cancels one | | Donor self-service | Every **Subscription created** and **Subscription payment received** email carries a personal cancel link that works without a login | Switching off **Subscription Notifications** on **Settings → Modules → Emails & Notifications → Emails Config** silences those two emails, and with them the only cancel link a donor who is not a member ever receives. Leave the category on for a recurring programme. See [System emails](/docs/platform/emails/system-emails). ### Example: an appeal tied to an event Orgo has no donation step inside event checkout, so an event-linked appeal is a normal campaign with the event used as the audience and the designation. On **Prices & Options**, add an option such as "Spring Conference bursary fund". Copy its link: it opens the donation page with that designation pre-selected, so it is what you put on the event page and in the run of show. Create a newsletter with the **Event attendees** audience, or start from the event with **Send email for participants**, which files the campaign under the event's own messages and unlocks the event placeholders. See [Newsletter](/docs/platform/newsletter). Append UTM parameters to the link you publish. The campaign's **Stats** tab breaks both views and gifts down by UTM source, medium and campaign, which is the only way to tell the stage announcement apart from the follow-up email. Filter the campaign's **Payments** tab by option to get the total raised for that event, separate from the rest of the campaign. Payments tab of a donation campaign with a gift count next to the campaign name, filter pills for payer name, payment ID, user ID, email, status, type and date, and rows showing the amount, a paid or refunded status, the payer, their chapter, the date, a confidentiality marker and whether the gift was one-time or a subscription The same list is where you check a gift somebody says they made, and where **Refund** lives. *** ## Setup checklist Work down this before you publish the first link. It mirrors [Setup order](#setup-order), so anything unticked tells you which step to go back to. * [ ] **Country** is set on **Settings → Organisation info** * [ ] The Payment Gateway page reads **Fully connected** and **Complete** * [ ] The organisation-wide checkout switches are set the way you want them for every campaign * [ ] The campaign exists, with **One-off**, **Recurring** or both switched on * [ ] Every suggested amount has a price row, and exactly one is marked default * [ ] There is a **Product option** for each restricted purpose, if you take restricted gifts * [ ] A goal type and **Goal value** are set, plus a **Target date** if the appeal has a deadline * [ ] Hero, story and thank-you message are saved on the **Landing page** tab * [ ] **Donation Product** points at the campaign you are promoting, and **Recurring Donation Product** at the monthly programme if you run one * [ ] The **Donation thank you** template is rewritten in your own voice, in the one language every donor will receive * [ ] **Enable Email Campaign Module** is on, so a newsletter draft can link to the campaign * [ ] You have given a test gift yourself and received the thank-you email * [ ] The link you are about to publish opens the right campaign, with the right designation pre-selected *** ## Limits worth knowing before you start Stated plainly, because each one has caught somebody out. The one that surprises fundraisers most: Orgo has no donation receipt or tax document anywhere in the product. Read the first limit below before you promise donors anything on paper. **Donations do not produce invoices or tax receipts.** **Generate Invoice** on a payment row only appears for membership fee and event registration payments; a donation payment is refused. There is no annual giving statement, no Gift Aid support and no donation tax form anywhere in the product. The donor gets the **Donation thank you** email, and Stripe's own receipt if you enable **Stripe Email Receipts**. If your donors need a document for tax purposes, produce it outside Orgo. **The PDF Receipts/Proofs setting is not a general donation receipt.** It adds a downloadable proof on paid rows, but the document is generated from the payer's validated identity record, so it only produces anything for donors who went through [identity validation](/docs/platform/identity-validation). Do not enable it expecting receipts for ordinary card gifts. **A chapter designation is a label, not a bank instruction.** With **Has local center option** on, a donor picking a chapter under **Designate to** stamps the payment with that chapter, which is what the payments filter and the refund permission read. A gift with no designation is treated as organisation-level, and the refund, cancel, accept and proof actions on it require `FINANCIAL_TENANT` rather than any one chapter's `FINANCIAL_LOCAL`. The money still settles into the Stripe account the campaign resolves to. Only fee payments follow chapter Stripe routing: see [Stripe integration](/docs/platform/fees/stripe-integration). **There is no CSV export on the campaign payments or subscribers lists.** Both are filterable and paginated on screen only. For a donor extract, build a payments report in [Reports](/docs/platform/reports): **Payments** is one of the builder's starting points, you can add columns from the product, the price, the payer and the company, and the download holds every matching row rather than one page. The alternative is to ask the question in [Ask Orgo](/docs/platform/insights) and use **Export CSV**, which returns the first 500 rows; save the query and run it from **Database Queries** for the whole set. Both routes require `ADMIN_TENANT`, so a fundraiser holding only `FINANCIAL_TENANT` cannot do this themselves. **Refunds are all or nothing.** **Refund** returns exactly that payment row's amount. There is no partial refund in Orgo, so a donor who wants half their gift back has to be refunded in full and give again. **Donor messages publish immediately.** A message attached to a successful or on-hold payment is stored as approved and appears in **Words of support** straight away. Moderation is after the fact: there is no pending queue to approve. Leave **Messages of support from donors** off if you cannot watch the page. **There is no abandoned-gift reminder for one-off donations.** The only checkout reminder in the product chases recurring subscriptions that stalled after identity validation, and it fires once, at least 48 hours later. Somebody who opens your donation page and leaves is never emailed. **Goals are unavailable on multi-currency campaigns**, because there is no single number to total toward. Pick one currency for any campaign you want a progress bar on. **Widget ids are public by design.** Anyone with the id can render your donation form on their own site. Delete a widget you no longer want live rather than removing the snippet from your page. **A campaign that has taken any money cannot be deleted.** Archive it. The page keeps loading and the form is replaced with a notice that payments are disabled. **Orgo is not a peer-to-peer or team fundraising tool.** There are no supporter-created pages, no individual fundraiser targets and no team leaderboards for giving. *** ## Troubleshooting No Stripe account is connected: the organisation's for an organisation campaign, the chapter's own for a chapter campaign. Connect one under **Settings → Modules → Payments & Fees → Payment Gateway**. If the connect buttons themselves are disabled, the organisation has no **Country** set under **Settings → Organisation info**. See [Stripe integration](/docs/platform/fees/stripe-integration). Stripe has stopped letting the account charge. Open the settings page and read **Requirements needed**, or the same list in the Stripe Dashboard, and clear it. The page shows **Partially connected** rather than **Fully connected** while this is true. An open requirement with a future deadline does not block anything yet, so a working account with a warning is normal. Check three things in order. Is it on the campaign's **Payments** tab with a status other than `success`? A payment on hold shows as **on-hold** and has not been captured. Was it designated to a chapter you do not hold `FINANCIAL_LOCAL` on? The payments list is scoped by permission, and the payment-ID and email filters are only offered to `FINANCIAL_TENANT`. And is it on the right campaign at all? The `/donate` shortcut resolves to whichever campaign is set as **Donation Product**, which is not necessarily the one you were promoting. The **Donation thank you** email is sent when Stripe confirms the payment, and it sits under the **Payment Confirmations** category on **Settings → Modules → Emails & Notifications → Emails Config**. A category switched off sends nothing and writes no log row. If the switch is on, check the [email log](/docs/platform/emails/email-log) for the recipient address: a gift given with a mistyped email has nowhere to go. Offline gifts you recorded by hand never trigger it, because there is no Stripe confirmation to react to. Orgo has no donation receipt document. Your options are **Stripe Email Receipts**, which lets Stripe send its own receipt from your account (it needs customer emails enabled on the Stripe account, and Stripe never sends receipts in test mode), or raising a document outside Orgo. **Generate Invoice** is not available on donation payments. See [Invoices](/docs/platform/fees/invoices) for what invoicing does cover. **Refund** on the payment row, which needs `FINANCIAL_LOCAL` on the chapter the gift was designated to, or `FINANCIAL_TENANT` when the gift carries no chapter. `ADMIN_TENANT` qualifies either way, and a chapter treasurer cannot refund an undesignated gift. It only works on a payment already in `success`; a payment still on hold is cancelled instead, and the full row amount goes back. Refunds you issue in the Stripe Dashboard are picked up and marked in Orgo too, so you do not have to do it twice. Send them the cancel link from their **Subscription created** or **Subscription payment received** email: it opens a page that cancels without a login, and it is the only self-service route a donor who is not a member has. A donor who is a member can instead open the **Payments** tab of their own profile, which lists their active recurring gifts with an **Unsubscribe** action. Failing both, cancel it for them from the campaign's **Subscribers** tab. **Display top 50 recent donations** has to be on for the panel to exist at all. Donors who ticked confidentiality show as "anonymous" throughout, and a gift given with **Enable payment confidentiality** on never sets the **Supporter** flag either, so a recurring donor can be entirely invisible by their own choice. The wall shows a first name and a surname initial, never a full name. The flag needs all of: the setting pointed at the right campaign, an active subscription (not cancelled, not pending), and a subscription the donor did not mark confidential. Cancelling clears it. Check the campaign's **Subscribers** tab for the donor's actual status before assuming the flag is broken. Each currency carries its own Stripe minimum charge, for example 0.50 USD and EUR, 0.30 GBP, 2.00 RON. That floor applies underneath whatever **Minimum** you set on the campaign, so a lower amount is refused at the payment step rather than by your own validation. Two reasons. The goal type selector only appears when both **Recurring** and **One-off** are enabled, since with one frequency there is nothing to choose between. And goals are not offered at all on a campaign with more than one currency. Organisation campaigns need `FINANCIAL_TENANT`. `FINANCIAL_LOCAL` reaches only campaigns belonging to a chapter the holder is attached to, which is why a chapter finance admin sees **Finance → Local products** but not the organisation's campaigns. Someone without the permission is sent to the login screen rather than shown a permission message, which reads like an expired session and is not one. See [Permissions](/docs/platform/permissions). *** ## Related * [Donations](/docs/platform/fees/donations): campaigns, suggested amounts, A/B testing, payments and refunds * [Donation pages and widgets](/docs/platform/fees/donation-pages): the public page, donor messages, the donor wall, embeds * [Stripe integration](/docs/platform/fees/stripe-integration): connecting payment processing, statuses and payouts * [Recording a payment](/docs/platform/fees/record-payment): cash, cheque and bank transfer gifts * [Newsletter](/docs/platform/newsletter): appeal emails, audiences and follow-ups * [Insights and Ask Orgo](/docs/platform/insights): revenue dashboards and donor questions * [Setup templates](/docs/platform/templates/index): the other playbooks # Setup Templates Source: https://orgo.space/docs/platform/templates/index Playbooks that take one kind of organization from an empty Orgo workspace to a working setup, in order The rest of these docs are organised by feature: one page per thing Orgo does. That is the right shape once you know what you are looking for, and the wrong shape on day one, when the question is "which of these forty features do we actually need, and in what order?" Setup templates answer that question. Each one takes a kind of organization, names the modules and settings it needs, puts them in the order you should configure them, and links to the feature page for each step. **Built for** the first fortnight on Orgo, and for the moment a year later when you add a part of the product you skipped. *** ## Pick your starting point One-off and recurring giving, campaign pages, donor recognition and receipts. Newsletters, discussions, notifications and system email, and which channel to use when. Associations whose members are companies or institutions: company membership, seats and invoicing. Sections by age, youth members and parents, safeguarding, progression and camps. Formal membership applications, identity checks, territorial structure, internal elections. Most organizations need more than one. A trade association that fundraises and sends a monthly bulletin is running three of these at once: read the one closest to your core operation first, then borrow from the others. The split that matters most is who your members are. If they are **organizations**, start with [Federations](/docs/platform/templates/federations), because company membership changes how joining, seats and billing work. If they are **individuals**, start with whichever of the other four describes your main activity. *** ## What a template gives you | Section | What it answers | | ------------------- | --------------------------------------------------------------------------------------------------- | | **What to turn on** | The exact modules and settings, with the settings path and the permission needed to change each one | | **Setup order** | What to configure first, so you do not have to undo work later | | **What you get** | The need you have, mapped to the Orgo feature that serves it | | **Recipes** | Worked configurations you can copy, marked as examples rather than defaults | | **Limits** | What Orgo does not do for this use case, stated before you build on an assumption | | **Troubleshooting** | The specific things that go wrong for this kind of organization | *** ## If you are not sure which applies Answer these in order. The first one that matches is your starting point. | If this is true | Start here | | ------------------------------------------------------------------------------------- | ---------------------------------------------------------------- | | Your members are companies or institutions rather than individuals | [Federations](/docs/platform/templates/federations) | | Joining is a formal application you approve, and you hold members' identity documents | [Political parties](/docs/platform/templates/political-party) | | Money from supporters who are not members is your main flow | [Fundraising](/docs/platform/templates/fundraising) | | Your members are under 18, or you run sections by age with adult volunteers | [Scouting and youth organizations](/docs/platform/templates/scouting) | | Your members are individuals paying a subscription and reading what you send them | [Member communication](/docs/platform/templates/communication) | If none of them fit, the feature pages stand on their own. [Organization settings](/docs/platform/organisation/index) and [Modules](/docs/platform/organisation/modules) are the two worth reading first, because everything else is switched on from there. *** ## Before any template Three things apply whatever you are building, and doing them first saves rework: Legal name, registration and VAT numbers, address, currency, timezone and the legal document URLs. Invoices, emails and public pages all read from it. See [Organization info](/docs/platform/organisation/organisation-info). Permissions are easier to hand out than to take back, and the difference between the Orgo administrator flag and the ADMIN\_TENANT permission catches people out. See [Permissions](/docs/platform/permissions). Every module you enable adds menu entries and settings for your admins to wade through. You can switch the rest on later. See [Modules](/docs/platform/organisation/modules). *** ## Related * [Modules](/docs/platform/organisation/modules): every switchable module and what enabling it turns on * [Organization settings](/docs/platform/organisation/index): the map of the settings area * [Permissions](/docs/platform/permissions): what each permission level unlocks * [Texts](/docs/platform/customization/labels): renaming Orgo's vocabulary to match your own * [Home](/docs/platform/index): the full feature index # Orgo for political parties Source: https://orgo.space/docs/platform/templates/political-party A playbook for parties: formal membership applications with a signed adhesion, identity checks, chapters and transfers, dues, internal elections, and handling membership as special-category data **Built for** political parties, and for any organization where joining and leaving are formal acts with a document behind them: trade unions, professional bodies with a statutory register, cooperatives. **Replaces** the paper membership application in a filing cabinet, the branch secretary's parallel member list, and the show of hands at congress. Two things make a party different from an ordinary membership organization, and this page is built on both. Joining is a formal, reviewable, signed act, not a sign-up form. And the fact that someone is a member is, in the European Union, special-category personal data, so who can see your member list is a design decision rather than a preference. This page routes. Each section names the feature that covers the need and links to the page that documents it in full. *** ## Before you start Five decisions shape everything below. Settle them on paper first. Each one turns into a form field, a switch or a price row later, and the ones about identity documents and about chapter currency cannot be unwound in the product at all. * [ ] **Statutes and membership rules to hand.** You can say who is eligible to join, what the application has to contain, who signs it, and what your statutes oblige the party to keep on file afterwards. * [ ] **Identity document chosen, with the legal basis written down.** You know which document you ask for, why you need it, how long you intend to keep it, and under which lawful basis you hold it. * [ ] **Territorial structure drawn.** Every layer named, from the party down to the smallest branch, whether you need a region tier above your branches, and which currency each branch collects in. A chapter's currency is set once and can never be changed. * [ ] **Dues schedule agreed.** One price per membership category, the billing period, and whether branches keep part of what they collect. * [ ] **Reviewers named, branch by branch.** For each branch, who validates the application, who runs the interview, and who takes the decision. The decision that bites later is the identity document. Orgo has no delete operation for an identity record and no retention timer, so "we will tidy that up later" is not available to you. Decide what you collect and how you will purge it before the first upload, not after. The decision that bites soonest is who reviews. The adhesion queue is scoped per chapter: `HR_TENANT` sees the whole party, everyone else sees only the chapters they hold `HR_LOCAL` on. A branch with nobody holding `HR_LOCAL` has nobody watching its applications except tenant-wide officers. *** ## Who this is for You are in the right place if most of these are true: * Somebody applies to join, a committee reviews the application, and the party admits them. Registering an account is not the same as being a member. * You need a signed document per member, retrievable years later, with a record of who approved it and when. * Your statutes divide the country into chapters, and possibly regions above them, each with its own officers. * Members pay dues, and some chapters keep part of what they collect. * You hold internal elections: leadership, congress delegates, candidate selection. * Your statutes require decisions to be recorded and made available to members. If people simply register and pay, you do not need the adhesion machinery. Set new registrations to a pending [status](/docs/platform/users/statuses) and start from [Membership fees](/docs/platform/fees/fees) instead. *** ## Joining: the adhesion Adhesion is Orgo's membership application module, and for a party it is the centre of the setup. An applicant fills in a form you define, uploads an identity document, signs the application in the browser, and sends it. Your team then moves it through a review chain and approves or rejects it. Full detail: [Adhesion](/docs/platform/users/adhesion). Turn it on at **Settings** → **Modules** → **Users & Profiles** → **Configuration** → **Adhesion & Membership** → **Enable Adhesion Module** (`ADMIN_TENANT`). The module is off by default; **Review steps** and **Require identity verification** are both on by default once it is. Adhesion and Membership settings section with the Enable Adhesion Module, Mandatory Adhesion, Video recording, Review steps and Require identity verification switches above the Default User Type After Approval, Admin Email Address and Draft Change Reasons fields ### The three pieces you configure | Piece | Where | What it decides | | ------------------- | ------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | The module switches | **Settings** → **Modules** → **Users & Profiles** → **Configuration** → **Adhesion & Membership** | Whether applying is mandatory, whether there is a video step, whether the full review chain runs, whether an ID is required, and which [user type](/docs/platform/users/user-types) approval grants | | The form | **Settings** → **Modules** → **Users & Profiles** → **Adhesion Form** | Which profile and [custom fields](/docs/platform/users/custom-fields) the applicant fills in, and which of them are required | | The document | **Settings** → **Modules** → **Users & Profiles** → **Adhesion Template** | The HTML the signed PDF is rendered from, with placeholders for the applicant's details | The template editor is three raw HTML areas (Header, Main Template, Footer). Put your statutes' declaration of adherence in the Main Template, with the placeholders for name, personal number, address and chapter, and `{{signature}}` and `{{dateSignature}}` in the signature block. Leave an area empty and Orgo falls back to its own default for that part. ### What the applicant does Start the application, upload the front of an identity document (and the back if the document carries information there), fill in the form, sign on a canvas, and send. Signing is what generates the PDF from your template with the signature embedded, and stores it as the application's signed document. **Send** is refused until a signed document exists and, while **Require identity verification** is on, until an ID has been uploaded. Staff holding `HR_LOCAL` over the applicant's chapter can fill the form in on somebody's behalf, for a paper application received at a branch office. They get no signature canvas: they upload the signed file instead, up to five files. ### Reviewing **Management** → **Adhesions** in the sidebar, `HR_LOCAL`. The queue is scoped: `HR_TENANT` sees the whole party, everyone else sees only chapters they hold `HR_LOCAL` on, and `HR_PARENT_LOCAL` and above get a chapter filter. One row is one application. The chips across the top carry live counts per status, so the queue doubles as your backlog report, and the per-row controls open the signed document, the video, the identity record and the status picker without leaving the list. Adhesions queue with status filter chips and counts, and per-row signed document download, video, identity state and status controls With **Review steps** on, an application walks the full chain: sent, **Adhesion form validated**, **Background checked**, **Interviewed**, then the decision. Each move is gated, which is what makes the chain worth having: * **Adhesion form validated** is refused until the identity document has been validated, unless you turned identity verification off. * **Adhesion success** and **Adhesion rejected** are refused until both the Interview conclusion and the Background conclusion have been saved on the **Conclusions** screen. * **Adhesion canceled** requires a cancel reason. * Sending an application back to **Initiated** opens your **Draft Change Reasons** picker, **deletes the signed document** so it must be signed again, and emails the applicant the reasons you selected. Turn **Review steps** off if your statutes do not require an interview and a background step, and an admin decides straight from a sent application. ### What approval actually does Approving sets the member's full member flag, assigns the **Default User Type After Approval** (creating the underlying role assignment if they did not already have it), and stamps the date they became a full member. The approval email only goes out if the user type actually changed, so somebody who already held that type hears nothing. Approval does not change the account [status](/docs/platform/users/statuses). An applicant sitting on **New request** or **Inactive** stays there after approval and still cannot sign in. If your joining process uses **Manual Approval** as well, approve the status separately, or drop **Manual Approval** and let the adhesion be the only gate. ### The audit record **Conclusions** and **Log** on a queue row open the same screen (`/adhesion/{id}/log`, `HR_LOCAL`). The log names who sent, validated, interviewed, decided on and last updated the application, each with a timestamp and a link to the person, followed by the field-level changes. That, plus the signed PDF, is the evidence that a member was admitted according to your statutes. Adhesions queue with the Log panel open over it, listing the dated entries for one application: validated by, interview by, decision by with a success tag, and updated by Read it as the chain your statutes describe: each move is a separate act by a named person on a named date, and an application that skipped a step has a gap where that entry should be. **Mandatory Adhesion** redirects every member to their application on every route until it reaches **Adhesion success**. Members holding `ADMIN_LOCAL` or above, and members who already hold the configured success user type, are exempt. It is the right setting for a party that admits nobody without an application, and it makes your review turnaround into a support problem if the queue is slow. Turn it on after the first review round, not before. *** ## Verifying identity Many jurisdictions require a verifiable identity before someone can be enrolled as a party member. [Identity Validation](/docs/platform/identity-validation) is the feature that collects one. ### What it does * Accepts an image of the document: **PNG, GIF and JPEG. PDFs are rejected.** Front, plus a back side when you switch on **Document has information on the backside**. * Reads Romanian documents automatically (old ID card, new ID card, passport), keyed off the CNP. It extracts first name, last name, date of birth, document series and number, CNP, expiry date and document type from the front, and issue date, town, county and address from the back. * For every other country the upload and review flow still works, but an administrator types the details in by hand. * Puts the record in front of a reviewer who **Validate**s or **Reject**s it, stamping who approved it and when. Rejection requires one of three reasons and emails the applicant, who can upload again. * Records the states **Pending**, **Orgo validated** (read automatically, still open for a human), **Validated** and **Rejected**. Reviewing requires `HR_ASSISTANT_LOCAL` over the member's chapter, which `HR_LOCAL`, `HR_PARENT_LOCAL`, `FINANCIAL_LOCAL` and `ADMIN_LOCAL` all satisfy, as do the tenant-wide `ADMIN_TENANT`, `HR_TENANT` and `FINANCIAL_TENANT`. The review screen is the whole feature in one place: the uploaded document on the left, and beside it the details read off it and the decision. Below is that second column. Review column of a pending identity record, with the Validate button above the Reject reason picker and a Change identity data button, then the locked first name, last name, personal number, date of birth, document serial and number, and issue and expiry date fields One thing the list above does not tell you: the fields are locked until you press **Change identity data**. That is how a misread detail gets corrected, and how a non-Romanian document gets entered at all. ### What it does not do Be honest with your members and your own committee about this. Identity Validation is document capture and human review, not verification. * **It does not check the document against any register.** Nothing talks to a national identity service, an electoral roll or a sanctions list. * **Outside Romania, approving a record only requires a first and last name.** Nothing forces the reviewer to confirm the document is genuine, and nothing compares the photo to the person. * **There is no expired state.** An expired document keeps whatever status it had; expiry is only checked at the moment somebody tries to validate it. * **There is no selfie or liveness step**, and no way for the member to correct what was read. Everything after the upload is done by an administrator. * **There is no re-check reminder for members.** The renewal reminders exist only for payment-linked identities. ### The module toggle and the adhesion step are two different things This trips people up. The identity step inside an adhesion is driven entirely by **Require identity verification** in the adhesion settings. It creates the same identity record and runs the same reading, whether or not the **Identity Validation** module is switched on. The module switch at **Settings** → **Modules** → **Identity Validation** governs the payment-linked flows (**Require for Online Payments**, the reminder ladder, subscription reconfirmation) and whether the identity emails appear in the template list. So a party that wants ID checks on membership applications and nothing else needs only the adhesion setting. Turn the module on when you also want identity tied to payments. **Require for Users** on the Identity Validation settings page is read nowhere in the product. Turning it on has no effect. *** ## Territorial structure Orgo calls a territorial branch a **chapter** (**local center** in the data model, the API and the permission names). The Local Centers module is on by default; the layers above and below it are not. | Your structure | Model it as | Switch | | -------------------------------------------------------- | ------------------------------------------------------ | ----------------------------------------------- | | The party | The organization itself | Nothing to turn on | | Federal state, region, county, and any tier between them | **Parent chapter**, nested as deep as your statutes go | **Enable Parent Centers** | | Local branch, constituency organization | **Chapter** | **Enable Local Centers Module** (on by default) | | Sections inside a branch | **Unit**, with a unit type you define | **Enable Organizational Units** | | A label for reporting only, granting nothing | **Region** | **Enable Regions** | All four live at **Settings** → **Modules** → **Groups & Teams**, and all require `ADMIN_TENANT`. See [Chapters](/docs/platform/groups/local-groups) and [Units](/docs/platform/groups/units). There is no limit of two layers. Federal state holding region holding county holding branch is one chapter tree, built by flagging every tier that holds another with **It's a parent chapter** and then setting **Belongs to parent chapter** on each tier below it. A tier in the middle carries both settings at once. Moving a chapter in the tree afterwards requires `HR_TENANT`, so plan the shape before you delegate. Once they exist, **Chapters** in the sidebar is your map of the party. Each tier is indented under the one above it, in tree order, and a chapter's members figure carries a `(+N)` count for everyone in the chapters beneath it, counted through the whole branch rather than one tier down. Chapters list in tree order with each tier indented under the one above it, each row showing member count, town, county and founding date ### Officer permissions follow the layer Permissions belong on [roles](/docs/platform/organisational-chart#the-role-form), never on user types: a user type cannot carry a permission at all. Match the role's level to the post. | Post | Role level | Permission family | | ------------------------------------------------ | ------------------ | ----------------------------------------------------------------- | | Party president, general secretary, national HR | **Organisation** | `ADMIN_TENANT`, `HR_TENANT`, `FINANCIAL_TENANT` | | Chair of any tier that holds other chapters | **Parent chapter** | `ADMIN_PARENT_LOCAL`, `HR_PARENT_LOCAL`, `FINANCIAL_PARENT_LOCAL` | | Branch chair, branch secretary, branch treasurer | **Chapter** | `ADMIN_LOCAL`, `HR_LOCAL`, `FINANCIAL_LOCAL` | `ADMIN_PARENT_LOCAL` grants every local permission across one anchor chapter and every chapter beneath it, however many tiers down; `ADMIN_LOCAL` grants every non-parent local permission inside its own chapter alone. Both are computed from the holder's own primary chapter, so a regional officer's reach follows them if they move. The anchor is the officer's own chapter when that chapter is flagged **It's a parent chapter**, and otherwise the chapter directly above theirs. A county chair filed against a county that is flagged as a parent therefore administers the county and its branches and nothing above it, which is what you want. A branch officer given the same permission anchors to their county instead, and so reaches every branch of that county. The `_PARENT_LOCAL` family only travels downward, never up and never sideways into another branch, and it only means anything while **Enable Parent Centers** is on. `HR_LOCAL` on a chapter is exactly that chapter, with no reach into the chapters below it. Read [What a parent-scope permission reaches](/docs/platform/groups/local-groups#what-a-parent-scope-permission-reaches) before you hand out `ADMIN_PARENT_LOCAL` to a county chair, especially if your structure has three tiers or more. ### When a member moves A member has exactly one primary chapter. Moving them is a [transfer request](/docs/platform/groups/transfers): somebody raises it with a written reason, and **the receiving chapter approves it**, not the one being left. That asymmetry is usually what a party wants, because the branch taking somebody on is the one with an interest in checking. Approval does three things: sets the primary chapter, ends the member's open member-type role assignment stamped to the chapter they are leaving, and creates a new one in the destination. Everything else stays where it was created, including fee payments, invoices, discussions and any additional roles. Treat a transfer as a change of home branch, not as a data migration. The alternative, direct reassignment from the chapter selector on a member's **Permissions** panel, needs `HR_TENANT`, records no reason and rewrites no role assignments. Use it to correct an import mistake, not to move a real person. *** ## Membership dues Dues are the ordinary [Membership Fees](/docs/platform/fees/fees) machinery: a fee [product](/docs/platform/fees/products) with one price per membership level, selected as **Membership Fee Product** and **Default Price** under **Settings** → **Modules** → **Payments & Fees** → **Membership fees**. Membership fees settings with Enable Membership Fees on, a Membership Fee Product and Default Price selected in the Product Configuration card, and the Allow Mark as Paid and Local Center Fees Enabled switches below Nothing charges anybody until both **Membership Fee Product** and **Default Price** are filled in. Three of the switches on this page matter more to a party than to most organizations: | Setting | Why it matters here | | ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Fee Payment Mandatory** | Statutes often say a member in arrears loses their rights. This is the switch that enforces it in the product, restricting the platform for members whose fee has expired | | **Continuity Mandatory** | Requires an unbroken payment history, for statutes that treat a lapse as a break in membership | | **Allow Mark as Paid** | Branch treasurers collect cash. On by default, and it is what lets an administrator record money taken outside the platform | Renewal reminders, the grace window and what expiry actually changes are on [Renewals](/docs/platform/fees/renewals). ### Chapter dues If branches keep part of what they collect, turn on **Local Center Fees Enabled** and give each chapter its own fee product and default price. A member then carries two independent validity dates, one for the party and one for the branch, and can be current on one and expired on the other. A chapter that connects its own Stripe account receives its own chapter fee payments; without one they fall back to the party account. See [Chapter fees](/docs/platform/local-group-fees/create-local-fees). For the branch treasurer collecting cash at a meeting, switch on **Local Center Members Table**. That gives the [Member fees table](/docs/platform/local-group-fees/member-fees): one row per member, one column per period, a checkbox on everything still owed. Ticking and pressing **Pay** writes one pending payment batch stamped as a bank transfer, which an `ADMIN_TENANT` then approves. Only approval moves anybody's validity date. The two fees are charged separately and never in one checkout, and chapter fees are one-off only: there is no recurring subscription for a chapter fee. Members start their own chapter fee payment; administrators record payments on a member's behalf rather than paying for them. *** ## Fundraising Party fundraising, whether from members or from supporters who are not members, runs on the donation machinery: campaigns with suggested amounts, public campaign pages at `/pay/`, embeddable widgets, recurring giving and a donor wall. Read [the fundraising playbook](/docs/platform/templates/fundraising) rather than this page for that. Two of its limits bear directly on party compliance and are worth knowing before you promise anything: * **Donations produce no invoice, receipt document or annual giving statement.** The donor gets a thank-you email, and Stripe's own receipt if you enable it. * **A chapter designation on a gift is a label, not a bank instruction.** Picking a chapter under **Designate to** stamps the payment with that chapter for filtering and permissions; the money still settles into the Stripe account the campaign resolves to. Only fee payments follow chapter Stripe routing. If your jurisdiction caps donations per donor or requires published donor reporting, neither is enforced or generated by Orgo. Build that into your own process. *** ## Internal elections [E-voting](/docs/platform/e-voting) covers leadership elections, congress motions and delegate selection. The module is on by default at **Settings** → **Modules** → **Voting** → **Enable Voting Module**. ### Eligibility Three audiences, set on the **Who is voting?** cards: | Audience | Who is eligible | | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Group vote** | Everyone in the selected group. No group selected means every active member of the party. Select a chapter and it is that chapter's members. Select a [role group](/docs/platform/groups/role-groups) and it is everyone bound to it | | **Private vote** | Only the members the creator adds by name. Use this for a congress where delegates are a named list | | **Event attendees** | Set automatically when the vote is started from an event, for a vote taken in the room at a congress | A multi-question ballot is one question per seat, answered in a single submission; a partial ballot is rejected. Turnout, the voted and pending counts and the roster of who has not answered are on the Participation panel, and Orgo sends no voting reminders, so chase from that list. Finished multi-question vote showing per-option result bars with vote counts and percentages, next to a participation panel giving turnout and the voted, pending and eligible counts The same two-column layout carries a vote from open to closed. While it runs, the left column is the ballot and the right is your turnout; once it closes, the left column becomes result bars per option and the right keeps the roster. **Creating a vote requires `ADMIN_TENANT` or `HR_TENANT`.** A branch chair holding `ADMIN_LOCAL` cannot open a ballot for their own branch, even though a group vote can be scoped to it. Either a national officer creates chapter ballots on request, or the people running branch elections hold a tenant-level permission, which is a much wider grant than it sounds. Decide this before your first branch election, not during it. Once a vote exists, `HR_LOCAL` on the vote's group can edit, publish, close, archive, duplicate and export it, alongside `ADMIN_TENANT` and the creator. ### Anonymity, stated precisely **Anonymous voting** is on by default. With it on, a ballot is stored with no reference to the person who cast it, and no linking record is written anywhere. This is structural, not a display rule: the storage that would hold the voter's identity is never populated. Administrators can see who voted; they cannot see what anyone chose. With it off, each ballot is linked to its voter, the voter is warned of that on the ballot before answering, and after the vote closes the people who can manage it get an **Individual results** panel and a per-voter CSV export. The setting freezes once the vote is published or the first ballot is cast. A vote presented as secret can never be opened up afterwards, and the reverse is blocked too. Orgo records who has voted and when each ballot was stored. In a small electorate, anyone watching the live participation roster can narrow down who voted when, and combine that with the arrival of results. That is inherent to showing live turnout. Switch on **Hide voters list** for any ballot where it matters, which restricts the roster to `HR_LOCAL` on the vote's group and above. ### What the integrity record proves, and what it does not Voting in the member app returns an **integrity code**, shown once in the confirmation panel. Pasting it into **Integrity verification** in the vote's actions menu confirms whether the tally recorded when that ballot was counted still matches the stored ballots. **It proves:** no ballot recorded at or before that point was altered, deleted or inserted afterwards. **It does not prove:** who cast the ballot, what option was chosen, that the voter was eligible, or that the result is correct. It carries no identity and is not a signature from an external authority. It is tamper evidence over the stored ballots, nothing more. Two practical gaps. Codes are issued only in the member app: the [Event App](/docs/platform/events/event-app) and the emailed link for non-member attendees return none. And ballots cast from the Event App voting tab are recorded without the voter link even on a vote configured as non-anonymous, so they count in the totals but never appear in Individual results or the per-voter export. **Run non-anonymous votes on the main member app.** Finally: **Orgo has no quorum and no majority threshold setting.** It reports raw counts and percentages, and your commission applies the rule in your statutes and records the outcome itself. *** ## Publishing decisions and leadership ### The register of decisions The [Official Gazette](/docs/platform/official-gazette) is a dated, numbered register of your formal documents: congress resolutions, executive decisions, statutes, minutes. Turn it on at **Settings** → **Modules** → **Files & eDocuments** → **Official Gazette** → **Enable Official Gazette Module** (`ADMIN_TENANT`, off by default). It then appears in the sidebar as **Official documents**. Each entry has a type, a subject, an optional document number, an official document date (which is what the list sorts by), free text for search, and one attached file. Numbering is yours: Orgo stores what you type and never generates one. Official documents register under a type filter and a free text search, listing dated entries with a download icon, a title, a type and the administrator who added each one Put your numbering scheme in the title, as the entries above do. The list has columns for date, title, type and who added the entry, but none for the document number, so a number kept only in that field is invisible until somebody opens the entry. | Action | Permission | | -------------------------------------- | -------------------- | | Read the list and open any entry | Any signed-in member | | Create, edit, replace the file, delete | `HR_TENANT` | The register is not public and not selectively private. Every signed-in member of the party can open every entry, and the **Private** / **Public** choice on the form is a label recorded on the entry, not a restriction on who can read it. Do not file anything there that some of your members should not see. Use [Files](/docs/platform/files), which has folder and group level permissions, for that. Document types are reference data, read only in the app. If your statutes use types Orgo does not already hold for your organization, ask Orgo support to add them. Publishing an entry notifies nobody. Announce the ones that matter through a [newsletter](/docs/platform/newsletter) or a [discussion](/docs/platform/discussion) post that links to them. ### Who holds which office The [Organizational Chart](/docs/platform/organisational-chart) draws your leadership from the roles you defined and who currently holds them. Nothing is drawn by hand: each box is a role, the number on it is how many members hold it with an open assignment and an **Active** account, and clicking it lists them. It needs **Enable Roles** (on by default) and **Organizational Chart** (off by default), both at **Settings** → **Modules** → **Users & Profiles** → **Configuration**, both `ADMIN_TENANT`. Roles land in sections by level: **Central** for organisation roles, **Parent local centers**, **Chapters**, and one section per unit type. Every signed-in member can open it. There is no anonymous or public version, so it cannot serve as the leadership page on your website. *** ## Handling special-category data **In the European Union, the fact that someone is a member of a political party is special-category personal data under Article 9 of the GDPR.** That changes the calculation on every setting in this section: the default is not "what is convenient", it is "who genuinely needs to see this". **Orgo gives you the controls. Your party is the data controller.** Nothing on this page is legal advice, and no configuration of Orgo makes your party compliant by itself. What follows is what the product actually enforces, so you can map it against the advice you take. ### Who can see that somebody is a member Four independent layers, and they do different jobs. | Layer | Where | What it controls | | --------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Who Can See Members in General Groups** | **Settings** → **Modules** → **Users & Profiles** → **Configuration** → **Privacy & Visibility** | The minimum permission needed to browse the full member list. Below it, a member must narrow the list by group, chapter or profession first. Options: All Users, HR Local, HR Tenant, Admin Local, Admin Tenant | | **Who Can See Local Center Members** | Same section | The minimum permission needed to filter members by a given chapter | | **Restrict Profiles to Shared Local Centers** | Same section | A member can only open profiles of people they share a chapter with. Admins and regional admins are exempt | | Per-member [privacy settings](/docs/platform/users/privacy-settings) | The member's own **Settings & Privacy** → **Privacy** | Which of their own fields other members see, plus **Make my profile completely private** | The first three require `ADMIN_TENANT` and sit in one section of one screen, beside a fourth switch, **Allow Local Admins to Modify User Permissions**, which decides whether branch administrators can change statuses, permissions and roles at all. Privacy and Visibility settings section with the Who Can See Members in General Groups and Who Can See Local Center Members selectors above the Restrict Profiles to Shared Local Centers and Allow Local Admins to Modify User Permissions switches Both selectors ship on **All Users**, which means that out of the box every signed-in member can browse the entire party membership. For a party the realistic starting point is **Who Can See Members in General Groups** at **HR Local** or higher, and **Restrict Profiles to Shared Local Centers** on, so a member of one branch cannot enumerate another branch's membership. ### The limits of the privacy switches **Privacy Defaults are copied onto an account once, at creation, and never re-applied.** Changing them at **Settings** → **Modules** → **Users & Profiles** → **Privacy Defaults** does not touch a single existing member, and nothing stops a member switching a field you defaulted to admin-only back on for themselves. If a field must never be visible to other members, keep it off the profile form rather than relying on the default. **Financial permissions grant full profile visibility.** `FINANCIAL_LOCAL` on a chapter reads every field on every member of that chapter, privacy switches included, because it implies the assistant-level HR read. A branch treasurer is a full member-data reader for that branch. Weigh that before appointing one. **Make my profile completely private** is the strongest member-side control: it removes them from member lists and directory queries entirely, and their profile URL returns "This profile is private". It is overridden only by `ADMIN_TENANT`, `HR_TENANT`, `HR_LOCAL` over their chapter, and `ADMIN_PARENT_LOCAL` inside its regional scope. Three fields are hidden from ordinary members however the switches are set: **date of birth**, **member card ID**, and the **identity verification record**. Anonymous visitors and guest accounts always get the strictest treatment. ### Exporting the member list Exporting members to CSV requires `HR_LOCAL` at minimum and is capped at 500 rows per page. A plain member cannot download the directory even for fields they can read on screen, so field visibility and bulk access are two separate controls. Every export writes a `csv` entry to your organization's activity log naming who ran it. ### What is stored about identity documents, and in what form | Item | How it is stored | | ----------------------------------------------------------------- | ------------------------------------------------------------------- | | The document images | Orgo's S3 media bucket, under an unguessable file name | | Document number and personal number (CNP) | Written twice: once as plain text and once encrypted | | Names, dates, series, town, county, address read off the document | Plain text on the identity record | | Every create and every change to the record | An audit entry naming the administrator and the fields that changed | Identity data sits outside the member privacy switches entirely: a member cannot hide their identity record, and other members never see it. Only the permission levels named under [Verifying identity](#verifying-identity) can open one. **Orgo has no delete operation for an identity record and no retention timer.** The record is only removed when the underlying member or contact row is deleted from the database, which closing or deleting an account does not do. If your retention policy requires ID scans to be purged after a period, that has to be arranged outside the product, through Orgo support. For sensitive answers you collect yourself rather than read off a document, [custom fields](/docs/platform/users/custom-fields) with **Admin** visibility are enforced on the server for both reading and writing, and text, numeric, textarea and date fields can be encrypted at rest (AES-256-GCM, bound to your organization and that field, five encrypted fields per organization). Every request that decrypts a value writes a log entry naming the reader, their IP address and the endpoint. ### What an erasure request actually removes This is the section to read before you answer a member's request, because [account deletion](/docs/platform/users/deletion-of-account) does much less than the word suggests. **Deletion clears:** email address, phone number, the sign-in identifier (rewritten with a random suffix), chapter, every role assignment row (deleted, not end-dated, so the history of who held which office disappears), followed units and discussions, and access. Company memberships are end-dated. The member is removed from the directory and every listing, and their profile page returns an error for everyone including administrators. **Deletion keeps:** first and last name, date of birth, gender, addresses and town, bio, profile photo, social links, profession and education fields, custom field values, **uploaded identity documents**, **the adhesion record and its attachments**, payments and invoices, event registrations and attendance, and discussion posts and comments. The account row itself stays; deletion sets a status. "Deleted" in Orgo is an anonymisation of contact identifiers plus a permanent access block. It is not erasure. For a party this matters twice over, because the two records that most clearly evidence party membership, the signed adhesion and the identity document, are both among the things deletion leaves behind. Treat the built-in action as step one and remove the rest yourself against your own retention policy. Deletion also **notifies nobody and writes no audit entry**, so record the request and what you did in your own system. Note who may delete: `ADMIN_TENANT` (the button only appears for them), or `ADMIN_LOCAL` over the member's chapter for a member who has one. `HR_LOCAL` and `HR_TENANT` cannot: they see "This profile can be deleted permanently only by organization Admin" and a **Request delete** button that opens a support request. **Ordinary members cannot delete their own account** unless they are on the guest user type, so build the erasure route into your privacy procedure rather than pointing members at a button they will not find. ### Leaving, and the three ways to record it A member who wants out and a member who wants their data gone are making different requests. Handle them differently. | Request | Use | What happens | | ------------------------------------------------ | ------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | "I resign from the party" | [Resignation](/docs/platform/users/resignation) | A request with a mandatory reason, approved by `HR_LOCAL` over their chapter. Approval end-dates every open role, sets the user type to your **Guest User Type**, clears the adhesion link, sets the account Inactive or leaves it Active according to their choice, and emails them. Nothing is deleted | | "Put me down as lapsed / expelled / unreachable" | A [status](/docs/platform/users/statuses) change | Any status other than Active blocks sign-in, hides the profile from the directory and end-dates open roles. **Excluded** exists precisely so your records can say the departure was permanent | | "Delete my data" | [Account deletion](/docs/platform/users/deletion-of-account), then manual work | See above | Resignation approval reassigns the user type on every approval. **If no Guest User Type is configured, approving a resignation leaves the member with no user type at all.** Set one at **Settings** → **Modules** → **Users & Profiles** → **Configuration** → **User Types & Roles** before you turn the resignation module on. It is also what makes the adhesion link get cleared, which is how a resigned member stops pointing at their application. ### The audit trail you actually have **Settings** → **Developers** → **Logs**, `ADMIN_TENANT` only. There is no local-admin view of it. It records adhesion creation and status changes, identity creation and changes, `upload_identity`, member profile edits with the before and after values, CSV exports of members and contacts, and encrypted custom field reads. It does **not** record account deletion, and it does not write a row per record for cascades, bulk operations run by Orgo support, or background jobs. The per-application adhesion log at `/adhesion/{id}/log` is separate and reachable with `HR_LOCAL`. *** ## What to turn on Everything below requires `ADMIN_TENANT` to change, and the Settings screens themselves also require the **Orgo administrator** flag on your profile, which is a separate thing from the permission. See [Permissions](/docs/platform/permissions). ### Joining and leaving | What | Exact label | Where | Default | | ------------------------------------------------ | ------------------------------------------------------- | ------------------------------------------------------------------------------------------------ | ------------------------------------------------------ | | Membership applications | **Enable Adhesion Module** | **Settings → Modules → Users & Profiles → Configuration → Adhesion & Membership** | Off | | Nobody uses the platform without applying | **Mandatory Adhesion** | Same section | Off | | Video statement from the applicant | **Video recording** | Same section | Off | | Validation, background check and interview steps | **Review steps** | Same section | On | | ID document on the application | **Require identity verification** | Same section | On | | What approval grants | **Default User Type After Approval** | Same section | None | | Who is emailed about a new application | **Admin Email Address** | Same section | None. The chapter's HR team is always notified as well | | The send-back reason picker | **Draft Change Reasons** | Same section | None | | The application form | Field include and require checkboxes | **Settings → Modules → Users & Profiles → Adhesion Form** | Email always included | | The signed document | Header, Main Template, Footer | **Settings → Modules → Users & Profiles → Adhesion Template** | Orgo's built-in default | | Formal departures | **Enable Resignation Module** | **Settings → Modules → Users & Profiles → Configuration → Resignation & Membership Termination** | Off | | Force deactivation on approval | **Automatically Inactivate Accounts After Resignation** | Same section | Off | | What a resigned member becomes | **Guest User Type** | **Settings → Modules → Users & Profiles → Configuration → User Types & Roles** | None. Set it before enabling resignation | | Extra departure labels (Excluded, Unreachable) | **Extra User Statuses** | **Settings → Modules → All Modules** | Suspended on, the rest off | ### Identity | What | Exact label | Where | Default | | ------------------------------------------------ | -------------------------------------------------------- | -------------------------------------------- | ------- | | The module | **Enable Identity Validation** | **Settings → Modules → Identity Validation** | Off | | Tie identity to payments | **Require for Online Payments** | Same page | Off | | Accept a clean automatic read without a human | **Automated Identity Validation** | Same page | Off | | Drop address fields from the review form | **Hide Address Fields** | Same page | Off | | Cancel a subscription that was never reconfirmed | **Cancel Subscriptions Without Identity Reconfirmation** | Same page | Off | ### Structure | What | Exact label | Where | Default | | ----------------------------------------------------- | -------------------------------------- | ------------------------------------------------------------------------------ | ------- | | Chapters | **Enable Local Centers Module** | **Settings → Modules → Groups & Teams → Local Centers** | On | | One or more tiers above chapters, nested to any depth | **Enable Parent Centers** | Same page | Off | | A flat region label | **Enable Regions** | Same page | Off | | Sections inside a chapter | **Enable Organizational Units** | **Settings → Modules → Groups & Teams → Configuration** | Off | | Named posts with terms and permissions | **Enable Roles** | **Settings → Modules → Users & Profiles → Configuration → User Types & Roles** | On | | Transfer emails | **Local Center Request Notifications** | **Settings → Modules → Emails & Notifications → System Emails** | On | ### Dues | What | Exact label | Where | Default | | ---------------------------------------- | ------------------------------------------------ | ---------------------------------------------------------- | ---------------------------------------- | | Dues | **Enable Membership Fees** | **Settings → Modules → Payments & Fees → Membership fees** | On | | What members are billed against | **Membership Fee Product** and **Default Price** | Same page | None. Nothing charges until both are set | | Record cash collected by a branch | **Allow Mark as Paid** | Same page | On | | Arrears cost a member their access | **Fee Payment Mandatory** | Same page | Off | | Statutes require unbroken payment | **Continuity Mandatory** | Same page | Off | | Branch-level dues | **Local Center Fees Enabled** | Same page | Off | | The branch treasurer's collection screen | **Local Center Members Table** | Same page | Off | ### Governance | What | Exact label | Where | Default | | ------------------------- | ---------------------------------- | ---------------------------------------------------------------------------- | ------- | | Internal elections | **Enable Voting Module** | **Settings → Modules → Voting** | On | | The register of decisions | **Enable Official Gazette Module** | **Settings → Modules → Files & eDocuments → Official Gazette** | Off | | The leadership map | **Organizational Chart** | **Settings → Modules → Users & Profiles → Configuration → Profile Settings** | Off | ### Data protection | What | Exact label | Where | Default | | --------------------------------------------------------- | ------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------- | ---------------------------------------- | | Who can browse the whole member list | **Who Can See Members in General Groups** | **Settings → Modules → Users & Profiles → Configuration → Privacy & Visibility** | All Users | | Who can filter members by chapter | **Who Can See Local Center Members** | Same section | All Users | | Keep branches out of each other's profiles | **Restrict Profiles to Shared Local Centers** | Same section | Off | | Whether branch admins can change statuses and permissions | **Allow Local Admins to Modify User Permissions** | Same section | On | | Field visibility given to new accounts | **Name**, **Email**, **Phone**, **Age**, **Town**, **Profile Image**, **Profession**, **Social Media** | **Settings → Modules → Users & Profiles → Privacy Defaults** | Copied onto an account once, at creation | *** ## Setup order The order matters. Several screens stay hidden until an earlier switch is on, and two things cannot be undone afterwards: a chapter's currency, and the fact that a member list left open has already been read. Legal name, registration number, address, currency, timezone, and the GDPR and terms URLs, at [Organisation info](/docs/platform/organisation/organisation-info). Then go to **Settings** → **Modules** → **Users & Profiles** → **Configuration** → **Privacy & Visibility** and set **Who Can See Members in General Groups**, **Who Can See Local Center Members** and **Restrict Profiles to Shared Local Centers** before anybody joins. Both selectors ship on **All Users**, and tightening them later does not un-see anything. **Done when** the organization card carries your legal details, and the Privacy & Visibility section still shows the levels you chose after a page reload rather than **All Users**. Turn on **Enable Parent Centers** at **Settings** → **Modules** → **Groups & Teams** if you have any tier above your branches. Then build the tree top down: create each tier that holds others first, flag it **It's a parent chapter**, and only then create the chapters below it with **Belongs to parent chapter** set. The picker only offers chapters already flagged as parents, so building bottom up means going back to fix every link. A middle tier carries both settings at once. Set each chapter's currency carefully. A chapter currency is set once and can never be changed afterwards. **Done when** the Chapters list shows every tier indented under the right one above it, each carrying the currency you intend to collect dues in. Reshaping the tree later needs `HR_TENANT`, so get it right while you still hold everything yourself. **Settings** → **Modules** → **Users & Profiles** → **Roles & User types**. Set the level to match the post (**Organisation**, **Parent chapter**, **Chapter**, or a unit type) and attach permissions to roles, never to user types, because a user type cannot carry a permission at all. Create the guest user type in the same pass and select it as **Guest User Type** under **Configuration** → **User Types & Roles**. Resignation needs it later, and approving a resignation without it leaves the member with no user type at all. **Done when** every post appears in the Roles list with the right level, every post meant to administer something has a permission attached, and **Guest User Type** names a type instead of showing an empty picker. **Settings** → **Modules** → **Users & Profiles** → **Custom Fields**. Anything your statutes require that Orgo does not ship a field for. Decide visibility and encryption on each one now, not later. **Admin** visibility is enforced on the server for both reading and writing, and encryption is available on text, numeric, textarea and date fields, capped at five encrypted fields per organization. See [Custom fields](/docs/platform/users/custom-fields). **Done when** every field on your list exists and, for each one, you can say in a sentence who reads it and whether it is encrypted. Template first, at **Settings** → **Modules** → **Users & Profiles** → **Adhesion Template**: it is the document members sign, and the form only makes sense once you know what the document has to print. The three HTML areas and the placeholders are described under [The three pieces you configure](#the-three-pieces-you-configure). Then **Adhesion Form**, ticking the profile and custom fields the applicant fills in and which of them are required. **Done when** every placeholder in the template refers to a field the form collects, and every field you marked required is one an applicant can actually answer. **Settings** → **Modules** → **Users & Profiles** → **Configuration** → **Adhesion & Membership** → **Enable Adhesion Module**. Then set **Review steps**, **Require identity verification**, **Default User Type After Approval**, **Admin Email Address** and **Draft Change Reasons**. Leave **Mandatory Adhesion** off. It is the last switch in this list for a reason, and turning it on now locks members out while you are still learning your own turnaround. **Done when** the sidebar carries **Management** → **Adhesions**, that queue opens empty rather than erroring, and **Mandatory Adhesion** is still off. Apply, upload a document, sign, send, validate the identity, save both conclusions, approve. Do it as a real applicant, not by reading the settings back. This is the step that surfaces a template placeholder you got wrong and a required field nobody can answer, while the only person affected is you. **Done when** your row sits at **Adhesion success** in the queue, the signed PDF opens from the **Signed document** column and prints your details in the right places, and the **Log** panel carries a dated entry for the validation, the interview and the decision. Connect Stripe first (the organization needs a **Country** before it will connect). Then create the fee product with its **Period** and **Cycle beginning**, add one price per membership level, and point **Membership Fee Product** and **Default Price** at it under **Settings** → **Modules** → **Payments & Fees** → **Membership fees**. Add **Local Center Fees Enabled** and **Local Center Members Table** if branches collect their own. See [Membership fees](/docs/platform/fees/fees). **Done when** the **Product Configuration** card names your product and a default price rather than showing empty selectors, because nothing charges anybody until both are set. **Enable Official Gazette Module** at **Settings** → **Modules** → **Files & eDocuments**, and **Organizational Chart** at **Users & Profiles** → **Configuration**. The chart needs roles to exist and be assigned before it draws anything, which is why it comes after step 3. **Done when** the sidebar carries **Official documents**, and the chart draws a box with a count on it for every role somebody currently holds. **Settings** → **Modules** → **Users & Profiles** → **Configuration** → **Resignation & Membership Termination** → **Enable Resignation Module**. Decide **Automatically Inactivate Accounts After Resignation** according to whether your statutes let a resigned member keep an account. **Done when** a test resignation, once approved, leaves the member on your guest user type rather than on none, with every open role end-dated. Import after the structure, the user types and the fee product exist, so imported members land in the right chapter on the right price. See [Import](/docs/platform/customization/import). **Done when** the members list shows your real roster, and a spot check of ten members finds each one in the right chapter and on the right membership category. Switching it on redirects every member without a successful application to their own application page on every route. Run it against one small chapter first, and watch your queue turnaround before widening it. **Done when** a member of the pilot chapter without a successful application lands on their application page wherever they navigate, while members holding `ADMIN_LOCAL` or above still reach the rest of the platform. *** ## Limits worth knowing before you start * **Identity Validation is not identity verification.** No register is consulted, no photo is compared, and outside Romania approving a record only requires a first and last name. * **Automatic document reading is Romania only.** Old ID card, new ID card and passport, keyed off the CNP. Everywhere else an administrator types the details in. * **PDFs are rejected as identity uploads.** PNG, GIF and JPEG only. * **There is no expired identity state and no re-check reminder for members.** Expiry is only checked at the moment somebody tries to validate a document. * **Identity records cannot be deleted from the product, and there is no retention timer.** Purging ID scans has to be arranged through Orgo support. * **Account deletion is not erasure.** It keeps the name, profile fields, custom field values, uploaded identity documents and the adhesion record, writes no audit entry and notifies nobody. * **Ordinary members cannot delete their own account** unless they are on the guest user type. An administrator does it on their behalf. * **Adhesion approval does not change the account status.** A member approved while sitting on **New request** still cannot sign in. * **Creating a vote needs `ADMIN_TENANT` or `HR_TENANT`.** A branch administrator cannot open a ballot for their own branch. * **Orgo has no quorum or majority threshold.** It reports counts and percentages; your statutes are applied by people. * **The integrity code is tamper evidence, not a signature.** It says no ballot recorded at or before that point was altered afterwards. It says nothing about identity, eligibility or the choice made. * **Event App ballots carry no voter link, even on a non-anonymous vote.** Run non-anonymous votes on the main member app. * **The anonymity setting freezes at publication.** A vote presented as secret can never be opened up, and the reverse is blocked too. * **The gazette has no per-entry visibility.** Every signed-in member reads every entry; **Private** is a label, not a restriction. * **Gazette document types are reference data.** New ones come from Orgo support, not from a settings screen. * **The organizational chart has no public version.** It cannot serve as the leadership page on your website. * **Privacy defaults apply once, at account creation.** Changing them later touches nobody, and a member can turn a field back on. * **Financial permissions read every profile field on their chapter's members**, privacy switches included. * **A transfer moves the person, not their data.** Fees, invoices, discussions, additional roles and group memberships all stay attached to where they were created. * **A transfer is approved by the receiving chapter**, never by the one being left. * **Chapter fees are one-off only** and are never charged in the same checkout as the party fee. * **Donations produce no receipt document**, and a chapter designation on a gift does not route the money to that chapter's account. * **The activity log is `ADMIN_TENANT` only.** There is no chapter-scoped audit view for a branch secretary. *** ## Setup checklist Work down this list once and your party is live. Each line is an outcome you can see on screen, in the same order as [Setup order](#setup-order) above. * [ ] Organization profile complete under **Organisation info**, with legal name, registration number, address, currency, timezone and the GDPR and terms URLs * [ ] Privacy floor set before anybody joins: **Who Can See Members in General Groups** and **Who Can See Local Center Members** raised off **All Users**, and **Restrict Profiles to Shared Local Centers** deliberately on or off * [ ] Chapters created, each under the right parent and each with the currency you will collect dues in, because a chapter currency can never be changed * [ ] Roles created for every office at the level that matches the post, with permissions attached to roles and never to user types * [ ] **Guest User Type** selected under **User Types & Roles**, before the resignation module goes anywhere near an on position * [ ] Custom fields created, each with its visibility and its encryption decided * [ ] Adhesion template written, with the placeholders your statutes need and `{{signature}}` and `{{dateSignature}}` in the signature block * [ ] Adhesion form built, asking for every field the template has to print and nothing an applicant cannot answer * [ ] Adhesion module on with **Review steps**, **Require identity verification**, **Default User Type After Approval**, **Admin Email Address** and **Draft Change Reasons** set, and **Mandatory Adhesion** still off * [ ] One application run end to end by you: signed, sent, identity validated, both conclusions saved, approved, with the signed PDF checked and the log reading correctly * [ ] Stripe connected and the fee product pointed at from **Membership Fee Product** and **Default Price**, plus **Local Center Fees Enabled** if branches keep part of what they collect * [ ] **Official documents** in the sidebar and the organizational chart drawing your real leadership * [ ] Resignation module on, with a test resignation leaving the member on the guest user type rather than on none * [ ] Existing membership imported, spot-checked for chapter and membership category * [ ] A written answer to "what do we do when a member asks us to erase their data", because the product's Delete does not answer it * [ ] **Mandatory Adhesion** switched on only after a pilot chapter has run through the queue at a turnaround you are happy to defend *** ## Troubleshooting The identity document has to be validated first, with the **Validate** button in the Identity column of the queue. That precondition is enforced whenever **Require identity verification** is on for your organization. If you do not run identity checks at all, turn **Require identity verification** off and both the precondition and the upload step disappear. If you do run them but somebody else does the validating, note that reviewing an identity needs `HR_ASSISTANT_LOCAL` over the applicant's chapter, which `HR_LOCAL`, `FINANCIAL_LOCAL` and `ADMIN_LOCAL` all satisfy, so it does not have to be the same person who handles the adhesion. With **Review steps** on, both the Interview conclusion and the Background conclusion must be saved before an application can reach **Adhesion success** or **Adhesion rejected**. Open **Conclusions** on that row, write both, then set the status. Conclusions can be saved while the application sits at validated, background checked, interviewed or canceled. They cannot be saved while it is still Initiated or pending, and they are read-only once a decision is made, which is deliberate: the note that justified the decision should not change after it. Approval sets the full member flag and the user type. It does not touch the account [status](/docs/platform/users/statuses), and only **Active** permits a sign-in. If you also run **Manual Approval**, a new registration lands on **New request** and stays there until somebody approves the status separately, on the member's **Permissions** tab or from the **New requests** button on the member directory. Running both gates is a defensible choice for a party, but it is two approvals, and it is the usual cause of "we admitted them last week and they say nothing works". If you do not need both, drop **Manual Approval** and let the adhesion be the gate. No. The identity step inside an adhesion is driven entirely by **Require identity verification** in the adhesion settings. The upload creates the identity record and runs the automatic read regardless of whether the module is on, and the **Validate** button in the adhesion queue works the same way. Switch the module on when you want identity tied to payments: **Require for Online Payments**, the upload reminder ladder, the pre-renewal reconfirmation emails, and the identity email templates. A party that only checks IDs at admission does not need it. Creating a vote requires `ADMIN_TENANT` or `HR_TENANT`, which are both organization-wide. `ADMIN_LOCAL` over a chapter does not qualify, even though the vote itself can be scoped to that chapter as a group vote. Two workable shapes. A national officer creates each branch ballot and hands management over: once a vote exists, `HR_LOCAL` on the vote's group can publish, close, archive, duplicate and export it. Or you accept the wider grant and give branch election officers `HR_TENANT`, which lets them see and manage member data across the whole party. For most parties the first is the right trade. Only partly, and it is worth being precise with your members about what you are offering. The integrity code they were shown after voting confirms that no ballot recorded at or before that moment was altered, deleted or inserted afterwards. It does not identify them, does not reveal their choice, and is not countersigned by anybody outside Orgo. It is tamper evidence over the stored ballots. What it cannot do is show a voter their own ballot, because on an anonymous vote (the default) no link between the voter and the ballot is stored anywhere. That is the price of the anonymity, and it is the right price for a secret ballot. If your statutes require individually verifiable ballots, an anonymous Orgo vote does not deliver that, and a non-anonymous one gives you a per-voter record that is visible to whoever can manage the vote, which is a different property entirely. **Who Can See Members in General Groups** is at its default of All Users. Raise it under **Settings** → **Modules** → **Users & Profiles** → **Configuration** → **Privacy & Visibility**, along with **Who Can See Local Center Members**, and switch **Restrict Profiles to Shared Local Centers** on so a member of one branch cannot open profiles in another. Then check the two things those settings do not cover. Privacy defaults were copied onto existing accounts when they were created, so tightening them now changes nobody: existing members keep whatever their fields were set to, and can change them themselves. And anyone holding a financial permission on a chapter reads every field on every member of that chapter regardless, so audit who holds `FINANCIAL_LOCAL`. Deletion clears the email, phone, sign-in identifier and chapter, deletes the role assignment rows, cuts every session, and removes the person from the directory and every listing. It keeps the name, date of birth, gender, addresses, profile photo, custom field values, payments and invoices, event attendance, discussion posts, **the uploaded identity documents** and **the adhesion record and its attachments**. For a party those last two are exactly the records that evidence membership, so deletion on its own is not an answer to an erasure request. Treat it as step one. Then decide, against your own retention policy, what to do with the remaining fields, and note that identity records cannot be removed from the product at all: that needs Orgo support. Record the request and your actions outside Orgo, because deletion writes no audit entry and notifies nobody. Three different acts with three different records. **Resignation** is the member's own decision with a reason attached. Approval end-dates every open role, sets the user type to your guest type, clears the adhesion link and sets the account Inactive or leaves it Active according to their choice. Nothing is deleted, and the reason and the reviewer's exit conclusion stay on record. **Excluded** (or **Suspended**) is your decision. It blocks sign-in, hides the profile from the directory and end-dates open roles, exactly as Inactive does; the difference is what your records say. Turn Excluded on under **Settings** → **Modules** → **All Modules** → **Extra User Statuses** first, because only Suspended is on out of the box. **Deletion** is a data action, not a membership one. Use it only when someone asks to be removed, and read the accordion above before you do. No **Guest User Type** is configured. Approval reassigns the user type unconditionally, so with nothing configured the member is left with none at all. Set one at **Settings** → **Modules** → **Users & Profiles** → **Configuration** → **User Types & Roles**, then fix the affected members by hand on their profile. The guest user type is also what makes the adhesion link get cleared on approval, so without it a resigned member's profile still points at their application. A [transfer request](/docs/platform/groups/transfers) is approved by `HR_LOCAL` on the **destination** chapter, not the source. A source-side administrator can raise the request but cannot wave it through, so an unapproved request sits in the queue indefinitely: nothing expires it and nothing auto-approves it. The list has no menu entry of its own, which is why requests get forgotten. Bookmark it, and check that the destination branch has somebody holding `HR_LOCAL`. When it is approved, remember what does not move: their dues history, invoices, discussions, additional roles and group memberships all stay attached to where they were created. Settle anything outstanding at the old branch before approving if your accounting requires it. That is how the register works and there is no setting that changes it. Every signed-in member of the party can open every entry in the [Official Gazette](/docs/platform/official-gazette), and the **Private** / **Public** radio on the form records a status on the entry rather than restricting who reads it. Keep the register for what your statutes require you to publish to the membership. Put anything narrower in [Files](/docs/platform/files), which has folder and group level permissions, or attach it to a [private group](/docs/platform/groups/private-groups) for the body that owns it. Neither the gazette nor the organizational chart notifies anybody. Publishing a gazette entry sends no email, no notification and no digest, and the chart simply redraws on the next page load. Announce what matters yourself, with a [newsletter](/docs/platform/newsletter) or a [discussion](/docs/platform/discussion) post linking to the entry. Votes are the exception: publishing a vote and closing one both send a notification, in the app and by email for members whose **Voting / Polls** preference is set to Instant. That is the setting working as designed: with **Mandatory Adhesion** on, every member without a successful application is redirected to their own application page on every route until it succeeds. Only members holding `ADMIN_LOCAL` or above, and members who already hold the configured success user type, are exempt. Short term, switch **Mandatory Adhesion** off while you clear the queue; the applications themselves are untouched. Longer term, either widen who reviews (the queue is open to `HR_LOCAL` per chapter, so branch secretaries can clear their own) or turn **Review steps** off if the interview and background steps are not something your statutes require. *** ## Related * [Adhesion](/docs/platform/users/adhesion) - the application, its review chain, the signed document and the per-application log * [Identity Validation](/docs/platform/identity-validation) - what an ID check captures, and what it does not prove * [Resignation](/docs/platform/users/resignation) - formal departure, and what approval changes * [Privacy settings](/docs/platform/users/privacy-settings) - who can see which member data, and where the switches stop * [E-voting](/docs/platform/e-voting) - eligibility, anonymity and the integrity record * [Chapters](/docs/platform/groups/local-groups) - the territorial tier and its permission scopes * [Setup templates](/docs/platform/templates/index) - the other playbooks # Orgo for scouting and youth organizations Source: https://orgo.space/docs/platform/templates/scouting How a scouting association sets Orgo up: your own vocabulary, groups and sections, youth members with parents, adult volunteers, badges, and camps **Built for** scouting associations, guiding organizations, cadet forces, church youth work and any organization whose members are mostly children led by vetted adult volunteers. **Replaces** the group secretary's spreadsheet, the district's separate copy of it, and the paper consent pack that gets rebuilt before every camp. Orgo is a general membership platform, so nothing in it is called a troop or a patrol out of the box. This page is the route map: which features carry the shape of a youth organization, what each one genuinely enforces, and where you will have to work around a limit. *** ## Who this is for You are in the right place if most of these are true: * Your members are organized geographically (district, group, section) rather than as one flat list. * A large share of your members are children, enrolled by a parent who also needs an account. * Adults are volunteers holding named positions with terms, not employees. * You award progression: badges, levels, promises, training courses. * You run residential events where you must know who is allergic to what, and who signed the consent form. * Your organization has its own words for all of the above, and "member of local center" is not one of them. ### Before you start Settle these before you open a single settings screen. Each one is a decision the setup will ask you for, and each is more expensive to change once members exist. Tick them off on paper first. * [ ] **Structure named.** You can name every layer, from the national body down to the smallest team, and you know which layer owns the member list. * [ ] **One word per concept.** You have written down what you call a district, a group, a section, a patrol and an age level. One word each, no synonyms. * [ ] **Age sections listed with their ranges.** For example Beavers 6 to 8, Cubs 8 to 10.5, Scouts 10.5 to 14. You know which section a member sits in and which age level they count as for pricing. * [ ] **Volunteers listed with their posts.** Each adult, the position they hold, the layer that position belongs to, and the date they started. * [ ] **Safeguarding policy on the desk.** You know what your policy makes you record for every adult, and which of those records expires and after how long. * [ ] **Youth data audience decided.** You know who is allowed to read a child's medical, dietary and contact details: everyone who can open an event, chapter administrators only, or a named safeguarding lead. * [ ] **Parent consent approach chosen.** Either a signed document you must be able to produce on demand, or a tick you only need to have collected. The two lead to different features. * [ ] **Subs schedule decided.** What each age level pays, whether the group charges its own dues on top of the national ones, when the fee year runs, and in which currency. * [ ] **Data ready.** You have dates of birth for your members, and you know which languages your organization runs in. *** ## Speaking your language Start here, before you configure anything else. Orgo lets you replace the wording it ships with your own, which is how "full member" becomes "Promise", "user type" becomes "Age level" and "chapters" becomes "Local groups". The feature is called **Texts**, at **Settings** → **Customization** → **Texts**, and it needs `ADMIN_TENANT`. The page is a two-column table: **System Expression** on the left is the phrase Orgo ships, **Custom Expression** on the right is the phrase you want in its place, with one Custom Expression column per language you have enabled. You do not type technical keys. **Add Text Replacement** opens a search over the whole interface catalogue, and you tick the results you want to override. ### A worked mapping These are the phrases a scouting association usually changes first. The middle column matters: one concept is almost never one row, because the catalogue stores singular, plural and lowercase forms separately, and stores longer sentences whole. | Orgo's wording | Rows you will find when you search for it | Scouting wording | | -------------- | --------------------------------------------------------------------------------------------------------- | -------------------------------- | | Member | `Member`, `Members`, `member`, `members` | Scout, Scouts | | Full member | `Full member`, `Full members`, `Only full members`, `Only NOT full members`, `Date joined as full member` | Invested member, Date of Promise | | Chapter | `Chapter`, `Chapters` | Group, Groups | | Local Center | `Local Center`, `Local center` | District | | User type | `User type`, `User Types` | Age level, Age levels | | Group | `Group`, `group`, `groups` | Team, Teams | | Event | `Event`, `Events`, `event`, `events` | Activity, Activities | | Membership fee | `Membership`, `Membership fee`, `Fees` | Subs, Annual subs | | Badge | `Badge`, `Badges` | Award, Awards | | Volunteer | `Volunteer` | Leader | Searching one fragment shows why. Typing "full member" into **Add Text Replacement** returns eight separate rows, each an independent replacement you have to tick and fill in: Add Text Replacement panel over the Text Replacements page, searching for full member and listing eight separate catalogue rows with checkboxes, including Full members, Is Full Member, Only full members and Only NOT full members with their source keys in brackets So: search a distinctive fragment, tick every form the search returns in one pass, then fill in the **Custom Expression** column for each enabled language and save. Your own session updates immediately; other people pick the new wording up on their next page load. You do not need to relabel unit layers. A unit type carries its own **Title** and **Plural name**, which you type yourself at **Settings** → **Modules** → **Groups & Teams** → **Unit Types**. Call the type "Section" or "Patrol" there and it appears that way on tabs and buttons without any text replacement. ### The real limit **Texts is applied in the browser only.** The replacements are stored on your organization and merged into the interface translation catalogue when the app loads (`client/src/utils/i18n.js`). Nothing on the server reads them. | Surface | Uses your wording | | --------------------------------------------------------------------- | ------------------------------ | | Sidebar, page titles, tabs, buttons, form labels, empty states | Yes | | The event app and the mobile app | Yes, same catalogue | | **System and notification emails** | **No** | | **Generated PDFs** (invoices, adhesions, signed documents) | **No** | | Your own data: group names, event names, badge names, unit type names | Not applicable, you wrote them | An organization that renames "member" to "scout" everywhere in the interface will still send emails that say "member". Fix that separately by editing the wording in [Email templates](/docs/platform/emails/email-templates). Plan for it: it is the single most common surprise after a relabelling pass. Two more things worth knowing before you start replacing words. A replacement swaps that exact phrase everywhere it appears, so a short common word like "Group" also changes inside sentences that merely use it. And nothing stops you giving two different features the same name, which is easy to do when both chapters and groups become "Teams". Full detail: [Texts](/docs/platform/customization/labels). *** ## What to turn on Every module and setting below is at **Settings** → **Modules**, and every one of them requires `ADMIN_TENANT` to change. Most are off until you switch them on. The two marked **already on** ship enabled, so your job there is to confirm rather than to enable. | Module and tab | Setting | What it buys you | | --------------------------------------------------------------- | -------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | | **Groups & Teams** → **Local Centers** | **Enable Local Centers Module** (already on) | Chapters: your groups or districts, each with their own members, events, files, dues and admins | | **Groups & Teams** → **Local Centers** | **Enable Parent Centers** | Layers above a chapter, nested as deep as you need, and the `ADMIN_PARENT_LOCAL` and `HR_PARENT_LOCAL` permissions that reach down through them | | **Groups & Teams** → **Local Centers** | **Enable Regions** | A flat region label for grouping and filtering. Grants no permissions | | **Groups & Teams** → **Configuration** | **Enable Organizational Units** | Sections and patrols inside a chapter | | **Groups & Teams** → **Configuration** | **Enable Role Groups** | Groups whose membership is a query over roles and profile data | | **Groups & Teams** → **Unit Types** | one type per layer | Define **Section**, then **Patrol** with **Parent unit type** set to Section | | **Users & Profiles** → **Configuration** | **Enable User Types** | Age levels as a member category, one per member | | **Users & Profiles** → **Configuration** | **Enable Roles** | Named positions with terms and permissions | | **Users & Profiles** → **Configuration** | **Enable Volunteer Roles** | Adds a **Volunteer** flag to a user type | | **Users & Profiles** → **Configuration** | **Enable Family Members** | The Family tab: parents, guardians and children in one record | | **Users & Profiles** → **Configuration** | **Non-Member Family Profiles** | Name and contact details for relatives who never sign in | | **Users & Profiles** → **Custom Fields** | your own fields | Medical notes, dietary needs, emergency contact, check expiry dates | | **Gamification & Courses** → **Gamification** | **Enable Gamification Module** | Badges and the Badges tab on every profile | | **Gamification & Courses** → **Gamification** | **Enable badge categories** | Groups badges so the award picker stays usable | | **Gamification & Courses** → **Gamification** | **Enable hours tracking** | Volunteering hours, and badges awarded from an hours total | | **Gamification & Courses** → **Courses** | **Enable Courses** (already on) | Leader training as self-paced courses | | **Files & eDocuments** → **eDocuments** | **Enable eDocuments Module** | Consent forms, volunteer agreements and codes of conduct, signed on screen | | **Identity Validation** | **Enable Identity Validation** | ID document upload and admin review. Read the limits in [Adult volunteers](#adult-volunteers) first | | **Payments & Fees** → **Membership fees** | **Enable Membership Fees** | Subs. Also **Local Center Fees Enabled** for a second, group-level fee | | **Payments & Fees** → **Membership fees** → **Pricing Options** | **Enable Age Restrictions on Prices** | Age-conditioned fee prices. Read the limit in [Limits worth knowing](#limits-worth-knowing-before-you-start) | Not a module: **Texts** and **Languages** live under **Settings** → **Customization**. ### Check the chapter layer first **Settings** → **Modules** → **Groups & Teams** → **Local Centers** carries your group and district structure, and it is the one screen worth opening before all the others, because people go looking for a switch that is already flipped. Local Centers tab of the Groups and Teams settings, with the Enable Local Centers Module switch already on at the top and a Basic Configuration block below it listing Enable Regions, Enable Parent Centers, Local Center User Types, Multi local center access and the other per-chapter switches **Enable Local Centers Module** is on for a new organization, so the whole **Basic Configuration** block below it is already visible. Every switch inside that block starts off, and those are the ones you actually have to decide about. The organization in the screenshot has already turned three of them on, which is why they read blue there: * **Enable Parent Centers**. Turn it on if you want any layer above your groups. It is not limited to one: county holding district holding group is a single chapter tree, built by flagging each layer that holds others with **It's a parent chapter**. * **Enable Regions**. Turn it on only if you want a flat reporting label. It grants no permissions, and it adds a **Regions** entry to the module menu on the left. * **Open Access Local Centers**. Turn it on only if every member should see content from every group and be notified about it. The rest are still off in that screenshot, **Multi local center access** among them. Turn that one on only if named people need to reach a second group without moving there. *** ## Setup order The order matters. Several of these screens are hidden until an earlier one is on, and a few decisions are hard to reverse once members exist. Each step says what you do, where in the interface it happens, and how you can tell it worked, so you can follow along with Orgo open beside you. Work down the table above, at **Settings** → **Modules**. Turning a module on only reveals screens, so it is safe to do in one pass, and you can leave the settings inside each one until later. Two of them change the settings menu itself, which is your proof the pass landed: **Enable Organizational Units** adds a **Unit Types** tab to **Groups & Teams**, and **Enable Regions** adds a **Regions** tab under **Local Centers**. **Done when:** **Groups & Teams** shows a **Unit Types** tab beside **Configuration** and **Local Centers**, and every switch in the table above is in the position you left it after a page reload. Enable your languages first at **Settings** → **Customization** → **Languages**, then do the replacements at **Settings** → **Customization** → **Texts**. That order matters: the Texts table grows one Custom Expression column per enabled language, so a language added later means going back through every row you already wrote. Do the whole pass before you train anyone, so nobody learns Orgo's words and then has to unlearn them. **Done when:** your own sidebar and page titles read in your vocabulary as soon as you save, and the Texts table has no empty Custom Expression cell in any enabled language. See [Languages](/docs/platform/customization/languages) and [Texts](/docs/platform/customization/labels). **Settings** → **Modules** → **Groups & Teams** → **Unit Types** → **Add Unit Type**. One type per layer of your structure, created top down: **Section** first, then **Patrol** with **Parent unit type** set to Section. Tick **Within local center** on every type that belongs to a group. Without it the type has nowhere to live, and it will not appear as a tab on a chapter. **Done when:** each type below the top one names its parent on the Unit Types list, and opening any chapter shows a tab named after your top-level type. **Settings** → **Modules** → **Users & Profiles** → **Roles & User types** → **Add role**. Set **Level** to **User type**, fill in **Title** and **Plural title**, and create one per age band. Give each one a **URL Slug** while you are there. The slug is what publishes a joining page at `/join/` for that age level, and it is also the way around the volunteer and parent picker limit described in [Adult volunteers](#adult-volunteers). Role editor with Level set to User type, Title and Plural title filled in, the Not eligible for fee and Parent switches below them, and a URL Slug field whose hint reads Used for the registration URL /join/[slug] Note what is not on this screen: there is no permissions section. Levels above **User type** have one, and that is the whole point of the next step. **Done when:** every age band appears in the Roles list with a green **User type** tag in the Level column, and `/join/` opens a joining page rather than a not-found. Same screen, one role per post. Set **Level** to the layer the post belongs to: **Organisation** for national officers, **Parent chapter** for district commissioners, **Chapter** for group leaders, or one of your unit types for section leaders. Attach the permissions the post needs here, never to a user type. **Done when:** the Roles list shows each post with the right Level tag, and the **Permissions** column is filled in for every post that is meant to administer anything. **Chapters** → **Create chapter**, one per group. If you enabled layers above your groups, build top down: create each district or county first and tick **It's a parent chapter** on it, then create the chapters below it with **Belongs to parent chapter** set. The parent picker only offers chapters already flagged as parents. Set the currency carefully. A chapter currency can be set once and never changed afterwards, because past payments and the connected Stripe account are bound to it. **Done when:** every group appears in the chapters list, indented under the right layer above it, and each with the currency you intend to collect subs in. From the chapter's unit tab, or from the drag-and-drop segmented board that `ADMIN_LOCAL` gets. Create your sections first, then the patrols inside them, so each patrol has a section to attach to. **Done when:** the chapter's org structure shows every section, each patrol nested under its section, and no unit sitting at the top level by accident. **Settings** → **Modules** → **Users & Profiles** → **Custom Fields**. Medical notes, dietary requirements, emergency contact, photo permission, and the safeguarding dates from your **Before you start** checklist. Decide **Visibility** on each field now, and decide it against where the answer is collected. A field above **Public** is silently discarded on the public registration pages, so anything you need at sign-up has to be **Public** there, with profile visibility controlled separately. Custom field editor showing the Title, the Field type dropdown, the reorderable list of options, and the Visibility selector above the Save, Cancel and Remove buttons **Done when:** every field on your list exists, and for each one you can say in a sentence who reads it and which form collects it. See [Custom fields](/docs/platform/users/custom-fields). In that order, because each one depends on the last. The [registration form](/docs/platform/users/registration-form) must include **Birthday** and mark it required, or the age logic in the fee has nothing to read. Then create the [fees](/docs/platform/fees/fees) and one price per age level. Then build the [e-document templates](/docs/platform/contracts) for parental consent, the volunteer agreement and the code of conduct. **Done when:** a test registration on your own joining page creates an account with a date of birth on it, that account is offered the right price for its age level, and any document you marked **Mandatory document** is waiting for it in onboarding. [Import](/docs/platform/customization/import) handles members, badge categories, badges and badge assignments as separate passes. Run them in that order: an assignment cannot attach to a badge that does not exist yet, and a badge cannot file itself under a category that has not been imported. **Done when:** the member count matches your source list, spot-checked members sit in the right chapter and unit, and their badge tabs show the awards you imported. *** ## Structuring your association Four separate mechanisms, and picking the wrong one is the most expensive mistake on this page because moving people afterwards is manual work. | Your structure | Model it as | Why | | ---------------------------------------------------- | ------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- | | National association | The organization itself | Everything lives inside it | | District, county or area, and any layer between them | Parent chapter, with **Enable Parent Centers** on. Nest them as deep as your structure goes | `ADMIN_PARENT_LOCAL` and `HR_PARENT_LOCAL` reach an anchor chapter and every chapter beneath it, at any depth | | Group or troop | Chapter | Owns its members, events, files, discussions, its own dues, and its own administrators | | Section (Beavers, Cubs, Scouts, Explorers) | A unit type called Section, one unit per section | Units belong to a chapter, carry a member type and appear in the org chart | | Patrol, six or lodge | A unit type called Patrol with **Parent unit type** set to Section | Units nest as deep as your chain of types | | Age level as a category | User type | One per member. Drives fee price, menu visibility, registration form and reports | | Region for reporting only | **Region** | A flat label. It grants nothing and is not a permission boundary | The distinction that catches people out: a **unit** is where a member sits in the structure, a **user type** is what kind of member they are. Most associations need both, because a Cub sits in the Cub section (a unit) and is also a Cub for pricing and forms (a user type). A [private group](/docs/platform/groups/private-groups) is neither: it is a working space people join for a project. Things to plan around: * **Every member has exactly one chapter.** **Multi local center access** grants named extra chapters to a member from their profile, but that is an access grant, not a second home group. Moving someone for good is a [transfer request](/docs/platform/groups/transfers). * **A member can hold roles in several units at once**, so a leader who runs the Cub section and sits on the group committee is two role assignments, not a choice. * **The unit member Admin flag is not cosmetic.** It delegates scoped fee access and unit event attendance, so Orgo restricts it to people who already hold `HR_LOCAL`, `FINANCIAL_LOCAL` or `ADMIN_TENANT` over the chapter. Unit admins cannot appoint each other. * **`ADMIN_PARENT_LOCAL` reach is computed from the holder's own primary chapter**, not from a branch you pick. Give it to someone whose chapter sits under North District and they administer North District and everything beneath it, however deep, and there is no control that points it somewhere else. Give it to a district commissioner whose own chapter is North District and it stays inside North District, because a chapter flagged **It's a parent chapter** anchors to itself and the grant never climbs to the county above. * **Reshaping the tree is an organization-level job.** Changing a chapter's parent, or its **It's a parent chapter** flag, requires `HR_TENANT`. District and group administrators see those two fields greyed out and can edit everything else on the chapter form. Detail: [Local Centers](/docs/platform/groups/local-groups), [Units](/docs/platform/groups/units), [User types and roles](/docs/platform/users/user-types), [Role Groups](/docs/platform/groups/role-groups). *** ## Youth members and parents Turn on **Enable Family Members** and, if you want to hold details for relatives who never sign in, **Non-Member Family Profiles**. Both are at **Settings** → **Modules** → **Users & Profiles** → **Configuration** → **Family & Relationships**. Family and Relationships block of the Users and Profiles settings, with Enable Family Members and Non-Member Family Profiles both switched on and no other fields in the block Those two switches are the entire block, which is worth noticing: the two age values described below are not on this screen or any other, so there is nothing here to tune them with. A family is one record grouping parents, guardians and children. One family per person. Members reach it at **Profile** → **Edit** → **Family**; anyone with `HR_LOCAL` over the member's chapter sees and manages it from the same tab. ### Registering a child The normal path is: the parent registers themselves, opens their Family tab, and uses **Add** in the Children section to register the child. That single action: * creates an active account for the child, marked as a child account; * records a parental consent date and method against both the account and the family membership; * creates the parent's family if they do not have one and makes them its owner; * treats the email as already confirmed, because the parent supplied it. The child's email is optional, and a child registered without one gets a generated placeholder address. It cannot receive mail and cannot be used to sign in. Leave it blank only when you want a record rather than a login, which for under-8s is usually exactly what you want. Ordinary members can create their own family and add non-member relatives. Linking an **existing** member account into a family requires `HR_LOCAL`, on purpose: otherwise anyone could attach themselves to anyone. ### What the age settings actually do There are two age values on the organization, and neither behaves the way the names suggest. | Setting | Where it appears | What it really does | | --------------------------------- | ------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Minimum Registration Age** | Not on the settings screen. The field is commented out of the settings UI | Read in exactly one place: when a parent registers a child. If the child is younger and the waitlist is active for their chapter, the waitlist entry is flagged **underage** and the Children list shows an "In waitlist, underage" tag | | **Children Auth Restriction Age** | Not on the settings screen either | Restricts no authentication at all. It only drives a notification when a young member reaches that age | There is no age gate on public self-registration. Anyone can register through `/register` or `/join/` whatever birthday they type, and **Minimum Registration Age** is not consulted on those paths. If your jurisdiction requires parental consent below a given age, enforce it in your joining process and your terms, not in these settings. ### Consent Parental consent is recorded when a parent registers a child, as a date and a method, and it is stored on both the account and the family membership. It is not shown on any screen and there is no consent report. If you need to evidence consent, or you need consent for something specific like photography or overnight stays, use an [e-document](/docs/platform/contracts) template instead: that produces a signed, dated PDF you can show someone. ### The birthday field is load-bearing Add **Birthday** to your [registration form](/docs/platform/users/registration-form) and mark it required. Several features silently do nothing without it: * age-conditioned fee prices skip the age check entirely for a member with no date of birth, and the member falls through to whatever price matches next; * a member with no date of birth never matches an age-based [role group](/docs/platform/groups/role-groups); * the notifications about children reaching an age never fire. ### Fees and families Family membership does not change what anyone pays. Fees are resolved per member, there is no family tier and no sibling discount, and linking a child to a parent does not transfer or cover the child's fee. What a parent listed as managing a member **can** do is pay for them. For one payer covering several people by design, use [Companies](/docs/platform/users/companies) instead. Detail: [Family Members](/docs/platform/users/family-members), [Waitlist](/docs/platform/users/waitlist). *** ## Adult volunteers ### Positions, not people Permissions belong on roles, never on user types. A user type cannot carry a permission at all: the permissions section disappears from the editor the moment you set the level to **User type**. So "Cub Leader" as a category is a user type, and "Cub Leader" as a post with access to the section's members is a role. If you need both, create both. Both live in the same list at **Settings** → **Modules** → **Users & Profiles** → **Roles & User types**, and the **Level** column is what tells them apart: Roles list with Level and Permissions filters above a table whose Level column tags each entry as Organisation, Chapter or User type, and a Permissions column beside it Read that column as the reach of the post. The **Level** and **Permissions** filters above it are the fastest audit you can run: filter on a permission and you get every post that carries it, which is the list you should be able to justify to your safeguarding lead. Every role assignment has a **dateBegin** and an optional **dateEnd**. Ending the assignment ends the permissions it carried and leaves the assignment visible as history, which is what makes a leader handover one line of work rather than a permissions audit. Match the role's level to the scope of the post: | Post | Role level | Effective permissions | | --------------------- | ---------------------- | ------------------------------------------------------------------------------------------- | | National commissioner | **Organisation** | Tenant-level, for example `HR_TENANT` | | District commissioner | **Parent chapter** | `ADMIN_PARENT_LOCAL` or `HR_PARENT_LOCAL` across the district and everything beneath it | | Group scout leader | **Chapter** | `ADMIN_LOCAL` or `HR_LOCAL` over the group | | Section leader | Your Section unit type | Scoped to that unit, plus the unit **Admin** flag where they need fee and attendance access | ### The volunteer flag, and its trap **Enable Volunteer Roles** adds a **Volunteer** flag to a user type, and **Enable Family Members** adds a **Parent** flag the same way. A user type flagged **Volunteer** or **Parent** is excluded from the **User Types** picker on the general registration form, so an adult cannot pick "Leader" or "Parent" for themselves at `/register`. The "I want to Volunteer" and parent opt-in switches that used to sit on that form are disabled in the product today and never render, even though the settings screen still offers **Text displayed below volunteer opt-in switch**. The exclusion is stricter than it looks. The picker only offers a type that has never had either switch touched, so turning **Volunteer** on and then off again leaves the type out of the picker for good. If a type vanished from `/register` after you experimented with the flags, that is why, and giving the type a slug is the way back. Route volunteers around it: give the volunteer user type a **URL Slug** and its own [registration form](/docs/platform/users/registration-form), then publish `/join/` as your leader application link. That page stamps the type from the slug and does not filter it out. Assigning the type after they join works too. ### Safeguarding checks: what Orgo does and does not do This is the section to read carefully, because the feature name promises more than the feature delivers. [Identity Validation](/docs/platform/identity-validation) collects a scan of an ID document, stores the details read off it, and puts the record in front of an administrator who approves or rejects it. Reviewing needs `HR_LOCAL` or above over the member's chapter. What it does: * accepts a document image (PNG, GIF, JPEG; PDFs are rejected), front and optionally back; * reads Romanian documents automatically (old ID card, new ID card, passport), keyed off the CNP; * for every other country, lets an administrator type the details in by hand; * records who approved it and when, and writes an audit entry for every change; * stores the document number and personal number encrypted as well as in plain text, and keeps images in an unguessable location. What it does not do, and what you must therefore run outside Orgo: * **no criminal record or vetting check.** It does not talk to any disclosure service, and nothing in the product performs a background check; * **no reference or interview tracking;** * **no expiry status.** An expired document keeps whatever status it had. Expiry is only checked at the moment somebody tries to approve it; * **no re-check reminder.** Renewal reminders exist only for payment-linked identities, not for volunteers; * **outside Romania, only a first and last name are required to approve a record.** Nothing forces an administrator to confirm the document is genuine. The practical setup for a scouting association is therefore layered: | What you need | Use | | -------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- | | Proof the volunteer signed the code of conduct and the volunteer agreement | An [e-document](/docs/platform/contracts) template with **Mandatory document** on, which holds them in onboarding until they sign | | The date a disclosure or vetting check was completed, and when it expires | Two **Date** [custom fields](/docs/platform/users/custom-fields) with **Admin** visibility | | A scan of the check itself | A **File Upload** custom field with **Admin** visibility, or Identity Validation if it is an ID document | | Evidence the volunteer completed safeguarding training | A [course](/docs/platform/courses) with **Award badge on completion**, or a badge awarded by hand | | The list of who is cleared | A member list column or export filtered on those fields | Nothing in Orgo watches a **Date** custom field and warns you when it passes. There is no expiry engine and no reminder. Put a recurring calendar reminder on whoever owns safeguarding, and run the export on a schedule. *** ## Progression and recognition Badges need the Gamification module (**Settings** → **Modules** → **Gamification & Courses** → **Gamification** → **Enable Gamification Module**). | Layer | Where | Notes | | ---------------------- | ------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | | **Badge Categories** | **Gamification & Courses** → **Badge Categories** | Optional, behind **Enable badge categories**. An image and a title. Keeps the award picker usable once you have a full scheme | | **Badges** | **Gamification & Courses** → **Badges** | Title, artwork, category, an optional hours threshold, an optional points threshold, and a default note | | **Volunteering hours** | The member's Badges tab | Behind **Enable hours tracking**. Each entry has a period, hours, title and notes | | **Points and tiers** | **Gamification** → point rules | Behind **Enable tiers/levels by points**. Points come from payments, attendance, referrals and discussion activity | Your scheme ends up as one list at **Settings** → **Modules** → **Gamification & Courses** → **Badges**: Badges settings list with one row per badge showing its image, its name, a Type column naming the badge category, and an amber hours pill on the badges that carry an hours threshold Two columns there are conditional, which is a quick way to check your settings took. The **Type** column, which holds the badge category, appears only when **Enable badge categories** is on. The amber hours pill appears only when **Enable hours tracking** or tiers is on, and it is the threshold that awards the badge automatically. Four ways a badge reaches a member: awarded by hand from their Badges tab (`HR_TENANT`, or `HR_LOCAL` over their chapter), awarded automatically when their logged volunteering hours pass a badge's **Hours number**, awarded on event attendance when the event names a badge, and awarded when a course enrolment is marked complete. A member can hold a given badge only once, and every automatic path checks first, so re-marking attendance never duplicates an award. Use **Pending** rather than **Completed** for work in progress. It is counted and filtered separately everywhere, which makes it a workable "started this badge" state. Things to know before you load your whole scheme: * **Deleting a badge deletes every award of it, from every member.** Deleting a category deletes the badges filed under it and their awards too. There is no undo. * **Nobody is notified when a badge is awarded or removed.** Announce the ones that matter yourself. * **A badge has no expiry and no renewal.** It records that something happened, not that a qualification is currently valid. For anything that lapses, use a **Date** custom field alongside it. * **Tier auto-promotion needs an ordering number that the settings screen does not expose.** Tier cards on a profile light up from the points threshold alone, but the promotion that writes the badge onto the member also reads a `level` field you can only set through the API. Award tier badges by hand unless you are willing to use the API. For leader training, [Courses](/docs/platform/courses) holds sections, lessons and quizzes with server-side scoring, restricted by user type and by chapter. Course completion awards a badge but produces no certificate: there is nothing to download or print. Detail: [Badges](/docs/platform/badges), [Gamification](/docs/platform/gamification), [Courses](/docs/platform/courses). *** ## Camps and events ### Collecting what you need before a camp Four steps, in this order. Editing any of it needs `EVENT_LOCAL` on the event's group, which `EVENT_TENANT` and `ADMIN_TENANT` satisfy across the organization. Open the camp's **Modify** screen and switch on **Require registration form for members**, under **Registration**. Paid events turn it on automatically and lock the toggle, so a ticketed camp is already done here. **Done when:** a **Registration form** entry appears in the event's sidebar, among **Participants**, **Program** and **Tickets**. Open that **Registration form** entry. The left pane offers fields, the right pane is the form you are building. Event registration form builder with the Standard fields and Custom fields tabs on the left over a list of available fields, and the chosen form fields on the right with Email and Full Name both marked required The **Standard fields** tab offers twelve fields with fixed labels (email, full name, phone, organisation, role, town, social links and company details) and **none of them covers dietary or medical information**. That is what the **Custom fields** tab beside it is for: **Text area** for medical notes and medication, **Checkboxes** for dietary requirements, **Yes/No** for photo permission, **Date** for a travel date, **Text input** for an emergency contact. **Done when:** the form fields pane on the right lists every medical, dietary and emergency contact field you need, each marked required or not on purpose, and **Save changes** has been pressed. Camp rules, refunds and cancellation go in **Custom text at bottom of registration form**, on the form's **Settings** tab. The GDPR and terms checkboxes are not yours to add: they appear on their own once your organization has the matching URLs, as the table under [Consent at registration](#consent-at-registration) sets out. **Done when:** the public event page shows your rules text under the form, and both checkboxes appear if you expect them. From the event sidebar, **Save as Template**. This is the only way to reuse the form you just built, because event custom fields cannot be copied from one event to another by hand. **Done when:** the camp appears in your [event templates](/docs/platform/events/event-templates) list, and next year's camp is created from it rather than rebuilt. Event custom fields belong to that one event. They are not your organization-wide [custom fields](/docs/platform/users/custom-fields), they do not appear on any other event, and there is no way to copy them across. That is why the template step is not optional: build the camp once with its full form, save it as an [event template](/docs/platform/events/event-templates), and create every future camp from that template. ### Where camp data actually lives, and who can read it Custom field answers are stored per registration, on that attendee's record for that event. The same person answering differently at two camps keeps two answers, which is what you want for medical information that changes. You read them in two places: the **Columns** menu on the **Participants** screen adds one column per custom field, and **Export** downloads a CSV that needs `EVENT_TENANT`, `EVENT_LOCAL` on the event, or event ownership. Event registration custom fields have no visibility control and no encryption option. The builder only asks for a type and its options, so every answer is readable by everyone who can open the event's Participants screen: the event owner, `EVENT_LOCAL` or `ADMIN_LOCAL` on the group, `EVENT_TENANT`, `ADMIN_TENANT`, and admins of a private group running its own event. If a medical detail should be tighter than that, keep it on the member's profile as an organization [custom field](/docs/platform/users/custom-fields) with **Admin** visibility, which is enforced on the server for reading and writing, and can be encrypted at rest when it is a text, number or date field. Then the camp form only asks "anything changed since last year?". ### Consent at registration Three separate things, and only the last one is a real signature: | What | Where it comes from | | ------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | | The GDPR checkbox on the registration form | Appears automatically when your organization has a GDPR policy URL in [Organisation Info](/docs/platform/organisation/organisation-info) | | The terms checkbox | Appears when your organization has a terms URL there | | Camp rules, refund and cancellation wording | **Custom text at bottom of registration form**, on the form's Settings tab | | A signed parental consent form | An [e-document](/docs/platform/contracts) template, assigned to the parent, signed on screen, rendered as a dated PDF | ### On the day Every confirmed registration carries a QR code, delivered in the confirmation email as a PDF ticket, shown on the event page and in the event app. Scanning it sets the attendee's RSVP to **Attended**, which is the same thing an attendance figure counts. Scanning twice is harmless. Sort the scanning permission out before the doors open. Scanning with a plain phone camera needs `HR_TENANT` or `EVENT_TENANT`. `EVENT_LOCAL` is **not** enough on that route: a section leader with local events permission gets an access error even though the ticket is valid. They can scan from inside the Orgo mobile app, where `EVENT_LOCAL` on the event's group is accepted, or you give door staff `EVENT_TENANT` for the weekend. Two more camp-day realities. Check-in is online only, so at a site with no signal you fall back to a printed participant export and record the RSVPs afterwards. And walk-ins must exist on the participant list before they can be marked present: add them with **Invite**, then set them to **Attended**. Detail: [Registration forms](/docs/platform/events/registration-forms), [Attendance](/docs/platform/events/attendance), [QR check-in](/docs/platform/events/check-in), [Ticketing](/docs/platform/events/ticketing). *** ## Setup checklist One line per step in [Setup order](#setup-order), written as the outcome rather than the click. Work down it with Orgo open, and treat anything you cannot tick as unfinished. * [ ] **Modules on.** Every module in the table above is in the position you chose, **Groups & Teams** shows a **Unit Types** tab, and **Enable Local Centers Module** is confirmed on rather than newly switched on. * [ ] **Languages then vocabulary.** Every language you run in is enabled, and no Custom Expression cell in the Texts table is empty in any of them. * [ ] **Emails checked after relabelling.** You have opened your system email templates and fixed the wording that Texts does not reach. * [ ] **Unit types defined top down.** Each type below the top one names its parent, and every type that belongs to a group has **Within local center** ticked. * [ ] **One user type per age level.** Each appears in the Roles list with a **User type** tag, and each that needs its own joining page has a working **URL Slug**. * [ ] **One role per post.** Each carries the right level and the permissions it needs, and no permission is sitting on a user type. * [ ] **Chapters created.** One per group, each under the right parent, each with the currency you will collect subs in. That currency cannot be changed later. * [ ] **Units created inside them.** Sections first, patrols nested under their section, nothing stranded at the top level. * [ ] **Custom fields in place with visibility decided.** For every field you can say who reads it and which form collects it, and nothing above **Public** is being asked for at public sign-up. * [ ] **Birthday required at registration.** A test registration produces an account with a date of birth on it. * [ ] **Fees priced per age level.** One price per level, assigned per member, not an age range on a single price. * [ ] **Consent and conduct documents built.** Parental consent, the volunteer agreement and the code of conduct exist as e-document templates, with **Mandatory document** on where the person must be held until they sign. * [ ] **Safeguarding records have a home.** A date field for each check that expires, a file field or Identity Validation for the evidence, and a named person with a calendar reminder to run the export, because nothing in Orgo watches those dates. * [ ] **Members imported and spot-checked.** Counts match, sampled members sit in the right chapter and unit, badge categories and badges were imported before assignments. * [ ] **Camp form saved as a template.** The full camp registration form, with its medical and dietary custom fields, exists as an event template so you never rebuild it. * [ ] **Door staff can scan.** Whoever is on the gate either holds `EVENT_TENANT` or is scanning from inside the Orgo mobile app. *** ## Limits worth knowing before you start Everything here is current behaviour, verified in the product. None of it is a reason not to use Orgo, but each one costs you a workaround if you find it late. | Limit | What it means for you | | ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Texts does not reach emails or PDFs** | Your relabelled vocabulary stops at the browser. Edit the email templates separately | | **Role group age options start at 16** | The **Min age** and **Max age** selectors on a role group run from 16 to 120, so you cannot build an automatic group of 8 to 10 year olds. Model youth sections with units and user types instead, and keep role groups for adults | | **Age-conditioned prices are not a range** | A fee price has **Age under** and **Age over**. Set both and the rule is OR, not AND: the member qualifies if they are under the first value **or** over the second. One price cannot express "ages 10 to 14". Use one price per age level and assign it per member | | **No date of birth means no age check** | A member with no birthday passes every age restriction on a price and never matches an age-based role group. Make **Birthday** required at registration | | **No family or sibling pricing** | Fees are resolved per member. There is no family tier and no discount for a second child. Companies are the only "one payer, many people" mechanism | | **Parental consent is stored but never shown** | The date and method are recorded when a parent registers a child, and there is no screen or report for it. Use a signed e-document if you need to produce evidence | | **Minimum Registration Age applies to one path only** | It is read when a parent registers a child from the Family tab, where it flags the waitlist entry as underage. Public self-registration ignores it | | **Children Auth Restriction Age restricts nothing** | It only triggers a notification when a member reaches that age | | **Identity Validation is not a background check** | It reads and stores an ID document. It does not vet anyone, and outside Romania approving one only requires a first and last name | | **Nothing watches a date field** | No expiry engine for check renewals, first aid certificates or anything else you store as a **Date** custom field | | **Badges have no expiry** | A badge records that something happened, not that it is still valid | | **Deleting a badge deletes its awards** | And deleting a badge category deletes its badges and their awards | | **Event custom fields do not travel** | They belong to one event. Use an event template | | **Event custom field answers are not restricted** | No visibility level, no encryption. Anyone who can open Participants reads them | | **Bulk invite does not send email** | **Send Invites to All Members** fills the participant list only. Announce the camp with a newsletter as well | | **`EVENT_LOCAL` cannot scan with a phone camera** | Only inside the mobile app. Otherwise give door staff `EVENT_TENANT` | | **Volunteer and parent user types are hidden at `/register`** | Use a `/join/` link for those types, or assign the type after they join | | **A chapter currency is set once** | It can never be changed afterwards, because past payments and the connected Stripe account are bound to it | *** ## Troubleshooting Because text replacements are applied in the browser and emails are rendered on the server. There is no setting that changes this. Edit the wording in [Email templates](/docs/platform/emails/email-templates), and remember that generated PDFs (invoices, adhesions, signed documents) are in the same position. You cannot, with role groups: the **Min age** and **Max age** selectors only offer 16 upwards. That is a deliberate consequence of role groups being built for adult segmentation. Model youth age bands with structure instead. Create a unit type called Section, one unit per age band inside each chapter, and a user type per age band. The unit gives you a real membership list with its own leaders; the user type gives you the filter, the fee price and the per-type registration form. Moving a child up an age band is then two edits, on their unit membership and their user type, both of which an `HR_LOCAL` administrator can do. One fee price per age level, assigned per member. Create the membership fee product, add a price per level, and set each member's level on their profile or from **Finance** → **Local members fees**, where the fee column is a per-member dropdown recorded against a fee year. Do not try to do it with **Enable Age Restrictions on Prices** alone. That feature adds **Age under** and **Age over** to a price, and when both are filled in the member qualifies if they are under the first value **or** over the second, which is the opposite of a band. It works for "under 18 pays less" and "over 65 pays less"; it cannot express "10 to 14". A member with no date of birth also passes the check entirely. Almost always the missing email. A child registered without one gets a generated placeholder address that cannot receive mail and cannot be used to sign in, which is the intended behaviour when you want a record rather than a login. If the child should have a login, add a real email to their account. If they should not, nothing is broken: the parent manages them from the Family tab and the child appears in lists, units and event registrations normally. Two other reasons a child account looks stuck: the [waitlist](/docs/platform/users/waitlist) is active for that chapter, in which case the child is parked there rather than joined, and the "In waitlist, underage" tag appears when the child is below **Minimum Registration Age**. Permission, not the ticket. Scanning through a phone camera opens a page that requires `HR_TENANT` or `EVENT_TENANT`, and `EVENT_LOCAL` does not satisfy it, so the person who organized the event may still be refused at the door. Two fixes: have them scan from inside the Orgo mobile app, where `EVENT_LOCAL` on the event's group is accepted, or grant `EVENT_TENANT` to the people on the gate. Marking somebody present without scanning is wider than both: the event owner, `EVENT_LOCAL` on the group, `HR_TENANT` and group admins can all set an RSVP to **Attended** from the participant list. Nowhere in the interface. Consent is captured when a parent registers a child through the Family tab, as a date and a method stored against the account and the family membership, but no screen displays it and there is no consent report. If you have to be able to produce consent on demand, do not rely on it. Build an [e-document](/docs/platform/contracts) template for parental consent, mark it **Mandatory document** so the parent is held in onboarding until it is signed, and you get a dated PDF with the signature on it and a filterable list of who has signed. Check the custom field's visibility. Anything above **Public** is discarded on the public registration pages, because the write check asks who is signed in and at registration nobody is. There is no error: the applicant fills the box, the account is created, and the answer is simply not there. This bites youth organizations particularly hard, because medical and dietary questions are exactly the ones you would instinctively mark **User** or **Admin**. Two options: collect the field as **Public** at sign-up and control profile visibility separately with [Privacy settings](/docs/platform/users/privacy-settings), or ask the question after joining on the [profile form](/docs/platform/users/profile-fields), where the member is signed in and **User** visibility works as documented. Look at where the permission was granted. A permission attached to a **role** ends when you end the role assignment, which is the whole reason to put permissions on roles. A permission ticked directly on the member's profile does not: it survives a chapter change, and it is now pointing at their new chapter. Check three places on the profile: the permissions panel itself, any **Multi local center access** grants (which stay stored even when the setting is switched off, and come back exactly as they were if it is switched on again), and `_PARENT_LOCAL` permissions, whose reach is recomputed from the member's new primary chapter. That last one is the surprising case: a district-level permission follows the person to their new district rather than staying with the old one. Nothing prevents that, and it is the most common self-inflicted wound of a relabelling pass. Chapters, units, private groups and role groups are four distinct things that a scouting association is tempted to call by two or three names between them. Pick one word per concept before you open the Texts screen and write it down: for example District for parent chapters, Group for chapters, Section and Patrol for your two unit types, and Team for private groups. Then replace only the phrases that match your list. Remember a replacement changes that exact phrase everywhere, including inside sentences that merely use the word. Move carefully. Deleting a badge deletes every award of it from every member, and deleting a category deletes the badges filed under it along with their awards. Nothing warns you afterwards, and nothing is recoverable from the interface. To restructure without losing history, rename badges and reassign them to different categories rather than deleting and recreating. Courses and events that pointed at a badge you delete simply lose the link, so check those too. *** ## Related * [Texts](/docs/platform/customization/labels) - replacing Orgo's vocabulary with your own * [Units](/docs/platform/groups/units) - sections and patrols inside a group * [Family Members](/docs/platform/users/family-members) - parents, guardians and child accounts * [Badges](/docs/platform/badges) - the award scheme and how badges are given * [Registration forms](/docs/platform/events/registration-forms) - what a camp asks at sign-up * [Identity Validation](/docs/platform/identity-validation) - what an ID check does and does not prove # Usage & Billing Source: https://orgo.space/docs/platform/usage-billing What your organization consumes against its plan, and the subscription, cards and invoices for Orgo itself This is what your organization pays **Orgo**: five meters showing what you consume against your plan limits, the invoices Orgo issues you, and the controls for your plan, cards and billing address. **Built for** the administrator who owns the account and has to answer "are we about to outgrow our plan" and "where is last quarter's invoice". **Replaces** emailing Orgo to ask. This is billing for Orgo itself, not for your members. Membership fees, member invoices and member payments live under [Membership Fees](/docs/platform/fees/fees) and [Stripe Integration](/docs/platform/fees/stripe-integration), and are unrelated to anything on this page. *** ## Where it lives | Screen | Path | Permission | | --------------------------------------------- | --------------- | --------------------------------------------------------------------- | | **Settings → Organization → Usage & Billing** | `/tenant/usage` | `ADMIN_TENANT` | | Subscription, cards and billing address | `/billing` | `FINANCIAL_TENANT` to open the route, `ADMIN_TENANT` to load anything | **Usage & Billing** is the everyday screen, and its sidebar entry only appears for `ADMIN_TENANT`. The subscription screen has no sidebar entry at all: you reach it from the warning link in the top bar when something needs attention (payment details missing, trial ending, trial expired, subscription cancelled, payment failed). That link is also admin-only. The `/billing` route admits `FINANCIAL_TENANT`, but every piece of data behind it requires `ADMIN_TENANT`. A finance-only user opens the page and sees nothing at all. Resource usage cards for users, storage, emails, contacts and API requests, each with a progress bar and a percentage *** ## The five meters | Meter | What it counts | | ------------------------------- | ---------------------------------------------------------------------------------------------- | | **Users** | Active members aged 18 or over, plus active members with no date of birth on file | | **Storage** | Total size of all files uploaded in your organization, in GB | | **Emails** (last 30 days) | Newsletter emails plus notification and system emails sent in the last 30 days | | **Contacts** | Contacts, plus every member who is not an active adult: inactive accounts and members under 18 | | **API Requests** (last 30 days) | Requests made with your API tokens in the last 30 days | Two of these are worth reading twice. **A member under 18 counts as a contact, not a user.** So does a member whose status is anything other than active. If your Users meter looks lower than your member directory, that is why. **A member with no date of birth counts as an adult.** An incomplete profile lands in the Users bucket, not the cheaper one. Deleted accounts are counted nowhere. ### Bars, percentages and "Unlimited" A meter with a real limit shows a bar and a percentage. The bar turns amber at 75% and red at 90%. A meter whose limit is set to unlimited shows the current figure followed by **Unlimited** and no bar at all. The limits themselves are part of your plan. They are set by Orgo and cannot be edited from this page; the meters are read-only. ### How fresh the numbers are Storage is measured on request. Users and Contacts come from a count that is cached for 15 minutes, so a member added a moment ago can take that long to show up. The email figure is assembled from a nightly aggregation (04:00 UTC) for completed days, with today's sending added live on top, so today's emails do appear. API requests are counted from durable per-token daily totals. On top of all that, the whole page caches for 5 minutes, so a change you make now shows up on the next refresh after that window. *** ## Invoices from Orgo Below the meters is your billing history with Orgo, read straight from the payment provider. * **Upcoming invoice**: the amount you will next be charged and the date of the attempt. It is a preview, so it has no number and no PDF yet. * **Past invoices**: date, amount, status, and a **download** link to the PDF. Up to the 100 most recent are listed. Drafts and voided invoices are left out, but a finalized zero-amount invoice, such as the one that opens a trial, is shown because it is a real event in your history. | Status shown | Meaning | | ------------ | ------------------------------------------------------------ | | **paid** | Settled | | **credited** | A paid invoice with a negative total, that is, a credit note | | **Unpaid** | Issued and still open | | **failed** | Anything else, including a failed collection attempt | Until Orgo has issued you an invoice the block is a single empty panel reading "There are no invoices". Organizations on the free plan stay on that state indefinitely, because nothing is ever charged. ### Cancel and reactivate Next to the Invoices heading you will see the state of your subscription and one button. * **Active**: shown while the subscription is active, in trial, or past due. The button reads **Cancel subscription** and asks for confirmation. * **Cancels on ``**: shown once a cancellation is scheduled. The subscription keeps working until that date, and the button becomes **Reactivate subscription**. Cancelling does not cut you off immediately: it schedules the cancellation for the end of the period you have already paid for. Reactivating before that date simply removes the scheduled cancellation. Reactivation is refused while your most recent invoice is unpaid. Settle it first, then reactivate. If there is no subscription yet, or it has already ended rather than being scheduled to end, no state tag and no button appear. *** ## The subscription screen `/billing` is the larger screen behind the top-bar warning. It shows your plan next to current consumption (users, storage, emails), the monthly total, and any coupon line. Prices are billed in USD, or in RON when your billing country is Romania. | State | What you see | | ------------------------- | ---------------------------------------------------------------------------------- | | **Free plan** | "You are on the free plan", with no card, address or invoice sections | | **Free trial** | The trial end date, with a prompt to add a card and billing address before it ends | | **Active** | The day of the month you are billed on | | **Trial expired** | A prompt to complete card and billing address to activate | | **Cancels at period end** | A tag with the date access ends | | **Cancelled** | A notice plus an **Activate subscription** button | Two arrangements have no self-service controls at all. **Manual** and **custom** subscriptions show their agreed monthly total and a note asking you to email `contact@orgo.space` instead of a change button. ### Changing your plan On the free plan the button reads **Upgrade subscription**. Each option shows its monthly price in your billing currency. A second selector offers storage add-ons larger than the amount already included in the chosen plan. Enter the code and click **Apply**. Invalid codes are rejected straight away; valid ones show the percentage off and the discounted total. The new total takes effect on your subscription. If a payment has failed, saving a plan change reopens the failed-payment dialog instead. Settle the outstanding invoice before changing plans; the change is refused server-side too while the latest invoice is unpaid. ### Cards and billing address The **Cards** section lists each saved card by brand, last four digits and expiry, flagging expired ones. You can add a card, mark one **primary** (the card Stripe charges), or remove any card that is not primary. Card details go straight from your browser to Stripe; Orgo stores only the reference. **Update billing address** collects organisation name, address, billing email and country. All four are required. The country sets your billing currency, and these details are pushed to Stripe so they appear on the invoices Orgo issues you. Once a subscription exists the country can no longer be switched to Romania; that choice has to be made before the subscription is created. Saving a card and a billing address is also what starts a subscription: as soon as the profile has a country and a default card and no subscription yet, Orgo creates one. Adding a card while a payment is outstanding makes it the default and retries the open invoice immediately. ### Paying a failed invoice A failed payment opens a dialog on this screen with a **Pay now** button, which charges the primary card for the most recent invoice. If your bank asks for 3D Secure, the confirmation appears in place and the page refreshes once the payment succeeds. Once the invoice clears, the top-bar warning disappears on the next page load without waiting for Stripe. *** ## When billing blocks access If your organization is on a paid plan with no Stripe subscription, and is not on a manual arrangement, Orgo restricts access until that is resolved: * **Tenant admins** land on the subscription screen, where the plan, card and billing address can be completed. * **Everyone else** sees a short notice saying access is restricted because of incomplete billing details or unpaid invoices, and telling them to contact their administrator. *** ## Troubleshooting Expected. Users counts active members aged 18 and over. Members under 18 and members whose status is not active are counted under Contacts instead. Deleted accounts are counted nowhere. A member added in the last few minutes may also not be in the count yet. The page caches for 5 minutes. Reload after that. Storage is the total size of the files held in your organization, so files still sitting in a drive folder or attached to an old event continue to count. Today's sending is added live on top of the nightly aggregation, but the 5-minute page cache still applies, so a send from the last few minutes may not be reflected yet. An unlimited meter is a deliberate setting on your plan rather than a missing value. If it looks wrong for your agreement, raise it with Orgo; it cannot be changed from this page. Two conditions refuse it: the latest invoice is not paid, or the subscription has been marked inactive rather than scheduled to cancel. Settle the outstanding invoice first; if the state does not change after that, contact Orgo. The list shows the 100 most recent finalized invoices and excludes drafts and voided ones. For anything older, contact Orgo. The subscription data requires `ADMIN_TENANT`. `FINANCIAL_TENANT` is enough to open the route but not to load anything on it. The organization is on a paid plan with no active subscription. An admin needs to open the subscription screen from the top-bar link, add a card and a billing address, and activate. The most recent invoice is unpaid. Use **Pay now** in the dialog, or add a card, which retries the open invoice with it. Manual and custom subscriptions are managed by Orgo. Email `contact@orgo.space`. *** ## Related * [Organization info](/docs/platform/organisation/organisation-info) * [Modules](/docs/platform/organisation/modules) * [Membership fees](/docs/platform/fees/fees) * [Stripe Integration](/docs/platform/fees/stripe-integration) * [API tokens and rate limits](/docs/platform/api) # Adding Members Source: https://orgo.space/docs/platform/users/adding-members Add a user, invite someone, register a member or create an account: the four ways people get into your organisation, and which one to use There are four ways a person ends up with an account in your organisation. If you have one person's details in front of you and want them in the platform now, that is **Register member** in the member directory, the first route below. *** ## Which route to use | If you want to | Use | Where it starts | | ----------------------------------------------------------------------------------------------- | --------------------- | ------------------------------------------------------------------------------- | | Create the account yourself, for one person whose details you already have | **Register member** | **Members** in the sidebar → **Register member** | | Send someone a link and let them fill in their own details, with credit to whoever brought them | **Invite** | **Members** → **Invite a friend**, or the **Referrals** tab on your own profile | | Let anyone sign themselves up, from your website or a public link | **Self-registration** | The registration form at `/register` | | Load a spreadsheet of people you already have | **Import** | **Settings** → **Customization** → **Import** | Adding a person to a member company is a separate job with its own section [further down](#adding-a-person-to-a-member-company). It attaches someone to a company that already holds the membership, and it is not a general way of adding members. *** ## 1. Register member, from the member directory Member directory with the Register member and Invite a friend buttons above the filter bar, the filter row, and the member table **Members** in the sidebar, then **Register member**, the first button above the filters. On a phone it is the person-plus icon in the header instead of a labelled button. **Who can.** `HR_TENANT` on the organisation-wide list. `HR_LOCAL` only on their own chapter's list, so a chapter secretary has to pick their chapter in the **Chapter** filter before the button appears. An administrator without `HR_TENANT` and without a chapter on their own account is refused on save with "You cannot create user without a local center". **What you fill in.** First and last name, email, chapter, user type, phone, birthday, gender, town of residence and town born, address and postal code, plus two collapsible blocks: **Permissions** (`HR_LOCAL` and above, and you can only grant what you hold yourself) and **Roles**. If the Companies module is on and you may assign a company, a company and company role appear too. **What the person receives.** The email address is labelled optional and it is what decides whether this is an account or only a record. With one, Orgo sends the **Account created by admin** message naming you and linking to the login page, and they sign in with an email one-time code and set their own password on the way through. Without one, nothing is sent and nobody can sign in as them. **What state the account lands in.** The status comes from **Settings** → **Users & Profiles** → **Configuration** → **Default Status for Admin-Created Users**: Active by default, or Inactive, Unapproved, Waiting List, Suspended or Excluded. That setting always wins, whatever any screen appeared to ask for. Fields you marked **Required** on the [registration form](/docs/platform/users/registration-form) are not asked for here, because nothing created this way passes through that form. If a field must be present on every profile, mark it required on the [profile form](/docs/platform/users/profile-fields) instead, which is re-checked on every visit. **The same route from a contact.** **Create user account** on a [contact](/docs/platform/contacts) record creates a member from that contact's email through exactly this mechanism, welcome message included. It carries the email and the joined date across but not the name, so open the new profile afterwards and fill in the first and last name. *** ## 2. Invite Referrals tab on a member profile with the sent, joined and pending counters, the personal referrer link with copy and share buttons, the invite by email box and the invitation history **Invite a friend**, next to Register member above the directory, opens the **Referrals** tab on your own profile. The button needs **Enable User Invitations** on and you to meet **Who Can Send Invitations**, and it is desktop only: on a phone, open the Referrals tab from your profile. Two mechanisms sit on that tab: * **Invite by email.** Orgo emails each address a registration link tied to that invitation. The box accepts 20 addresses, sends the first 10 of them, and refuses after 50 invitations from one member in an hour, so work in batches of ten. * **Your personal link**, `https:///register/`. Orgo sends nothing; you share it yourself, and whoever registers through it is recorded as referred by you. **What the person receives.** The registration form with their email already filled in and locked to the invited address. **What state the account lands in.** An emailed invitation skips email confirmation entirely: the account is created **Active** with the address already confirmed, and the person is signed in and taken to the dashboard. If a chapter administrator sent it from their chapter context, the invitation carries that chapter and accepting places them in it. Invitation links keep working while **Enable Registration Form** is off, which is how you close the door to the public and still admit the people you name. Full detail, including the tracking counters: [Member Invitations](/docs/platform/users/invitations). *** ## 3. Self-registration The public form at `/register`, plus one form per [user type](/docs/platform/users/user-types) at `/join/`, both embeddable in your own site as an iframe. It is live while **Enable Registration Form** is on, and you decide what it asks in **Settings** → **Users & Profiles** → **Registration Form**. **What the person receives.** No password is asked for. Orgo generates one, emails a six digit code valid for five minutes, and requires them to set their own password at first login. **What state the account lands in.** Unconfirmed email until they enter the code. On verification the status resolves in this order: eligible for the [waitlist](/docs/platform/users/waitlist) becomes **Waiting list**; a [referral program](/docs/platform/users/referral) requiring referrals becomes **Awaiting referral**; **Manual Approval** on becomes **Unapproved**; otherwise **Active**, and the welcome message goes out if **Send Welcome Message** is on. Full detail: [Registration Form](/docs/platform/users/registration-form). *** ## 4. Import **Settings** → **Customization** → **Import**, the **Users** step. Requires `ADMIN_TENANT`. Upload a CSV of up to 50 MB, watch the per-row progress, read the per-row errors, and undo the whole thing once with **Rollback**. Only `user_legacy_id` is required; every unrecognised column becomes a profile custom field. The create step skips people who already exist, so use **Modify Users** to change them instead. **What the person receives.** Nothing. Import sends no email at all, so tell people yourself that their account exists. **What state the account lands in.** Active, unless your file carries a `status` column. The password the import writes is a placeholder nobody knows, so an imported member signs in with the email one-time code from the login page, or with a password reset. Two kinds of row cannot sign in at all: rows whose email already belongs to somebody else, and rows with no email, both of which get a generated placeholder address that cannot receive mail. Full detail, including the other seventeen import types and the ordering between them: [Data Import](/docs/platform/customization/import). *** ## Joining can be gated Three modules change what happens to a person arriving through the invite or self-registration routes. None of them is a way of adding somebody, and none of them appears in the table above for that reason. | Module | What it changes | | ------------------------------------ | --------------------------------------------------------------------------------------------------------- | | **Manual Approval** | New registrations land as Unapproved and wait for an admin. See [User Statuses](/docs/platform/users/statuses) | | [Waitlist](/docs/platform/users/waitlist) | Registrations naming a chapter are queued with a position instead of admitted | | [Adhesion](/docs/platform/users/adhesion) | A formal application, with an ID check and a signature, after the account exists | Register member and Import set the status directly and never enter the waitlist queue or the Manual Approval review. **Mandatory Adhesion** is the exception: it opens an application on every new account however it was created. *** ## Adding a person to a member company This is a different job. It attaches an individual to a [company](/docs/platform/users/companies) that already holds the membership, so it only applies to organisations that sell corporate or team memberships and only once the company record exists. If the person is not joining through a member company, use **Register member** above. On the company page, the **Team Members** panel offers two buttons: * **Invite** emails a company invitation naming the company and the role offered. It expires after 30 days, and accepting creates the person's account if they do not have one and emails them a one-time login code. * **Add Member** (`ADMIN_TENANT`) attaches somebody who is already in your database, whether a member or a contact. Both consume one of the company's seats, and a person can belong to only one company. Members added this way inherit the company's membership validity instead of paying an individual fee. Everything else about companies, including seats, fees and renewal reminders: [Companies](/docs/platform/users/companies). *** ## At a glance | Route | Who can use it | What the person receives | Status it starts in | | --------------------- | ----------------------------------------------- | ------------------------------------------------------------------------------ | ------------------------------------------------------ | | **Register member** | `HR_TENANT`, or `HR_LOCAL` on their own chapter | Account created by admin email with a login link, if you gave an email address | **Default Status for Admin-Created Users** | | **Invite** | Whoever **Who Can Send Invitations** names | An invitation email with a registration link, or a link you share yourself | Active, email already confirmed | | **Self-registration** | Anybody, while the form is on | A six digit confirmation code | Unconfirmed email, then whatever your gates resolve to | | **Import** | `ADMIN_TENANT` | Nothing | Active, unless the file says otherwise | *** ## Troubleshooting Two gates. On the organisation-wide list it needs `HR_TENANT`. On a chapter's list it needs `HR_TENANT`, or `HR_LOCAL` on that exact chapter, which means a chapter secretary has to select their own chapter in the **Chapter** filter first: they never see the button on the organisation-wide list. `ADMIN_LOCAL` on its own is not enough. Check the email address first. It is optional on the create form, and without one nothing is sent and there is nothing for the person to sign in with. Then check that **User Created by Admin** is still switched on under **Settings** → **Emails & Notifications** → **System Emails**, and look the address up in the email log. The member's own profile has a **Logs** tab with an **Email Logs** sub-tab that shows exactly what was sent to them. Their status is not Active. Everyone you create by hand or by import gets the status you configured, not the one the screen implied, so check **Default Status for Admin-Created Users**: Inactive, Unapproved, Waiting List, Suspended and Excluded all block sign-in. Setting that default to Waiting List is the least obvious trap, because it blocks the account without creating any waitlist entry for staff to approve. The full elimination sequence is in [Troubleshooting member access](/docs/platform/users/troubleshooting-access). Register member, Import, and invitations. A valid invitation link opens the form even while **Enable Registration Form** is off, which is the supported way to run an invitation-only organisation. Only public self-registration is refused, and it is refused on submit rather than on load, so `/join/` pages keep rendering. See [Registration Form](/docs/platform/users/registration-form). Only self-registration and invitation links go through the registration form, so only those collect its required fields. Register member, Import and a parent registering a child all bypass it. Put anything genuinely mandatory on the [profile form](/docs/platform/users/profile-fields) instead. Invite by email is the only bulk route that does not involve a CSV, and it sends ten addresses per batch. For anything larger, build the CSV and use [Import](/docs/platform/customization/import): it validates the headers before writing anything and it can be rolled back once. *** ## Related * [Users & Profiles](/docs/platform/users) - the member directory these routes feed * [Member Invitations](/docs/platform/users/invitations) - the invite route in full * [Registration Form](/docs/platform/users/registration-form) - what self-registration asks * [Data Import](/docs/platform/customization/import) - the CSV route in full * [Companies](/docs/platform/users/companies) - adding a person to a member company * [Family Members](/docs/platform/users/family-members) - a parent registering a child * [User Statuses](/docs/platform/users/statuses) - what each starting status blocks * [Permissions](/docs/platform/permissions) - `HR_TENANT`, `HR_LOCAL` and the rest # Adhesion (Membership Applications) Source: https://orgo.space/docs/platform/users/adhesion Require a formal application, an ID check, a signature and admin review before granting full membership Adhesion is Orgo's membership application module. An applicant fills a form you define, optionally uploads an identity document and records a short video, signs the application in the browser, and sends it to your team. Staff then move it through a review chain and either approve or reject it. **Built for:** organisations that vet people before admitting them, such as professional associations, political parties, trade unions and cooperatives, and anyone who needs a signed, auditable record of who was admitted and by whom. **Replaces:** a PDF application form plus email review, plus a separate place to store the signed copy. **When you do not need it:** if you only want a light approval gate, set new registrations to a pending [status](/docs/platform/users/statuses) instead. Adhesion is heavier: it adds an ID check, a signature and a multi-step review. *** ## Turning it on **Settings** → **Users & Profiles** → **Configuration** → **Adhesion & Membership**. Requires `ADMIN_TENANT`. Adhesion and Membership settings section with the Enable Adhesion Module, Mandatory Adhesion, Video recording, Review steps and Require identity verification switches | Setting | What it does | Default | | ------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | | **Enable Adhesion Module** | Turns the module on. Until it is on, the Adhesions menu item and the member's own application page are hidden. | Off | | **Mandatory Adhesion** | Every new account gets an application in Initiated status the moment it is created, and the member is redirected to it on every page until the application succeeds. | Off | | **Video recording** | Adds a video step after sending, where the applicant answers questions on camera. | Off | | **Review steps** | Runs applications through form validation, background check and interview before the decision. Turn it off to decide straight from a sent application. | On | | **Require identity verification** | Requires an ID document upload, and blocks the "form validated" step until that document is validated. | On | | **Default User Type After Approval** | The [user type](/docs/platform/users/user-types) assigned when an application is approved. | None | | **Admin Email Address** | Extra address notified when an applicant sends an application. The local HR team is always notified as well. | None | | **Draft Change Reasons** | The pick list an admin chooses from when sending an application back. Entries are separated by a pipe character, not by commas. | None | With **Mandatory Adhesion** on, members are redirected to their application on every route until it reaches Adhesion success. Members holding `ADMIN_LOCAL` or above, and members who already hold the configured success user type, are exempt. Keep your review turnaround short. *** ## Building the form **Settings** → **Users & Profiles** → **Adhesion Form** (`ADMIN_TENANT`). Each row has two checkboxes, include the field and make it required. Email is always included, always required, and cannot be unchecked. Adhesion form builder listing built-in profile fields with an include checkbox and a required checkbox on each row The selectable built-in fields are: first name, last name, date of birth, gender, address street, address details, town born, town current, location on members map, chapter, user types, profession headline, profession job, profession expertise, profession sector, profession industry, phone number, ID serial and number, Facebook, Twitter, LinkedIn, Instagram, Telegram and TikTok profiles, personal number, education status, certifications, experience history, and fee level. Every [custom field](/docs/platform/users/custom-fields) you have defined is listed underneath and can be added the same way. Personal number, ID serial and number, and date of birth are only shown to people allowed to see private data. **Fee level** lets the applicant choose which [membership fee price](/docs/platform/fees/fees) applies to them; that choice is written to their profile and printed on the generated document. The **Iframe URL** button copies an embeddable link to the application page for your tenant. The applicant still has to be signed in, so this is a convenience for your own site, not an anonymous public form. *** ## What the applicant does The member opens **My Adhesion** from their profile menu (`/adhesion`), or lands on it automatically when adhesion is mandatory. Staff with `HR_LOCAL` over the member's chapter can fill it in on their behalf from the member's profile, which opens the same page for that member. `/adeziune` still resolves to it as well. Member adhesion page on a phone, headed with the organization name and the applicant's name, showing the first step Upload identity scan image with a Front document drop area accepting JPG or PNG up to 10 MB, a note that the document is stored securely for identity verification, and a Continue button Creates the application in **Initiated** status. Everything after this point is editable only while it stays in Initiated. Shown only when **Require identity verification** is on. The front of the document is required; a back side can be added with the "Document has information on the backside" switch. Orgo runs OCR on the upload to pre-fill identity fields; if OCR fails the upload still succeeds and the applicant types the details manually. The fields you selected in the form builder. Required custom fields must all have a value before the next step unlocks. The applicant can download the unsigned document first, then signs on a canvas. Signing generates the PDF from your template with the signature embedded and stores it as the application's signed document. Staff filling the form on someone else's behalf get no canvas: they upload the signed file instead, up to 5 files. Moves the application to **pending**. Blocked until a signed document exists and, when identity verification is on, until an ID document has been uploaded. When the member sends it themselves, Orgo emails the configured admin address plus every HR member of their chapter. Only when **Video recording** is on. The recorder walks the applicant through a set of questions with a 5 minute total limit, and can be re-recorded while the application is Initiated or pending. *** ## Reviewing applications **Management** → **Adhesions** in the sidebar, or `/adhesions`. Requires `HR_LOCAL`. Adhesions queue with status filter chips and counts, and per-row signed document download, video, identity state and status controls Status chips with live counts sit above a table of the applicant, age, chapter, sent and updated dates, the signed document and video downloads, the identity state, and a status dropdown. Filter by name, by user ID, and, with `HR_PARENT_LOCAL` or above, by chapter. `HR_TENANT` sees the whole tenant; everyone else is restricted to chapters they hold `HR_LOCAL` on. Applications marked Duplicated, and applications belonging to deleted members, never appear. | Status shown | Meaning | | --------------------------- | ------------------------------------------------- | | **Initiated** | Draft. The applicant can still edit everything. | | **pending** | Sent for review. | | **Adhesion form validated** | An admin checked the submitted form. | | **Background checked** | Background check recorded. | | **Interviewed** | Interview recorded. | | **Adhesion success** | Approved. | | **Adhesion rejected** | Refused. | | **Adhesion canceled** | Withdrawn or dropped, with a reason. | | **Duplicated** | Marked as a duplicate and removed from the queue. | With **Review steps** on, the queue offers the full chain: pending, validated, background checked, interviewed, then the decision. With it off, the review statuses are hidden and an admin goes straight from a sent application to success, rejected or canceled. Gates on each move: * **Adhesion form validated** requires a validated identity document, unless identity verification is off for the tenant. * **Adhesion success** and **Adhesion rejected** require both the Interview conclusion and the Background conclusion, whenever Review steps is on. * **Adhesion canceled** requires a cancel reason. * Moving back to **Initiated** opens the Draft Change Reasons picker, deletes the signed document so it has to be signed again, and emails the applicant with the reasons you selected. Every status change asks for confirmation and is written to the application log. Approving flags the member as a full member, assigns the **Default User Type After Approval** (creating the underlying role assignment if the member did not have it), and stamps the date they became a full member. If their user type actually changed as a result, they get the approval email. Approval does not change the member's account status. A member whose account is Inactive or Unapproved stays that way after approval; change the [status](/docs/platform/users/statuses) separately. ### Conclusions and the audit log The **Conclusions** and **Log** buttons on each row open the same screen, also at `/adhesion/{id}/log` with `HR_LOCAL`. **Conclusions** holds three free-text notes: Interview conclusion, Background conclusion, and Adhesion cancel reason. They can be saved while the application sits at validated, background checked, interviewed or canceled. They are read-only once it reaches Adhesion success or Adhesion rejected, and cannot be saved at all while it is still Initiated, pending, Duplicated or a decision has been made. **Log** shows who sent, validated, interviewed, decided on and last updated the application, each with a timestamp and a link to the person, followed by the system log entries with the raw field-level changes. *** ## The generated document **Settings** → **Users & Profiles** → **Adhesion Template** (`ADMIN_TENANT`). The editor is three raw HTML areas (Header, Main Template, Footer), not a rich text editor. Leave one empty and Orgo falls back to its built-in default for that part. **Preview** renders your markup in a modal. Adhesion template editor with Header, Main Template and Footer HTML code areas and a Preview button These placeholders are replaced when the PDF is generated: | Group | Placeholders | | --------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Identity | `{{firstName}}`, `{{lastName}}`, `{{personalNumber}}`, `{{dateBirth}}`, `{{gender}}`, `{{idSerialNumber}}`, `{{address}}`, `{{idTown}}`, `{{idCounty}}`, `{{country}}` | | Contact | `{{email}}`, `{{phoneNumber}}`, `{{facebook}}`, `{{linkedin}}`, `{{instagram}}`, `{{tiktok}}` | | Organisation | `{{localCenterName}}`, `{{localCenterAddress}}`, `{{feePrice}}` | | Professional | `{{professionIndustry}}`, `{{professionJob}}`, `{{professionExpertise}}`, `{{professionSector}}`, `{{hasExperienceHistory}}`, `{{experiences}}` | | Education | `{{educationStatus}}`, `{{educationDegree}}`, `{{certifications}}` | | Signature block | `{{signature}}`, `{{dateSignature}}` | For a custom field, use `{custom_field_}` with the field's numeric id (single braces). File-type custom fields render as a download link; yes/no fields render the labels you configured. `{{educationDegree}}`, `{{certifications}}` and `{{experiences}}` expand to HTML tables, so put them on their own line rather than inside a sentence. *** ## Emails Five emails belong to this flow. All are switched off together by the **Adhesion Notifications** toggle under **Settings** → **Emails** → **System Emails** → **Adhesion / Applications**, and each can be rewritten from the [email templates](/docs/platform/emails) screen. A rewritten template has no language of its own: it reaches every applicant as written, whatever language they read the platform in. | Email | Sent to | Trigger | | --------------------------- | ---------------------------------------------- | ------------------------------------------------------------- | | `adhesion_pending_admin` | Admin Email Address plus the chapter's HR team | Applicant sends their application | | `adhesion_draft` | Applicant | Application sent back to Initiated, with the selected reasons | | `adhesion_validated_member` | Applicant | Application moved to Adhesion form validated | | `adhesion_rejected` | Applicant | Application rejected | | `adhesion_success` | Applicant | Application approved and their user type changed | *** ## Troubleshooting Sending needs a signed document and, when identity verification is on, an uploaded ID. If the form was filled by staff, the signed file has to be uploaded manually. The identity document has to be validated first, with the **Validate** button in the Identity column of the queue. If you do not run identity checks, turn **Require identity verification** off and both the precondition and the upload step disappear. With **Review steps** on, open **Conclusions** on that row, save both the Interview and Background conclusions, then set the status. It only goes out when approval actually changes their user type, so nothing is sent if they already held the type set in **Default User Type After Approval**. Also check that **Adhesion Notifications** is on under System Emails. Set its status back to **Initiated**: this deletes the signed document and reopens every step. Applications that were rejected or marked Duplicated also show a **Reopen** button on the applicant's own page for staff with `HR_LOCAL`. Approving a [resignation](/docs/platform/users/resignation) detaches the application from the member when a guest user type is configured, so their profile no longer points at it. The application row itself is kept as a record. *** ## Related * [Identity Validation](/docs/platform/identity-validation) - the ID document check the validation step depends on * [User Types](/docs/platform/users/user-types) - what gets assigned on approval * [Custom Fields](/docs/platform/users/custom-fields) - adding your own questions to the form * [Registration Form](/docs/platform/users/registration-form) - what people fill in before the application * [User Statuses](/docs/platform/users/statuses) - the account status, which approval does not change # Companies Source: https://orgo.space/docs/platform/users/companies Corporate membership: one company record, a seat allowance, invited employees, and a single fee that covers them all A company is an organization that holds a membership on behalf of its people. It has its own record, its own billing details, a seat allowance, and one membership fee. Everyone inside it inherits the company's membership validity instead of paying individually. **Built for** organizations whose members are businesses rather than individuals, including business networks, chambers of commerce, trade and industry associations, and any body that sells corporate or team memberships. **Replaces** spreadsheets of member companies plus manual invoicing and per-employee fee tracking. This page is about **member companies**, not about adding people to your organization in general. Everything below applies once a company record exists and holds the membership. To create an account for an ordinary member, use **Register member** in the member directory: see [Adding Members](/docs/platform/users/adding-members). Companies list with search, status filters showing counts for All, Active, Pending and Inactive, and rows showing member count and valid-until date *** ## How to enable **Settings** → **Modules** → **Companies** → **Configuration**. Requires `ADMIN_TENANT`. | Setting | What it does | | ---------------------------- | -------------------------------------------------------------------------------------------------------------- | | **Enable Companies Module** | Turns the feature on. Adds **Companies** to the sidebar and a **Company** tab to each member's own profile | | **Who can create companies** | **Any member**, **Local center admins and above**, or **Organization admins only** | | **Enable Company Fees** | Lets companies pay membership fees for their members. Only appears when the Payments and Fees module is active | With **Enable Company Fees** on, mark fee prices **Company only** in the fee product settings and give each a **Company slots** number: company members then inherit membership status from the company and cannot buy an individual fee. A separate switch, **Settings** → **Modules** → **Payments & Fees** → **Company Fee Payment Mandatory**, locks company members out of the platform until the company fee is paid. *** ## Creating a company **Create** on the Companies list opens one form. Only **Company Name** is required, though payment needs the billing block completed. | Group | Fields | | ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | | Identity | Company Name, Description, Website, Company Logo | | Billing Details | Legal Name, Registration Number, VAT Number, Billing Address, Town, Country | | Financial Contact | Financial contact full name, Financial contact email, Financial contact phone, Additional contact email 1 (Cc), Additional contact email 2 (Cc) | Companies start **Pending** and flip to **Active** on the first paid membership fee. `ADMIN_TENANT` can also set status by hand from the company page. **Delete Company** is a soft delete: the record moves to status Deleted and disappears from every list. An ordinary member who creates a company is added to it as **Primary Contact** and can only ever belong to one company. Administrators (`ADMIN_LOCAL` and above) create companies on behalf of others, so they are exempt from the one-company rule and are not enrolled in what they create. *** ## Roles inside a company Roles are stored per membership; a person may hold several. | Role | What it grants | | ------------------------- | ------------------------------------------------------------------------------------------- | | **Member** | The default. Sees the company page, inherits the membership validity | | **Primary Contact** | Edits the company, manages members and invitations, pays. At most one per company | | **Voting Representative** | A label marking who speaks for the company. At most one per company | | **Financial Rep** | Legacy. Same rights as Primary Contact, but it can no longer be assigned from the interface | Assigning Primary Contact or Voting Representative takes it from whoever held it before, in the same action. `ADMIN_TENANT` can do anything on any company in the tenant, and so can whoever **Who can create companies** names, with a floor of `ADMIN_LOCAL`. Setting it to "Any member" does not grant access to companies you do not belong to. That reach is organization-wide by design, chapter admins included. A company is not attached to a chapter anywhere in its record, so there is nothing for a chapter-scoped permission to narrow down to: an `ADMIN_LOCAL` holder in one chapter sees, edits and manages members and payments on every company in the organization. If that is wider than you want, set **Who can create companies** to **Organization admins only**, which raises the floor to `ADMIN_TENANT`. *** ## Members: users and contacts A membership points at either a **User** (has an account) or a **Contact** (in your database, no account). Both appear in the member list, occupy a seat, and can carry a joined date; contacts are tagged **Contact** and link to the contact record rather than a member profile. Only user memberships inherit the company's validity date: a contact has no fee date, so membership sync skips it. **Add Member** is an `ADMIN_TENANT` action and searches users and contacts not already in a company. Company admins invite by email instead. Both act on people who are already in your database: **Add Member** attaches an existing user or contact to this company, it does not create anybody. To create a member who is not joining through a company, use [Adding Members](/docs/platform/users/adding-members). *** ## Inviting employees The **Team Members** panel and its **Invite** and **Add Member** buttons put a person into *this company*, taking one of its seats and passing the company's membership validity to them. That is a narrower job than adding a member to your organization, which starts from the member directory instead: [Adding Members](/docs/platform/users/adding-members). Team Members panel of a company showing active members with a Primary Contact badge and joined date, a pending invitation with an Invited badge and expiry, and Invite and Add Member buttons **Invite** on the company page. Enter the email, first name and last name, pick a role, and add an optional personal message. The email carries a link to `/company-invitation/{hash}`, which shows the company name and logo, who invited them, the message, and the role they were offered. Accepting joins them to the company and emails a one-time login code, creating their account first if they do not have one. Invitations expire **30 days** after they are sent. Pending ones show in the member list with an **Invited** badge and a countdown; admins can resend (resetting the 30 days) or revoke them. An invitation is rejected up front when there are no free seats, when one is already pending for that email, or when the person already belongs to any company. The seat check runs again at acceptance, so one sent before the company filled up can still fail. First name and last name are labelled Optional in the invite dialog, but the server rejects the invitation without them. Fill both in. *** ## Seats Seats come from the fee price the company bought: each **Company only** price carries a **Company slots** value, and paying for it writes that number onto the company. **0 means unlimited.** The count is active members plus pending invitations, so an outstanding invitation holds a place. Memberships that ended, and those whose user was deleted, do not count. When the allowance is full, **Invite** and **Add Member** disappear. *** ## Paying the company fee Payment and Plan panel listing company membership tiers with slot counts, annual prices and billing period, Select buttons on the unselected tiers, and Pay and Mark as Paid on the current one The **Payment & Plan** panel is visible to the Primary Contact (and any legacy Financial Rep) and to `ADMIN_TENANT`. It lists every non-archived **Company only** price on the tenant fee product, with its slot count and price. Select a plan, then **Pay**. Orgo checks that Legal Name, Billing Address, Financial contact full name and Financial contact email are filled in, sending you to the edit form if any are missing, then offers: * **Pay online**: a Stripe checkout. VAT is added on top of the configured net price as a separate line when your tenant charges VAT on fees and the price is not exempt. * **Get invoice for bank transfer**: generates an unpaid invoice, emails it, and shows a reference to quote on the transfer. Only offered when both bank-transfer membership payments and invoicing are enabled. * **Mark as Paid** (`ADMIN_TENANT` only): records money received outside the platform. It asks for a period start, defaulting to the current expiry so it extends rather than overwrites, records a payment, updates the seats, and voids any pending bank-transfer invoice. On a calendar-anchored fee cycle, a mid-cycle payment buys only the remainder and is prorated: the panel shows the list price struck through next to what you will actually be charged, plus " of months" and the exact period. The charge is always recomputed server-side at checkout, so the quote can never undercharge. Renewal opens **60 days** before the current period ends. Before that window, a company with a valid membership sees no Pay button. *** ## What members get from a company fee When a payment lands, Orgo copies the company's valid-until date onto every active member who has an account, sets the company to Active, and applies the plan's seat count. Joining an existing paid company inherits its date immediately; leaving or being removed clears the person's fee date and fee price. On their own fee screen, company-covered members see "Membership managed by company" with a link to the company, instead of the individual payment options. If **Company Fee Payment Mandatory** is on and the membership has lapsed, members are blocked out: Primary Contacts land on `/company-fee-payment`, a guided three-step page (Billing Information, Select a Plan, Complete Payment), everyone else on `/company-fee-required`, which names the company and points them at the financial contact. *** ## Renewal reminders Companies get their own reminder ladder, separate from individual member reminders: about a month before expiry, 7 days before, 1 day before, on the expiry date, then 7, 14 and 30 days after. Each goes **To** the financial contact email, copying the active Primary Contacts and the two additional Cc addresses. Without a financial contact email, the first Primary Contact is promoted to the To line. A company with nobody reachable is skipped. Only **Active** and **Pending** companies with a plan and a renewal date are reminded. Setting a company to Inactive, or deleting it, stops both the reminder and the renewal invoice that goes with it. *** ## Importing companies **Settings** → **Import** offers **Companies** (with membership details) and **Company Members** (assigning users to companies with roles), both gated on the module being active. Example CSV files are linked next to each. *** ## Related * [Adding Members](/docs/platform/users/adding-members) - the four ways people get into your organization, and where this one fits * [Family Members](/docs/platform/users/family-members) - the household equivalent, without shared fees * [Membership Fees](/docs/platform/fees/fees) - fee products, prices and cycles * [Record a Payment](/docs/platform/fees/record-payment) - payments taken outside the platform * [VAT](/docs/platform/fees/vat) - how VAT is added to a fee price * [Contacts](/docs/platform/contacts) - non-member records that can hold a company seat * [Permissions](/docs/platform/permissions) - what `ADMIN_TENANT` and `ADMIN_LOCAL` cover # Custom Fields Source: https://orgo.space/docs/platform/users/custom-fields Create your own profile fields, control who can see and edit each one, and encrypt the sensitive ones Custom fields capture information Orgo does not ship a column for: emergency contact, T-shirt size, licence number, dietary restrictions, whatever your organisation actually tracks. A field is defined once and reused across the profile form, the registration form, the adhesion form and contact records. Custom fields settings listing the organisation's custom fields with their field types and custom_field_<id> reference tags, plus the Interest Custom Field selector *** ## Creating a field **Settings** → **Users & Profiles** → **Custom Fields**. Creating, editing, reordering and deleting fields all require `ADMIN_TENANT`. The form opens inline at the top of the list. Both are required before Save is enabled. Dropdown, Checkboxes and Radio choice fields start with two placeholder options: add, rename, remove and drag to reorder. File Upload fields need at least one allowed file type before saving. **Public**, **User** or **Admin**, described below. A new field exists but is not shown anywhere yet. Add it to the [profile form](/docs/platform/users/profile-fields), the [registration form](/docs/platform/users/registration-form) or the [adhesion form](/docs/platform/users/adhesion). Custom field editor showing the Title input, the Field type dropdown, the draggable option list, the Visibility selector set to Public, and the Save, Cancel and Remove buttons Drag rows in the list to reorder them. Order matters where a form does not define its own arrangement. *** ## Field types | Type | Stores | Good for | | ------------------------ | ----------------------------------------- | ------------------------------------ | | **Input text** | One line of text | Membership number, emergency contact | | **Input numeric** | A number | Years of experience | | **Textarea** | Multi-line text | Notes, medical information | | **Dropdown** | One option from a list | Region, skill level | | **Checkboxes** | Several options from a list | Interests, languages, committees | | **Radio choice** | One option from a list, all shown at once | Short either-or questions | | **Switcher(True/False)** | On or off | Consent, opt-in | | **Date** | A calendar date | Certification expiry | | **File Upload** | An uploaded file | Certificates, ID scans, signed forms | There is no dedicated URL or email type. Use **Input text** for those. Choice fields store the option's position, not its text. Renaming an option therefore updates it everywhere, including in answers members already gave. Deleting an option does not delete the answers that pointed at it, but those answers no longer resolve to a label and display as a bare number. Prefer renaming over delete-and-recreate. **File Upload fields:** pick at least one allowed type per field from **PDF**, **Images (PNG, JPG)** and **Videos (MP4, WebM)**. Maximum file size is per field, 1 MB to 50 MB, default 50 MB. An optional **Example File** gives members a template to download. *** ## Visibility Every field carries one of three levels, enforced on the server for both reading and writing. | Level | Who can read the value | Who can write it | | ---------- | ------------------------------------------------------------------------- | ------------------------- | | **Public** | Any signed-in member of your organisation, plus the member and your staff | The member and your staff | | **User** | The member and your staff. Other members do not see it at all. | The member and your staff | | **Admin** | Your staff only. The member cannot see it on their own profile. | Your staff only | "Your staff" means `HR_ASSISTANT_TENANT` (implied by `HR_TENANT` and `FINANCIAL_TENANT`) organisation-wide, or `HR_ASSISTANT_LOCAL` (implied by `HR_LOCAL`, `HR_PARENT_LOCAL`, `FINANCIAL_LOCAL` and `ADMIN_LOCAL`) over a member in their own local center. Guest accounts see no custom field values at all. Forms label User and Admin fields "(user only)" and "(admin only)". Admin fields are excluded from the profile completion screen's required-field check, so a member is never blocked by a field they cannot see. Visibility is organisation-wide, not per user type; to vary the questions by type, use per-type [registration forms](/docs/platform/users/registration-form). ### Where a value actually saves Visibility gates writing as strictly as it gates reading, and the write check asks who is signed in at that moment. On the public registration pages nobody is signed in yet, so nothing above Public passes. The value is dropped without an error: the applicant sees a normal success screen and the answer is simply not there. | Where the value is entered | Public | User | Admin | | ----------------------------------------------------------- | ------ | ----------------------------------- | --------------------------------------- | | A member editing their own profile | Saved | Saved | The field is not shown to them | | Your staff editing a member's profile | Saved | Saved | Saved | | A member's [adhesion](/docs/platform/users/adhesion) form | Saved | Saved | Rejected unless staff are filling it in | | The public registration form at `/register` | Saved | **Field renders, answer discarded** | **Field renders, answer discarded** | | A per-user-type form at `/join/` | Saved | **Field renders, answer discarded** | Field is stripped before the page loads | | [Import](/docs/platform/customization/import) from a spreadsheet | Saved | Saved | Saved | "Your staff" is drawn slightly tighter on the profile edit form than elsewhere: the form only offers Admin fields to `HR_LOCAL` and above. Someone holding `FINANCIAL_LOCAL` or `HR_ASSISTANT_LOCAL` can read an Admin field's value on a member's profile but will not find it among the fields they can edit. Give them `HR_LOCAL` on that chapter if editing is part of their job. The practical rule: **only Public fields belong on a registration form.** If you need the answer at sign-up but not on public display, collect it as Public and then control who sees the member's profile at all with [Privacy settings](/docs/platform/users/privacy-settings), or ask for it after joining on the [profile form](/docs/platform/users/profile-fields), where the member is signed in and User visibility works as intended. *** ## Encryption at rest Toggle **encryption** while creating or editing a field. Only `ADMIN_TENANT` sees the toggle. * Only **Input text**, **Input numeric**, **Textarea** and **Date** can be encrypted. Choice, switch and file fields cannot. * **5 encrypted fields per organisation.** To go past the cap, decrypt or delete an existing one; for identity documents use [Identity Validation](/docs/platform/identity-validation), which has its own encrypted storage. * AES-256-GCM, bound to your organisation and to that specific field, so a value cannot be transplanted between fields or tenants. * Turning it on re-encrypts stored values, turning it off decrypts them. Both run in the background after you save and are recorded in your organisation's activity log. * Every decrypting read is logged: who read it, from which address, through which endpoint. Switching encryption off asks you to type the field's name to confirm. It is not a display setting: it rewrites every stored value back to plain text. Reading and editing an encrypted field is no different from any other; the encryption is invisible in the interface. *** ## Where custom fields are used | Surface | How to enable it | Notes | | ------------------------------------------------------ | ----------------------------------------------------- | ------------------------------------------------------------------------------------------------ | | [Profile form](/docs/platform/users/profile-fields) | Add the field in the profile form builder | Also offers **Required** and **Immutable** | | [Registration form](/docs/platform/users/registration-form) | Tick the field on the registration form | Available on per-user-type registration forms too | | [Adhesion form](/docs/platform/users/adhesion) | Tick the field on the adhesion form | | | Contact records | Contacts reuse the fields already on the profile form | | | Member directory | Turn the column on from the column menu | Table view only. `HR_TENANT` anywhere, or `ADMIN_LOCAL` on that administrator's own chapter list | | Imports | Use a `custom_field_` column header | The id is the reference tag shown next to each field in the list | | E-document templates | Use a `{custom_field_}` placeholder | | To collect something from every existing member, add the field to the profile form and mark it **Required**: members are prompted the next time they open Orgo. Event registration forms and the standalone form builder create their own fields, scoped to that event or that form. Those do not appear on this settings page and are managed where they were created. *** ## The Interest field The selector at the bottom of the list designates one Dropdown, Checkboxes or Radio choice field as your interests field. That adds an interests filter to the member directory and an interests breakdown to organisation statistics, and gives the field its own section on member profiles instead of a plain form row. Create a Checkboxes field with your options, add it to the profile form, then select it here. **Enable Skills Field** (**Settings** → **Users & Profiles** → **Configuration**) does the same for skills, except Orgo creates the field and seeds it with a catalogue. While the setting is on the field cannot be deleted, though its options stay editable. Turning it off preserves members' existing selections. *** ## Deleting a field Deleting removes every answer members gave and strips the field from the profile, registration and adhesion form configurations, plus any per-user-type registration form. It is not reversible. To stop collecting a field without losing data, take it off the forms and leave the definition in place. *** ## Tags Tags are a lighter alternative: a name administrators apply to member profiles for filtering and segmentation. Members never see or set their own tags, tags carry no value or type, and tag names are unique within your organisation regardless of capitalisation. Manage them at **Settings** → **Users & Profiles** → **Tags**. Tags settings page listing the organisation's tags with edit controls Use a tag when staff need to label people ("VIP", "needs follow-up"). Use a custom field when you need a member to answer a question. *** ## Troubleshooting Check the field's visibility. Anything above **Public** is discarded on the public registration pages, because the write check asks who is signed in and, at registration, nobody is. There is no error: the applicant fills the box, the account is created, and the answer never reaches the profile. Set the field to **Public** if you need it at sign-up, or move the question to the [profile form](/docs/platform/users/profile-fields), where the member is signed in and User visibility behaves as documented. See the table under [Where a value actually saves](#where-a-value-actually-saves). The same field on a `/join/` form behaves slightly differently: Admin fields are stripped before the page is built, so the applicant never sees them, while User fields still render and are still discarded. Reading User and Admin values on someone else's profile requires the **Orgo administrator** flag or an organisation-wide staff permission (`ADMIN_TENANT`, `HR_TENANT`, `FINANCIAL_TENANT` or `HR_ASSISTANT_TENANT`), or a chapter staff permission **plus the reader and the member being in the same chapter**. The chapter comparison is a direct match, not a walk up the hierarchy, so someone holding `HR_PARENT_LOCAL` over a region does not pick up User and Admin values on members of the chapters below them: on those profiles they see the Public fields only, like any other member. If a regional officer genuinely needs those values across the region, the only permission that delivers them today is an organisation-wide one such as `HR_TENANT`. Weigh that against the reach it grants, and prefer keeping the sensitive questions in an organisation-level workflow instead. The column menu is the table icon above the list, and it only exists in the table view, so a person sitting in **Gallery** will not see it at all. Both the menu and the custom-field columns need `HR_TENANT`, or `ADMIN_LOCAL` while looking at that administrator's own chapter list. A chapter administrator can therefore put a custom field on their own chapter's list, but not on the organisation-wide directory or on another chapter's. For those, use the profile, export the list, or ask an organisation administrator. Import writes custom field values straight to storage and does not run them through encryption, so values loaded from a spreadsheet into an encrypted field are stored as they were typed. Everything still reads back correctly in the interface, which is exactly why this is easy to miss: nothing looks wrong. To bring imported rows under encryption, open the field, switch **encryption** off, save, then switch it back on and save again. Each flip queues a background pass over every stored value for that field, and the second pass encrypts everything it finds in plain text, including the imported rows. Note what the first flip does: it writes every value for the field back as plain text before the second flip re-encrypts them. If that window is unacceptable for the data in question, do not import into that field. Collect the values through a form, or use [Identity Validation](/docs/platform/identity-validation) for identity documents, which has its own encrypted storage. Each flip queues a background pass, and a pass that notices the flag has changed under it stops where it is rather than fighting the newer instruction. Flip twice in quick succession and the first pass can end part-way, leaving some values converted and some not. This is safe to read: every value carries its own marker, so Orgo decrypts the ones that need it and returns the rest untouched, whatever state the field is in. It is only untidy at rest. To settle it, leave the toggle alone for a few minutes, then check your organisation's [Logs](/docs/platform/logs) for the encryption entries, and if you want certainty that every row matches the flag, flip it off and on once more and let that pass finish. Every request that decrypts at least one value files one entry in your organisation's [Logs](/docs/platform/logs), recording who made the request, their IP address, the endpoint they hit and how many values were decrypted. Read it as one entry per request, not one per value. Opening a member's profile files a single entry covering every encrypted field on it, and a screen that lists many members at once files one entry with a large count. The entry is written just after the response is sent, so allow a moment before it appears. Turning encryption on or off is logged separately, with the field name and the direction of the change. *** ## Related * [Profile Fields](/docs/platform/users/profile-fields) for putting fields on member profiles * [Registration Form](/docs/platform/users/registration-form) for collecting them at sign-up * [Adhesion](/docs/platform/users/adhesion) for membership applications * [Privacy Settings](/docs/platform/users/privacy-settings) for the built-in profile data members control themselves * [Permissions](/docs/platform/permissions) for the permission names used above # Deletion of Account Source: https://orgo.space/docs/platform/users/deletion-of-account Exactly what account deletion removes, what it anonymises and what it keeps Deleting an account in Orgo strips the member's contact identifiers, cuts their access permanently, and removes them from every list and search. It does not delete the underlying record, and it does not remove their name, their history or their payments. That distinction matters if you answer erasure requests, so this page states it field by field. Read the tables before you promise a member anything. **Built for** honouring a member's request to be removed from the community. **Replaces** an "archive" flag that leaves the person searchable. Close account page showing Close account, Suspend account, Resign and Delete account actions with their explanations *** ## Where it lives **Profile** → **Settings & Privacy** → **Close account**, then **Delete account**. A confirmation dialog appears ("Are you sure you want to completely delete the account? This action cannot be undone!") and confirming applies the change immediately. There is no module to enable and no setting that turns deletion on or off. The same page also offers **Close account** (sets Inactive, reversible) and, for admins, **Suspend account**. Those are the reversible options; see [User statuses](/docs/platform/users/statuses). *** ## Who may delete an account | Situation | Allowed? | | ------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | | A member deleting their own account | **No**, unless their account is on the guest user type. The attempt is refused with "You cannot delete your account, please contact the administrator." | | A guest deleting their own account | Yes | | An admin deleting a member who belongs to a local group | `ADMIN_LOCAL` over that local group, and the button only appears for `ADMIN_TENANT` | | An admin deleting a member with no local group | `ADMIN_TENANT` | | An HR admin (`HR_LOCAL`, `HR_TENANT`) | No. They see "This profile can be deleted permanently only by organization Admin" and a **Request delete** button that opens a support request instead. | Ordinary members cannot self-delete. An erasure request from a member is something an administrator carries out on their behalf, which is worth building into your privacy procedure rather than pointing members at a button they will not find. *** ## What deletion removes These are cleared or deleted outright on the account: | Data | What happens | | ------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | | Email address | Cleared to empty | | Phone number | Cleared to empty | | Sign-in identifier | Rewritten with a random suffix, so the old email plus workspace no longer resolves to this account | | Local group | Cleared | | Role assignments | Rows deleted, not end-dated. Group and unit memberships go with them, and the history of who held which role disappears. | | Followed units and discussions, muted units | Rows deleted | | Company memberships | End-dated, so the person stops counting as a current employee or company contact | | Access | All existing sessions invalidated immediately; no further sign-in is possible by password or by one-time code | | Visibility | Removed from the member directory and every member listing; their profile page returns an error for everyone, including administrators | ## What deletion keeps These are **not** touched: | Data | State after deletion | | ----------------------------------------------------------------- | --------------------------------------------------------- | | First name and last name | Kept, unchanged | | Date of birth, gender, addresses, town | Kept | | Bio, profile photo, social links, profession and education fields | Kept | | Custom field values | Kept | | Identity documents uploaded for validation | Kept | | Adhesion record and its attachments | Kept | | Payments, invoices and fee history | Kept | | Event registrations and attendance | Kept, including their place on any attendee list | | Discussion posts, comments and reactions | Kept | | The account record itself | Kept. Deletion sets a status; it does not remove the row. | Both tables describe the **Delete account** action only. A record that was merged away also ends up on the Deleted status, but it is not shaped like a deleted account: its email is prefixed rather than cleared, its phone number and local group are kept, and its roles were transferred to the surviving record rather than deleted. See [Merging duplicates](/docs/platform/users/merging-duplicates). "Deleted" in Orgo is an anonymisation of contact identifiers plus a permanent access block. It is not erasure. If your organisation has to satisfy a right-to- erasure request in full, treat the built-in action as step one and remove the remaining personal data yourself: the name and profile fields, custom field values, uploaded identity documents and the adhesion record. Retaining payment and invoice records for the statutory period is normally lawful; retaining a profile photo is not. *** ## What deletion does not do * **It does not notify anyone.** No email goes to the member and none to your administrators. The **Notify Admins on Account Deactivation** setting covers a member closing their own account (Inactive), not deletion. * **It does not write an audit entry.** There is no deletion record in the member's activity log, so if you need a compliance trail, record the request and the action in your own system. * **It does not free places.** Event registrations, attendee lists and waitlist entries are untouched. Cancel those separately if the place should be released. * **It cannot be undone.** There is no restore action, and a deleted account can no longer be edited: an administrator who tries is refused with "User has been deleted". The one exception is a merge, whose source record is also set to Deleted and is put back on its previous status if the merge is undone within 30 days. *** ## What the member experiences Immediately after deletion: * their session ends and they are returned to the login screen; * signing in with a password fails, because the sign-in identifier no longer matches; * asking for a one-time code returns the neutral "if this email exists, a code has been sent" response and no code is sent; * they no longer appear to other members anywhere in the app. Because the email address was cleared, the same person can register again from scratch with the same address. The new account is a genuinely new member with no history: the old record stays where it is, detached. *** ## Automatic clean-up of unconfirmed registrations One deletion happens without anyone pressing a button. Every night at 05:00 UTC, accounts that have been sitting on **Unconfirmed email** for more than two months, with no payments and no adhesion, are removed. Where related records prevent the row from being removed, the account is marked Deleted instead and is anonymised in the same way as above. This only ever touches accounts that never verified their email address. Nothing else is cleaned up on a schedule. *** ## Common questions Delete the account from their Close account page as an `ADMIN_TENANT` (or an `ADMIN_LOCAL` for their local group). Then decide, against your own retention policy, what to do with the name, profile fields, custom field values, identity documents and adhesion record, which the action leaves in place. Record the request and what you did outside Orgo, because the platform does not log the deletion. No. Even setting the status back to Active does not return their email, phone number, local group or roles. They should register again. Use [resignation](/docs/platform/users/resignation), or set them to Inactive. Both keep everything and both are reversible. Payments, invoices and fee history survive untouched, so an unpaid invoice is still an unpaid invoice. Deletion does not cancel debts and does not write anything off. Expected. Event attendance is not touched. Remove the attendance record from the event if it should not be there. *** ## Related * [User statuses](/docs/platform/users/statuses) - Inactive and Suspended, the reversible alternatives * [Resignation](/docs/platform/users/resignation) - recording a departure without removing anything * [Privacy settings](/docs/platform/users/privacy-settings) - limiting what others see, short of deletion * [Identity validation](/docs/platform/identity-validation) - the identity documents deletion leaves behind * [Permissions](/docs/platform/permissions) - the permissions named on this page # Family Members Source: https://orgo.space/docs/platform/users/family-members Group parents, guardians and children into one family record, and hold profiles for relatives who have no account A family is a named record that groups people who belong together: parents and guardians, their children, and other relatives. Each person can be a full member with their own account, or a name-and-email profile held inside the family for people who never sign in. **Built for** organizations whose membership is household-shaped rather than individual, including scouting and youth organizations, sports clubs, and faith communities that enrol whole families and need to know which adult is responsible for which child. Family tab on a member profile showing the family name, a Parents section with the family admin and a Can manage child accounts member, each with the date they were added, a Children section, and an Other Family Members section *** ## How to enable **Settings** → **Modules** → **Users & Profiles** → **Configuration** → **Family & Relationships**. Requires `ADMIN_TENANT`. | Setting | What it does | | ------------------------------ | ------------------------------------------------------------------------------------------------------ | | **Enable Family Members** | Turns on the Family tab and lets you link member accounts into a family | | **Non-Member Family Profiles** | Allows profiles for relatives who are not members, stored as a name, email and phone inside the family | Both toggles are switches on the Users & Profiles configuration page. Turning on **Non-Member Family Profiles** alone shows the Family tab but leaves it empty: the family panel itself renders only when **Enable Family Members** is on. *** ## Where families live Members open **Profile** → **Edit** → **Family** (route `/users/edit/{id}`). A member sees their own family there. Anyone with `HR_LOCAL` for the member's local centre sees, and can manage, the family from the same tab on that member's profile. A read-only summary also appears on the profile page itself: linked members as avatars, non-member relatives as a name plus email and phone. That block is visible to the member and to `HR_LOCAL` administrators only. *** ## Creating a family One family per person. A member who is not in a family yet sees **Create Family**, which names the record after them (for example "Maya Marino Family") and makes them the owner. When an administrator creates a family from someone else's profile, Orgo asks what that person's place in it should be: **Parent/Owner** or **Child**. Picking Child creates the family without an owner and adds the person as a child, which is what you want when the responsible adult is not in the system yet. Ordinary members can create their own family and can add non-member relatives to it. Adding an existing organization member to a family requires `HR_LOCAL`. Members without that permission see: "For privacy reasons, only chapter or association administrators can add organisation members to a family." *** ## Adding people The family panel has three sections, each with its own **Add** button. | Section | Relationship levels it holds | | ------------------------ | ------------------------------------- | | **Parents** | Parent, Guardian, Grandparent, Spouse | | **Children** | Child | | **Other family members** | Sibling, Other | In the **Parents** section, a row that is a member account carries a grey line under the name: **Family Admin** or **Can manage child accounts**, then **Added on** and the date that person joined the family. Children, other relatives and non-member profiles show the name and its tags only. The add dialog asks three things: **Parent** (can manage child accounts), **Child** (account managed by parent), or **Other member** (guardian, grandparent, and so on). **Yes** searches existing member accounts. **No** takes a first name, last name and an optional email, and stores the person as a non-member profile. A **Can manage child accounts** switch appears for anyone who is not a child. Parents and guardians receive it automatically. Linking an existing member takes effect immediately. There is no request for the other person to accept. A person can hold only one non-parent membership across all families. If you add someone who is already a child or sibling elsewhere, Orgo asks: " is already a member of "". Move them to this family?" Moving requires permission on the other family too, and a family owner cannot be moved out of the family they own. Parents and guardians are exempt: a parent of several children legitimately appears in each child's family. *** ## Registering a child who has no account From the Children section you can create the account outright. Orgo asks for an optional email, first and last name, birthday and gender, then: * Creates an active user account with `accountType` set to `child` * Records parental consent (date and method) on both the account and the family membership * Creates the parent's family if they do not have one, adds the parent as owner, and adds the child * Marks the email as confirmed, since the parent supplied it The email is optional, but a child registered without one gets a generated placeholder address that cannot receive mail and cannot be used to sign in. Leave it blank only when you want a record, not a login. If the [Waitlist](/docs/platform/users/waitlist) is active and the child's local centre qualifies, the child goes onto the waitlist instead of straight into the organization. When **Minimum Registration Age** is configured and the child is younger than it, the waitlist entry is flagged **underage** and the Children list shows an "In waitlist, underage" tag next to their name. *** ## Removing people and deleting a family Any member of a family with management rights can remove others; you cannot remove yourself. Removing someone deletes the family link, not their account. Deleting the whole family is a link at the top right of the panel. It only works once every member except the owner has been removed, otherwise Orgo answers "Cannot delete family with other members. Please remove all members first." *** ## Families and fees Family membership does not change what anyone pays. Fees are resolved per member. Linking a child to a parent does not transfer, discount, or cover the child's fee, and there is no family price tier. If you need one payer to cover several people, use [Companies](/docs/platform/users/companies) or a fee bundle instead. *** ## Age settings Two age values exist on the tenant, **Children Auth Restriction Age** and **Minimum Registration Age**, but only the second one has any effect today, and neither is editable from the settings screen: both fields are hidden pending backend enforcement. * **Minimum Registration Age** is read when a parent registers a child. Below it, the child's waitlist entry is marked underage. * **Children Auth Restriction Age** does not restrict authentication. It only drives a notification when a young member reaches that age. Do not rely on these settings for legal age gating. There is no age check on public self-registration: anyone can register regardless of the birthday they enter. If your jurisdiction requires parental consent below a given age (GDPR, COPPA), enforce it in your registration flow and terms. *** ## Common questions The parent registers themselves, opens **Profile** → **Edit** → **Family**, creates their family if they do not have one, then uses **Add** in the Children section and chooses to register the child. The child is linked automatically. Yes. Add both at parent level in the same family. Parents are not restricted to one family, so a parent already in another family record can be added without being moved out of it. No. Adding an existing account requires `HR_LOCAL`. Members can add non-member relatives (name, email, phone) on their own. They can see the child in the family panel and open the child's profile. **Can manage child accounts** is recorded on the membership and controls who may add and edit members inside that family. It does not grant a parent the ability to act as the child elsewhere in the platform. *** ## Related * [Companies](/docs/platform/users/companies) - one organization paying for many members * [Waitlist](/docs/platform/users/waitlist) - where underage children are held * [Registration Form](/docs/platform/users/registration-form) - the birthday field * [Profile Fields](/docs/platform/users/profile-fields) - what a child profile can store * [Privacy Settings](/docs/platform/users/privacy-settings) - who can see whom # Users & Profiles Source: https://orgo.space/docs/platform/users/index Set up registration, manage members, and handle the complete member lifecycle Everything about the people in your organisation lives here: how they join, what you store about them, how you find them again, and what happens when they leave. Looking for how to add someone? There are four routes and [Adding Members](/docs/platform/users/adding-members) compares them: register a member yourself, invite them, let them sign themselves up, or import a spreadsheet. *** ## The member directory **Members** in the sidebar lists everyone in your organisation. **Settings** → **Users & Profiles** → **Who Can See Members in General Groups** decides who sees it at all: All Users, HR Local, HR Tenant, Admin Local or Admin Tenant. At an admin level, ordinary members never see the directory. Always reach the directory from the sidebar rather than by typing a URL. The organisation-wide list lives at `/users?generalUnit=true`; a bare `/users` has no scope to show and renders an empty page. The same screen shows a single group's members at `/users?unit={id}`. Member directory in table view with the filter bar, member rows and the CSV export button Three views share the same filters: the table, **Gallery** (photo cards) and **Map**, which plots members who have a town on their profile. ### Filters The filter bar changes with your permissions and active modules. Only these filters exist: | Filter | What it matches | Shown when | | --------------------------------------- | ------------------------------------------------------------------ | ----------------------------------------------------------------------- | | **Name or Keyword** | Full name, profession headline, company, or role at that company | Always | | **Location** | Town of residence | Organisation-wide and role-group lists | | **Country** / **County** / **State** | Country for international organisations, county or state otherwise | Depends on the organisation country | | **Status** | One member status (see [User Statuses](/docs/platform/users/statuses)) | HR\_LOCAL on that local center, or HR\_TENANT organisation-wide | | **Fee status** | Fee paid, Fee not paid, or Grace period | Fees module on and HR\_TENANT | | **Fee type** | A specific membership fee price | Fees module on and HR\_TENANT or FINANCIAL\_TENANT | | **Card ID** | Partial match on the member card number | **Enable Card/Member IDs** is on | | **Profession** | Profession industry | Professions module with industries on | | Skills, interests, **Availability** | Values from those profile fields | The matching field is enabled | | User type | One user type | **Who Can Filter Users by Type** (All Users or Admin Tenant) allows you | | **Chapter** | Local center | The organisation has local centers | | **All members** / **Only full members** | Full membership | **Full Membership Status** is on | | **All permissions** | Members holding one or more permissions | ADMIN\_TENANT only | **Grace period** only appears when the fee is mandatory, auto deactivation on expiry is on, and the deactivation delay is more than zero days. It finds members whose fee has expired but who are still inside that delay. The permission and user-type filters are enforced server side: asking without the required permission returns access denied, not an unfiltered list. A date-joined range (**From** / **Until**) exists in the mobile filter sheet only; the desktop bar has no equivalent. ### Columns, sorting and row actions Sortable headers: name, user type, full member, age, card ID, town, country or county, chapter, fee date and status. Sorting applies to the whole result set, not just the current page. Columns are permission-gated rather than chosen: | Column | Requires | | ---------------------------------------------------------------------------------- | --------------------------------------------------------------------- | | Email and phone (copy-to-clipboard icons), age | HR\_ASSISTANT\_LOCAL | | Fee | HR\_LOCAL or FINANCIAL\_LOCAL, fees module on | | Adhesion | HR\_LOCAL, adhesion on | | Status | HR\_LOCAL, and no status filter active | | **Groups**, from the column menu | HR\_LOCAL on a chapter list, HR\_TENANT on the organisation-wide list | | One column per [custom field](/docs/platform/users/custom-fields), from the column menu | HR\_TENANT | The column menu itself (the table icon above the list) needs HR\_TENANT, and it only appears in the table view, never in Gallery or Map. Each row's menu holds **View Profile**, **Modify Profile** and **Modify Roles** (ADMIN\_LOCAL and above), plus making or removing a unit admin inside a unit. Members pending approval (**New request**) or waitlisted get **Approve** and **Add to waiting list** shortcuts next to the name, and a **New requests (N)** button jumps to that queue. There is no multi-select: actions apply one member at a time. ### Export and adding members The Excel icon exports the current filtered, sorted list as CSV. Exports are paged at 500 profiles: below that you confirm and download, above it you pick which page, so a large organisation needs several exports. Export needs HR\_TENANT, or HR\_LOCAL with a chapter selected, and each export is written to the audit log with the exact query used. A **Members** report in [Reports](/docs/platform/reports) has no such paging: the download holds every matching member in one file, however many there are. It needs ADMIN\_TENANT and it is built from its own column and filter picker rather than from the list you are looking at, so the directory export stays the quicker route for a chapter admin or for the list already on screen. **Register member** creates an account directly; it needs HR\_TENANT, or HR\_LOCAL for your own local center. The status comes from **Default Status for Admin-Created Users**, and with an email address supplied the member gets a welcome message with a login link. For many people at once, use [Import](/docs/platform/customization/import). **Invite a friend**, next to it, sends a registration link instead. All four routes side by side: [Adding Members](/docs/platform/users/adding-members). *** ## Worked example: what a chapter treasurer sees Permission names on their own do not tell you what lands on screen, because the directory gates the filters, the columns and the export separately. Here is the same person, a chapter treasurer holding only `FINANCIAL_LOCAL` on their own chapter, walking through the list. | What they want | Do they get it | Why | | ---------------------------------------------------------- | -------------- | ---------------------------------------------------------------------------------------- | | The **Fee** column | Yes | The fee column asks for `FINANCIAL_LOCAL` or `HR_LOCAL` | | Email, phone and age columns | Yes | `FINANCIAL_LOCAL` implies `HR_ASSISTANT_LOCAL`, which is what those columns ask for | | The **Fee status** filter (Paid / Not paid / Grace period) | No | That filter asks for `HR_TENANT`, an organisation-wide permission | | The **Fee type** filter | No | That filter asks for `HR_TENANT` or `FINANCIAL_TENANT` | | The CSV export | No | Export asks for `HR_TENANT` organisation-wide, or `HR_LOCAL` on the chapter being listed | | The column menu, to add a custom field column | No | The column menu asks for `HR_TENANT` | So a treasurer who needs to work through unpaid members chapter by chapter needs `FINANCIAL_LOCAL` **and** `HR_LOCAL` on that chapter: `FINANCIAL_LOCAL` for the money, `HR_LOCAL` for the export and the status column. The fee filters are a bigger step: `FINANCIAL_TENANT` unlocks **Fee type** but not **Fee status**, which only `HR_TENANT` opens, and both reach every chapter in the organisation. Before widening someone's scope that far, check whether the chapter-scoped screens in [Local group fees](/docs/platform/local-group-fees/member-fees) already answer the question they are asking. Two implications worth remembering for any permission you hand out: * `FINANCIAL_LOCAL`, `HR_LOCAL` and `HR_PARENT_LOCAL` all imply `HR_ASSISTANT_LOCAL`, so any of them unlocks contact details. `EVENT_LOCAL` and `COMMUNICATION_LOCAL` do not. * Filters and columns are not the same gate. Seeing a value in a column does not mean you can filter or sort a list by it, and being able to read the list does not mean you can export it. *** ## The member profile Clicking a name opens the profile in a modal you can expand to a full page (`/user/{id}`). Which tabs appear depends on modules, permissions and whether the profile is your own. Member profile showing status, user type, age, town, chapter, member since, badges, permissions, resignation, identity, adhesion and roles | Tab | What is there | Who sees it | | ------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- | | **Profile** | Photo, status, user type, age, town, chapter, member since, badges, permissions, roles, social links, resignation, identity and adhesion shortcuts | Everyone who can see the profile | | **My Network** | Connection requests and accepted connections | Own profile, connections enabled | | **Fee** | Fee level, periods and history | Self, HR\_LOCAL, FINANCIAL\_LOCAL, or a parent managing the profile | | **Payments** | Every payment: fees, tickets, donations | Same as Fee, online payments enabled | | **e-Documents** | Contracts and documents assigned to the member | Self, HR\_LOCAL, or a managing parent | | **Events** | Events attended or registered for | Per event-module visibility | | **Files** | The member's personal drive | Self and admins in scope | | **Referrals** | People they referred or invited | Referral or invitations enabled | | **Company** | The company they belong to | Own profile, companies module on | | **[Activity](/docs/platform/users/profile-activity)** | Staff notes, donations, form submissions and tag changes on one feed | HR\_LOCAL or FINANCIAL\_LOCAL over that member, or ADMIN\_TENANT, with **Enable Profile Notes & Activity** on | | **Logs** | Audit and email history | ADMIN\_TENANT | Logs tab showing the audit log with date, action and author, and the email log sub-tab The Logs tab has two sub-tabs. **Audit Logs** records every change with the date, the action, who made it, and an expandable before-and-after view of each field. **Email Logs** shows what the platform sent this member and what happened to it: the fastest answer to "they say they never got it". *** ## Setting up Start minimal: you can collect more later. [Registration form](/docs/platform/users/registration-form) Use these when members fall into categories that behave differently, such as Scout and Leader. Each type can have its own registration form. [User types](/docs/platform/users/user-types) Turn on **Manual Approval** to review each one from the directory. [Statuses](/docs/platform/users/statuses) [Profile fields](/docs/platform/users/profile-fields) · [Custom fields](/docs/platform/users/custom-fields) Members can restrict themselves further, never less. [Privacy settings](/docs/platform/users/privacy-settings) [Permissions](/docs/platform/permissions) Users and Profiles module configuration with the left sub-navigation and the User Types and Registration setting sections All of this lives under **Settings** → **Users & Profiles** and needs ADMIN\_TENANT to edit. The left sub-navigation also holds Custom Fields, Tags, Roles & User types, the Registration and Profile forms, the Referral Program, Privacy Defaults and Security & Permissions. Entries appear only for what is switched on, so the Adhesion form, the Adhesion template and the Registration Waitlist are absent until those modules are active. *** ## Choosing what to turn on | If you want to | Turn on | | ------------------------------------------------ | ----------------------------------------------------------------------------------- | | Review every application before admitting people | [Adhesion](/docs/platform/users/adhesion) | | Queue people when membership is full or closed | [Waitlist](/docs/platform/users/waitlist) | | Let members bring in others | [Invitations](/docs/platform/users/invitations) and [Referral](/docs/platform/users/referral) | | Verify who someone is | [Identity Validation](/docs/platform/identity-validation) | | Support families with children | [Family Members](/docs/platform/users/family-members) | | Track why people leave | [Resignation](/docs/platform/users/resignation) | | Support the GDPR right to erasure | [Account Deletion](/docs/platform/users/deletion-of-account) | | Clean up duplicate records | [Merging duplicates](/docs/platform/users/merging-duplicates) | *** ## Troubleshooting Start with their status: Inactive, Suspended, New request (still awaiting approval) and Unconfirmed email all block access. Full elimination sequence in [Troubleshooting member access](/docs/platform/users/troubleshooting-access). Add the field in [Profile Fields](/docs/platform/users/profile-fields) and mark it required. On their next visit, members with missing required fields are redirected to an onboarding screen that lists exactly what is missing. That redirect only knows about a fixed set of fields: first name, last name, date of birth, gender, phone, address, town born, town current, and the Facebook, Twitter, LinkedIn, Instagram, Telegram and TikTok links, plus any custom field. Marking anything else required, in particular **Bio**, **Postal code**, **Website**, **Location on members map**, the three **Profession** fields or any of the company fields, still marks it required on the profile form, so a member who opens that form cannot save without it. What it does not do is trigger the prompt, so nobody is ever sent there and the field quietly stays empty for everyone who does not edit their profile. If one of those is what you actually need, collect it with a [custom field](/docs/platform/users/custom-fields) instead, which the prompt does check. The directory opens in **Gallery** for everyone who is not an Orgo administrator, and in the table for those who are. Nothing is missing: the view toggle above the list switches between table, Gallery and Map, and your choice is remembered in that browser from then on. If a colleague says a column is missing, first check that they are looking at the table and not at Gallery, since the column menu is only offered in the table view. Columns are not a shared setting. Each one is gated on the permission in the table above, evaluated per person and, for chapter permissions, per chapter. Turning a column on from the column menu changes what you see, not what your colleagues see. The two that surprise people most: email, phone and age need `HR_ASSISTANT_LOCAL`, which `HR_LOCAL`, `HR_PARENT_LOCAL` and `FINANCIAL_LOCAL` all imply but `EVENT_LOCAL` and `COMMUNICATION_LOCAL` do not; and the custom-field columns need `HR_TENANT`, so a chapter administrator does not get them even on their own chapter's list. Export is gated separately from reading the list. On the organisation-wide list it needs `HR_TENANT`. On a chapter's list it needs `HR_LOCAL` on that chapter. `FINANCIAL_LOCAL`, `ADMIN_LOCAL` and `HR_ASSISTANT_LOCAL` are not enough, even though all of them can read the list and some of them see more columns than the export contains. A chapter secretary who has `HR_LOCAL` but still sees no button is usually on the organisation-wide list rather than their chapter's. Pick the chapter in the **Chapter** filter first. Four conditions have to hold at once: **Manual Approval** is on, you hold `ADMIN_LOCAL`, you are looking at either your own chapter's list or the organisation-wide list with `HR_TENANT`, and you are not already filtering by the Unapproved status. The last one catches people out: the button hides once you are in the queue it would take you to. `HR_LOCAL` alone does not show the counter. The **Approve** and **Add to waiting list** shortcuts on the row are a separate gate and do appear for `HR_LOCAL`, because approving somebody is an ordinary status change and asks for `HR_LOCAL` over that member's chapter. So a chapter secretary can approve people one at a time from the list; what they do not get is the counter that jumps them to the queue. Sidebar entries and page permissions are configured in two different places and can disagree. Each entry in the sidebar carries its own permission, set in **Settings** → **Customization** → [Menu Organizer](/docs/platform/customization/menu-organizer), while what the Members page shows is decided by **Settings** → **Users & Profiles** → **Configuration** → **Who Can See Members in General Groups**. Set the menu entry more generously than that setting and people see a link that leads to an empty page. Fix it at whichever end reflects your intent: raise the menu entry's permission to match the visibility setting, or lower the visibility setting if the members really should see the directory. Do not assume a hidden link means a protected page, or that a visible link means an accessible one. *** ## Related * [Adding Members](/docs/platform/users/adding-members) - the four ways people get an account * [Lists & Segments](/docs/platform/users/lists) - reusable audiences built from member criteria * [User Statuses](/docs/platform/users/statuses) - what each status blocks * [Permissions](/docs/platform/permissions) - who can do what * [Custom Fields](/docs/platform/users/custom-fields) - data Orgo does not ship with * [Contacts](/docs/platform/contacts) - people who are not members # Member Invitations Source: https://orgo.space/docs/platform/users/invitations Let existing members invite new people to join your organization Invitations let your existing members bring new people in by email, or by sharing a personal link. The invited person lands on your registration form with their email already filled in, and the invitation is credited to whoever sent it. **Built for** organisations that grow by word of mouth. **Replaces** forwarding a signup URL by hand and having no idea who brought whom. Inviting is one of four ways somebody gets an account. If you would rather create the account yourself, or load a spreadsheet, compare the routes in [Adding Members](/docs/platform/users/adding-members). *** ## Turning invitations on **Settings** → **Users & Profiles** → **Configuration** → **User Invitations**. Changing these settings requires ADMIN\_TENANT. The same **Enable User Invitations** switch also appears on the **Referral Program** settings page, so you can find it from either place. | Setting | What it does | | ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------- | | **Enable User Invitations** | Turns the feature on. Without it, the Referrals tab and the invitation endpoints are closed to everyone. | | **Who Can Send Invitations** | The minimum permission needed to send. Options are **All Users**, **HR Local**, **HR Tenant**, **Admin Local**, **Admin Tenant**. | Both the interface and the API check **Who Can Send Invitations**, so restricting it actually blocks sending rather than just hiding the button. User Invitations section of the Users and Profiles configuration page with the Enable User Invitations switch and the Who Can Send Invitations selector *** ## Where members invite from Members invite from the **Referrals** tab on their own profile. The tab only appears if invitations are on and the member meets **Who Can Send Invitations**. There is also an **Invite a friend** button above the member directory, which opens the same tab. The tab offers two mechanisms. Referrals tab on a member profile showing sent, joined and pending counters, the personal referrer link with copy and share buttons, the invite by email box and the invitation history list ### Your referrer link A personal link of the form `https:///register/`, with copy, WhatsApp, Email and Messenger share buttons. Anyone who registers through it is recorded as referred by that member. Nothing is sent by Orgo: the member shares the link themselves. ### Invite by email The member types addresses into the email box and sends. Orgo emails each address a registration link tied to that specific invitation. | Limit | Value | | ------------------------------- | ------------------------------------------------------------ | | Addresses accepted by the box | 20 | | Addresses processed per send | the first 10 | | Invitations per member per hour | 50, after which sending is refused until the hour rolls over | Malformed addresses are skipped silently, and an address that already has a pending invitation is reported back as already invited rather than emailed twice. Because only the first ten addresses in a send are processed, work in batches of ten rather than pasting twenty at once. If a local administrator opens the tab in their local center context, the invitations they send carry that local center, and people who accept are placed in it automatically. *** ## What the invited person experiences Sent from your organisation's address, naming the member who invited them and the local center if there is one. The email is controlled by **Settings** → **Emails & Notifications** → **System Emails** → **User Invitation**: turn that off and no invitation emails go out. The registration form loads with their email already filled in and locked to the invited address. If they have no account yet, the form also asks them to set a password. An invited registration skips email confirmation: the account is created as active with the email already confirmed, and they are signed in and taken to the dashboard straight away. The invitation record is consumed, the inviter gets an in-app notification that their invitation was accepted, and the person moves from Pending to Joined in the inviter's history. Inviting an email address that already belongs to a member of your organisation does not fail at the invite step, but their registration will: the form rejects the email as already registered. Check the member directory before inviting. *** ## Tracking who brought whom The Referrals tab shows the sender three counters: **Invitations sent**, **Joined** and **Pending**, plus a conversion percentage once there are more than two invitations and at least one join. Below them, **Invitation history** lists every invitation under **All**, **Joined** and **Pending** tabs, and the member can delete any of their own pending invitations. Pending means the invitation was emailed and nobody has registered with it yet. Joined means someone registered through that member's link or invitation and the referral record is complete. If your organisation reviews new registrations (**Manual Approval** in **Settings** → **Users & Profiles**), the referral is not completed at registration. It completes when the member is activated, and that completion step also awards referral points. It currently only runs when the Gamification module with tiers is enabled, so on a manual-approval organisation without gamification the invitation stays in Pending. Invitations do not expire on their own. The tab shows a note about 30 days, but no job deletes old invitations: a link keeps working until the person registers with it or the inviter deletes it. *** ## Not the same thing as the referral program Invitations are an existing member reaching out to an outsider, and they make signup faster. The [Referral Program](/docs/platform/users/referral) is other members vouching for someone who has already registered, and it makes signup slower on purpose. They share the Referrals tab and sit on the same settings page, but neither one turns the other on, and neither makes your organisation invite-only. *** ## Common scenarios Enable invitations and set **Who Can Send Invitations** to **All Users**. Every active member gets the Referrals tab with the email box and their personal link. Raise **Who Can Send Invitations** to **HR Local** or higher, so only chapter staff can invite. To keep open invitations but add a review step, turn on **Manual Approval** so new registrations land as Unapproved, or use [Adhesion](/docs/platform/users/adhesion) for a full application. Check the spam folder first: the mail comes from your organisation, not from the member's own address. Then check whether that address was already invited, in which case the send is skipped and no second email goes out. Confirm the **User Invitation** system email is still switched on, and look the address up in the delivery log under Emails & Notifications. As a fallback, delete the pending invitation from the history list and send it again. Yes, that combination works. With **Enable Registration Form** off, the public Register link disappears and self-registration is refused, while a valid invitation link still opens the form for the person you sent it to. **Manual Approval** and the [Waitlist](/docs/platform/users/waitlist) are the alternatives if you want the form to stay open and the intake reviewed instead. *** ## Related * [Adding Members](/docs/platform/users/adding-members) - all four routes into the platform compared * [Referral Program](/docs/platform/users/referral) - members vouching for a new signup * [Registration Form](/docs/platform/users/registration-form) - what invitees fill in * [Waitlist](/docs/platform/users/waitlist) - queueing new registrations per local center * [Adhesion](/docs/platform/users/adhesion) - application review for new members * [Permissions](/docs/platform/permissions) - what each permission level covers # Lists & Segments Source: https://orgo.space/docs/platform/users/lists Build reusable groups of members and contacts by criteria, and use them as newsletter audiences A list is a reusable set of members and contacts: everyone who joined this year and has not paid, everyone with an active recurring donation, everyone who attended last year's conference. Lists are what you pick as the audience when you send a newsletter. **Built for** organisations that send to parts of their base rather than all of it. **Replaces** the spreadsheet you re-filter before every mailing. Lists live under **Administration** → **Communication** → **Lists & Segments** (`/email-lists`). They require the newsletter module, and the menu entry appears for COMMUNICATION\_TENANT. HR\_TENANT also has full access. Lists and Segments index with All, Dynamic and Static chips and a table of lists showing type, audience, subscribed and total counts The index has five columns: **Name**, **Type** (Automated or Static), **Audience** (the profile type), **Subscribed** and **Total**, plus edit and delete buttons on each row. Chips at the top filter to **All**, **Dynamic** or **Static**, a search box appears once you have more than ten lists, and the table pages at 20. *** ## Two kinds of list **Automated** lists are defined by criteria and re-evaluate themselves. Someone who becomes eligible tomorrow is in the list tomorrow, with no action from you. **Manual** lists contain exactly the people you put in them, and change only when you change them. The type and the audience scope are fixed when the list is created. Both controls are locked on the edit screen. If you build a manual list and later want it to maintain itself, create a new automated list. *** ## Creating a list The **Describe your audience** panel takes a plain-language description of up to 1000 characters, for example "active members in Norfolk who joined this year and have not paid", and turns it into a name, a scope and a set of criteria, with an estimate of how many people match. It is a starting point, not the saved definition: review what it produced before saving. **Automated by criteria** or **Manual selection**. This cannot be changed later. **Members & Contacts**, **Members Only** or **Contacts Only**. Contacts are people in your database who are not members: newsletter subscribers, past attendees, donors who never joined. See [Contacts](/docs/platform/contacts). **Active Only**, **Inactive Only** or **All (Active & Inactive)**. Active Only is the default, so a list silently excludes lapsed members until you widen it. This is the one audience setting you can still change after creation. Add as many as you need. Criteria always combine with **AND**: every condition must be true. There is no OR and no grouping. You can also start from **Ask Orgo**. When an answer there is a set of people, it offers **Save as segment** (or **Open in editor** on a list proposal), which opens this builder with your question already in the describe box and the suggestion already running. List builder with the Describe your audience panel, list type cards, profile type and member status choices, and two filter criteria joined by AND *** ## What you can filter on Available criteria depend on the profile type, because members and contacts do not carry the same data. | Criterion | Members Only | Contacts, or mixed | Values | | ------------------------------ | ------------ | ------------------ | ------------------------------------------------------------------------------------------------------------ | | **Status** | yes | yes | One of your profile statuses, or No status | | **Tags** | yes | yes | Has tag, Has all tags, Doesn't have tag | | **Date joined** | yes | yes | A date, with before/after/equals comparisons | | **Age** | yes | yes | A whole number of years, with comparisons | | **Has Payment** | yes | yes | Has donation, No donation, Any payment, No payments | | **Has Recurring Payment** | yes | yes | Active, past or any recurring donation, the negations of each, any active or past recurring payment, or none | | **Event Attendance** | yes | yes | Attended any event, Never attended any event, Attended specific event, Not attended specific event | | **Local center** | yes | yes | A specific center, Has no local center, Has any local center | | **Valid fee date** | yes | no | A date | | **Date joined as full member** | yes | no | A date | | **Only full members** | yes | no | Yes or No | | **Membership Fee Status** | yes | no | Paid, Not Paid | | **Donation dropout** | no | Contacts Only | Started but never donated | **Local center** only appears when your organisation uses local centers. **Status** is always offered on Members Only; on the contact scopes it appears only when contact statuses are turned on. For the two donation criteria, picking a donation value reveals a **Product** selector so you can narrow to one donation campaign rather than all of them. Choosing "Attended specific event" reveals an event search. ### Operators Which comparisons you get depends on the criterion, and the **Operator** dropdown is hidden when only one applies: | Criterion | Operators | | -------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | | The three dates, **Age** and **Only full members** | Equals, Not equals, Greater than, Greater than or equals, Less than, Less than or equals, Contains, Is null, Is not null | | **Tags** | Has tag, Has all tags, Doesn't have tag | | **Local center** | Equals, Has no local center, Has any local center | | Everything else | Equals only | So "under 18" or "joined after March" are comparisons rather than exact matches. There is no free-text criterion: you cannot build a list by name or email address. *** ## Working with a saved list List detail with total contacts, subscribed, unsubscribed and member status tiles, the active criteria card, and the recipients table with subscription filter chips An automated list over members opens with four tiles: the total, how many are **Subscribed**, how many are **Unsubscribed**, and the member status the list applies. A manual list, and an automated Contacts Only list, show the first three. A list built on **Event Attendance** shows the total alone, because the subscribed split does not apply to it. Below them, **Active criteria** spells out the saved definition of an automated list in plain terms, and **Recipients** lists the people themselves. On an automated list, chips above the table switch between Subscribed, All and Not subscribed. A manual list has no chips: the table always shows everyone in it, subscribed or not, so what you see matches the **Total** tile above. Subscribed means the person explicitly opted in. Someone who never made a choice counts as not subscribed rather than as subscribed, which is why a list you built by hand can show a Subscribed count well below its total. Campaigns only reach subscribed addresses, so a list whose total is much larger than its subscribed count will send to fewer people than it appears to hold. See [Contacts](/docs/platform/contacts) for the three subscription states. Lists over 100 people do not load their members automatically: use **Show recipients**. The recipients table pages at 50 at a time. On a manual list you also get **Add**, which searches members or contacts by name and adds the ones you tick, **Add CSV** for bulk additions from a file, and a remove button per row. Adding someone who is already in the list is harmless: the existing entry is kept and the row is reported as skipped rather than failing. Adding and removing people on a manual list requires **ADMIN\_TENANT**, which is a higher bar than the rest of this page. A COMMUNICATION\_TENANT holder can open the list and see the **Add**, **Add CSV** and remove controls, but those calls are refused. If you manage manual lists, you need ADMIN\_TENANT. Automated lists have no add or remove buttons. To change who is in one, change its criteria. *** ## A list is not the same thing as an audience When you compose a newsletter you pick one audience, and a saved list is only one of the choices: | Option | Who it sends to | | ---------------------------- | ------------------------------------------------------------------------ | | **All members and contacts** | Everyone subscribed in the database | | **Members from a group** | One group | | **All subscribed contacts** | Contacts only, no members | | **From a list** | A saved list, the subject of this page | | **Event attendees** | Participants of one event | | **Non-openers of "..."** | People who did not open an earlier campaign, offered only on a follow-up | The other five are derived from the platform's own structures and cannot be saved or reused. Reach for a list when the audience is a question about the people themselves rather than a group, an event or a previous campaign. Someone whose only communication permission is COMMUNICATION\_LOCAL sees just one option, **Members from a group**. **From a list** is hidden from them, along with the two database-wide options and event attendees. Local campaign managers send to a group they manage, not to a saved list. Choose **From a list** and pick the list. The count shown next to the option is the subscribed count, not the total. For an automated list, the audience is resolved again when the newsletter is actually sent, so people who became eligible after you drafted it are included and people who no longer qualify are not. If the newsletter belongs to a local center, that center's boundary is applied on top of the list, so a list cannot be used to reach members outside it. One exception is worth knowing: a list built on **Event Attendance** ignores the subscribed and unsubscribed split entirely, because event mail is treated as informational rather than marketing. *** ## When a list is not enough List criteria cover the questions organisations ask most often, and they only combine with AND. If you need something they cannot express, such as a report across several years of payment history, ask about custom database queries: those are set up for your organisation and appear on the statistics page rather than here, behind the analytics query feature and FINANCIAL\_TENANT or explicit query access. *** ## Related * [Newsletter](/docs/platform/newsletter) - composing and sending to a list * [Users & Profiles](/docs/platform/users) - the member directory the criteria draw on * [Contacts](/docs/platform/contacts) - non-member people who can be in a list * [Custom Fields](/docs/platform/users/custom-fields) - extra data on a profile * [Permissions](/docs/platform/permissions) - what COMMUNICATION\_TENANT and HR\_TENANT unlock # Merging Duplicates Source: https://orgo.space/docs/platform/users/merging-duplicates Find and combine duplicate members and contacts, choose which values survive, and undo a merge within 30 days Duplicates accumulate. Someone registers twice with two email addresses, a contact imported from a spreadsheet already exists as a member, or an event attendee signs up again the following year without logging in. Merging folds two records into one and moves the history of both onto the record you keep. **Built for** organisations whose data came from more than one place. **Replaces** deleting one of the two records and losing everything attached to it. Merge Records is at **Settings** → **Developers** → **Merge Records** (`/admin/merge`). It needs `HR_TENANT`, and the **Merge Profiles** toggle under **Settings** → **Users & Profiles** must be on. With the toggle off, the page redirects to the dashboard. Merge Records page with the manual source and target selectors above a Duplicate Suggestions table showing match scores and reasons *** ## What can merge into what | Direction | Allowed | | -------------------- | ------- | | Contact into contact | yes | | Member into member | yes | | Contact into member | yes | | Member into contact | no | A member is never folded into a contact. If you pick that combination the page tells you to swap the two: select the contact as source and the member as target. The **source** is the record that goes away. The **target** is the record you keep. The page labels them exactly that way: **Source (will be deleted)** and **Target (will be kept)**. *** ## Finding duplicates **Duplicate Suggestions** at the bottom of the page has three tabs, searched separately: * **Contact Duplicates** and **User Duplicates** find records that share an email address (scored 100%) or share a name while having different emails (scored 70%). * **Contact-User Matches** finds a contact and a member with the same email (scored 95%). This is the common case after importing a mailing list. Each tab shows up to 50 pairs, highest score first, with the reason for the match. Deleted members are excluded. **Merge** on a row loads the comparison straight away. If you already know the pair, use **Manual Merge** at the top instead: pick Contact or User for each side, then search by name or email. *** ## Reviewing before you merge The comparison is the point of the feature. It puts source and target side by side, one row per field. Fields where the two agree are ticked and left alone. Fields where they disagree are tagged **Conflict** and get a pair of radio buttons: keep the source value or keep the target value. Orgo preselects a suggestion for every field, preferring a filled value over an empty one, and the longer text when both are filled. Read the conflicts anyway, particularly email and phone. For member-to-member merges, profile custom field values are compared in the same table alongside the built-in fields. Underneath, **Related Records to Transfer** counts everything attached to the source: event attendance, payments, invoices, subscriptions, fee payments, roles, badges, adhesions, course enrolments, form submissions, identity documents, tags, company memberships, family links, posts and discussions, files, votes, tasks and more. Those counts are what will move. Merge comparison table with source and target columns, Conflict tags and radio buttons for choosing which value to keep, above the related record counts *** ## What happens when you confirm Everything below runs in a single transaction. If any part fails, nothing changes. * The field values you chose are written to the target. * Related records are re-pointed at the target. Where both records already have the same thing, the duplicate is dropped rather than doubled: one attendance per event (the source's status and payment win), one value per custom field, one tag, one company membership. * The source's sign-in material is destroyed, not moved: sessions, API tokens, push tokens and any active impersonation session are deleted. * A source **contact** is deleted outright. * A source **member** is kept as a tombstone so nothing breaks: their status becomes **Deleted**, their email and username are prefixed so the address is free for reuse, their identity link is cleared, and their first name is prefixed with `[MERGED]`. A deleted record is hidden wherever deleted members are hidden: the member list, search, duplicate suggestions, email lists and campaigns. It cannot be opened or edited afterwards, so undo is the only route back. * The source drops out of any manual list it was in: it stops being counted, stops appearing in the recipients table, and stops receiving campaigns sent to that list. Its place in the list is not moved to the target, so add the target by hand if it should be on the list. * The chapter does not move. The survivor keeps its own chapter, even though the source's roles do move across, so check the Roles tab afterwards when the two records sat in different chapters. * For a member-to-member merge, both profiles get a merge entry in their Logs tab, recording who did it and which record it was merged into. When the source is a contact, only the surviving member gets an entry, and a contact-to-contact merge writes none: **Merge History** is the record for those. *** ## Undoing a merge **Merge History** (top right of the page, `/admin/merge/history`) lists every merge with its date, direction, both record names, who performed it, and its status. A merge can be undone once, within 30 days. After that the **Undo** button is replaced by **Expired** and the merge is permanent. Undo restores the source from the snapshot taken at merge time and points the transferred records back at it. A source contact that was deleted is recreated, which means it comes back with a new id. It also rewinds the surviving record. Every field you took from the source goes back to the survivor's own pre-merge value: profile fields, custom field values, the username the merge regenerated from the new email address, and the identity record and payment customer reference it was handed. A value is only put back while it still holds exactly what the merge wrote into it, so anything you edited on the survivor after the merge is left as you left it. What undo does not do is remove activity. Anything created on the survivor since the merge stays there. Roll back promptly if a merge was wrong, before new activity piles up on the record you would have to sort out by hand. If the source's old email address was claimed by a new account while the merge stood, the source comes back under a suffixed username so the live account keeps its own sign-in; the restored person still signs in with their email address as normal. If undo cannot proceed at all because it would duplicate a unique value, it is refused with a message naming that value and nothing is changed. Merge History table listing past merges with date, type, source and target records, who performed them and their status, with an Undo button while the rollback window is open and Expired once it has closed *** ## What merging is not for Merging is for two records that are the same person. It is not the way to remove someone from your database: use deletion, so their history is not silently attached to somebody else. It is also not a bulk tool. There is no "merge all suggestions" action, and each pair is reviewed on its own. If an import created thousands of duplicates, roll the import back instead. *** ## Related * [Data Import](/docs/platform/customization/import) - the usual source of duplicates, and how to undo one * [Contacts](/docs/platform/contacts) - what a contact is, and how it differs from a member * [Deletion of Account](/docs/platform/users/deletion-of-account) - removing a record instead of merging it * [Custom Fields](/docs/platform/users/custom-fields) - the profile values compared during a merge * [Permissions](/docs/platform/permissions) - what HR\_TENANT unlocks # Privacy Settings Source: https://orgo.space/docs/platform/users/privacy-settings Control who can see each piece of member profile data: organisation defaults, per-member controls, and the directory-wide visibility rules Privacy in Orgo works on two independent layers. You set organisation defaults that are copied onto each account the moment it is created, and every member then owns their own settings from that point on. On top of both, three tenant-wide settings decide who is allowed to browse the member directory at all. Default Privacy Settings with toggles for Name, Email, Phone, Age, Town, Profile Image, Profession and Social Media *** ## Organisation defaults **Settings** → **Users & Profiles** → **Privacy Defaults**. Requires `ADMIN_TENANT`. Toggle ON means the field is visible to the community by default. | Setting | Help text in the app | | ----------------- | ----------------------------------------------- | | **Name** | Show full name to community by default | | **Email** | Show email to community by default | | **Phone** | Show phone number to community by default | | **Age** | Show age to community by default | | **Town** | Show town/location to community by default | | **Profile Image** | Show profile image to community by default | | **Profession** | Show profession to community by default | | **Social Media** | Show social media links to community by default | These are a starting point, not a ceiling. The values are copied onto a member's own privacy record once, when the account is created. Changing them afterwards does not touch a single existing member, and nothing stops a member from switching a field back on that you defaulted to admin-only. If a field must never be visible to other members, remove it from the profile form rather than relying on the default. *** ## What a member controls A member opens their own profile, then **Settings & Privacy** → **Privacy**. Local admins (`ADMIN_LOCAL` and above) and a parent managing a child's profile see the same panel. Member privacy panel with the Make my profile completely private master switch above toggles for Name, Email, Phone, Age, Profile image and town, and Profession and social media The member panel groups fields more tightly than the admin defaults do: **Profile image & town** is one switch, and **Profession & social media** is another. Setting either one applies to both fields behind it. Each card shows its current state as "All community" or "Only by admins". **Make my profile completely private** sits above the rest. Turning it on sets every field to private and greys the individual switches out. Turning it off sets every field back to visible. *** ## What each setting actually hides This is what a signed-in member without HR or Financial permissions sees on someone else's profile. | Setting is private | Effect | | ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------- | | **Name** | Last name is cut to its initial and a full stop, and a multi-part first name is cut to its first part. "Maya Louise Marino" reads as "Maya M." | | **Email** | Email address is blank | | **Phone** | Phone number, local number and country code are all blank | | **Age** | Age is blank | | **Town** | Current town and home town are blank | | **Profile image** | Photo is blank | | **Profession** | Profession headline and industry are blank | | **Social media** | Every social link is blank: TikTok, Telegram, Instagram, Facebook, Website, LinkedIn, Twitter, Signal, Bluesky | Three things are hidden from ordinary members no matter how the switches are set: **date of birth**, **member card ID**, and the **identity verification record**. Age can still be shown, date of birth cannot. Anonymous visitors and guest accounts get the strictest treatment. They see the shortened name and no email, phone, age, town, photo or profession, regardless of what the member chose. **Make my profile completely private** does more than blank fields. The member is filtered out of member lists and directory queries entirely, and opening their profile URL returns "This profile is private" to anyone who is not allowed to see it. *** ## Who sees the unredacted profile Field-level privacy is skipped for: * the member themselves; * a parent who manages that member's profile through the family feature; * `ADMIN_TENANT`; * anyone with `HR_TENANT` or `FINANCIAL_TENANT`, because both imply the assistant-level HR read; * anyone with `HR_LOCAL`, `HR_PARENT_LOCAL`, `FINANCIAL_LOCAL` or `FINANCIAL_PARENT_LOCAL` over that member's local center, for the same reason. The private-profile master switch is narrower: it is overridden only by `ADMIN_TENANT`, `HR_TENANT`, `HR_LOCAL` over the member's local center, and `ADMIN_PARENT_LOCAL` inside its regional scope. Financial permissions grant full profile visibility. If you appoint a treasurer at a local center, they can read every field on every member of that local center, privacy switches included. *** ## Directory-wide visibility **Settings** → **Users & Profiles** → **Configuration**, section **Privacy & Visibility**. All three require `ADMIN_TENANT` to change. | Setting | What it does | | --------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Who Can See Members in General Groups** | Minimum permission needed to browse the full member list. Below it, a member must narrow the list by group, local center or profession first. Options: All Users, HR Local, HR Tenant, Admin Local, Admin Tenant. | | **Who Can See Local Center Members** | Minimum permission needed to filter members by a given local center. Same options. | | **Restrict Profiles to Shared Local Centers** | When on, a member can only open profiles of people they share a local center with, counting local centers reached through unit roles. Admins and regional admins are exempt. | *** ## Bulk export Exporting members to CSV requires `HR_LOCAL` at minimum, and the export is capped at 500 rows per page. A plain member cannot download the directory even for fields they are allowed to read on screen, so field visibility and bulk access are two separate controls. *** ## Related * [Profile Fields](/docs/platform/users/profile-fields) covers what data a profile holds in the first place * [Custom Fields](/docs/platform/users/custom-fields) has its own visibility and encryption options * [Permissions](/docs/platform/permissions) explains the roles named above * [Identity Validation](/docs/platform/identity-validation) covers ID documents, which privacy switches do not govern * [Account Deletion](/docs/platform/users/deletion-of-account) is the permanent option # Profile Activity & Notes Source: https://orgo.space/docs/platform/users/profile-activity The Activity tab: staff notes, donations, form submissions and tag changes on one feed, and who can read it Activity is a single feed of what a person has done with you and what your staff have written about them: donations, form submissions, tag changes and notes, all merged newest first. It is where your team keeps the running story of a member or a contact, in the words of the people who spoke to them. **Built for** the membership officer who needs to know what happened with someone before calling them back. **Replaces** the shared spreadsheet of "who spoke to whom" and the notes people keep in their own inbox. Activity tab on a member profile, with a Notes composer above an Activity feed whose filter chips read Donations, Notes, Tags, Forms, Date, Author and Search, and entries grouped under the day headings 07 AUG 2026, 24 FEB 2026 and 12 FEB 2026 *** ## Turning it on **Settings** → **Modules** → **Users & Profiles** → **Configuration** → **Enable Profile Notes & Activity**. It needs `ADMIN_TENANT` and it is **off** until you switch it on. The Users and Profiles configuration page with Enable Profile Notes & Activity switched on, sitting below Enable Skills Field and Enable Weekly Availability The setting is a real gate, not a way of hiding a tab. Every endpoint behind the feature checks it, so with it off nobody reaches the feed or the notes, whatever they type into the address bar or call from the API. Switching it back off deletes nothing. Notes stay in the database, and they reappear exactly as they were, with their authors and dates, when the setting goes back on. *** ## Who can see it Two conditions have to hold at once: the setting is on, and you hold **HR** or **Financial** permission over the person you are looking at. `ADMIN_TENANT` covers everybody. Contacts use the identical gate. | | Activity | Logs | | --------------------------- | ------------------------------------------------------------------- | --------------------------------------------------- | | Permission | `HR_LOCAL` or `FINANCIAL_LOCAL` over that person, or `ADMIN_TENANT` | `ADMIN_TENANT` only | | Needs a setting switched on | Yes, **Enable Profile Notes & Activity** | No | | What it shows | Donations, form submissions, tags and notes | Every recorded change, with before and after values | | Exists on contacts | Yes | No | So the two tabs answer different questions for different people. A chapter secretary with `HR_LOCAL` gets Activity on their own chapter's members and never sees Logs. Someone auditing a disputed profile edit wants Logs, and only a tenant administrator has it. Staff who hold HR or Financial permission get the Activity tab on **their own profile** as well, so they can read the notes colleagues have written about them. Treat notes as something the subject may eventually read, and keep anything genuinely confidential out of them. The setting's own help text is more reassuring than the behaviour, so do not rely on it. *** ## Where it lives On a **member profile**, Activity is a tab, next to Logs. The note composer sits at the top of the tab and the feed underneath it. On a **contact record**, there is no tab strip, so Notes and Activity are two stacked cards in the body of the record, below Tags. They behave the same way. Contact record with Tags, Notes and Activity as stacked cards, the Notes card holding an Add a note about this contact box with an Action select, and the Activity card listing three Note added entries and a Donated 50 usd entry *** ## What appears in the feed Four kinds of entry, merged into one list, newest first. | Entry | Where it comes from | What it says | Opens | | ------------ | ------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------- | ---------------- | | **Donation** | A successful payment on a donation product, or a payment flagged as a split donation | "Donated 50 usd". No author | No | | **Form** | A form the person submitted | 'Completed form "Volunteer Application Form"'. No author | Yes, the answers | | **Note** | A note your staff wrote | "Note added" or "Note modified", or **Called** or **Emailed** when the note carries that action, with the author and the time | Yes, the note | | **Tag** | A tag added to or removed from the profile | 'Tag "Leadership" added' or 'Tag "Sports" removed', with who did it | No | A fifth row appears once a note is deleted: **Note removed**, recording that something was there. It carries no text and it does not open, because the text is gone. Donations and form submissions never carry an author, because they are things the person did rather than things somebody did to their record. Tag changes are recorded wherever a tag is added or removed through the app, which includes workflow automations and the public newsletter signup form. Nobody is signed in for those, so they appear with **no author name** against them. Bulk CSV imports write tag links directly and produce no entry at all. *** ## What never appears **Profile field edits are deliberately absent.** Somebody changing a member's email address or town writes nothing to Activity. Those belong in the [Activity Log](/docs/platform/logs), which stores the old value beside the new one, and they are reachable from the **Logs** tab on the same profile. Also absent, and not planned for this feed: fees and any payment that is not a donation, event registrations, emails sent or received, logins, e-documents, roles, permission changes, custom field changes and badges. Payments have the [Payments tab](/docs/platform/users), emails have the [email log](/docs/platform/emails/email-log), and everything else with an audit trail is in Logs. *** ## Notes ### Writing one Type into the composer at the top of the tab, or the Notes card on a contact, and press **Add note**. A note is capped at **512 characters**, and an empty or whitespace-only note is refused. The optional **Action** select marks what the note records: **Called** or **Emailed**. Leave it blank for a plain note. When it is set, the feed shows the action as the entry's label and as a badge on the note itself, so a run of calls is readable at a glance without opening anything. ### Reading, editing and deleting The composer only writes. Everything else happens in the feed: click a note entry and it opens in a modal with the full text, the action badge, the author and the time. Note modal with an amber Called badge beside the Note heading, three lines of note text about a conference bursary, the author Julian Sorensen with their avatar, the timestamp 07 Aug 2026 15:23, and Edit and Delete buttons **Edit** turns the same modal into a form: the text becomes editable and the Action select comes back, so you can add, change or clear the Called or Emailed marker after the fact. The same note modal in edit mode, with the note text in an editable box, the Action select showing Called and outlined as focused, and Cancel and Save buttons **Edit** and **Delete** are offered to the note's **author** and to `ADMIN_TENANT`, and to nobody else. A colleague with the same HR permission can read a note you wrote but cannot change or remove it. Notes that existed before this feature keep their original date and appear in the feed at that point in time. Contact notes carried over from the older single-box field have no author recorded, so only an `ADMIN_TENANT` can edit or delete those. *** ## Opening a form submission Clicking a **Completed form** entry opens the whole submission, read-only. Every field on the form is shown, including the ones the person left blank, so you can see what was asked as well as what was answered. Read-only form answers modal titled Event Feedback Survey, showing a dropdown answer, two unanswered radio groups, a date, and two free-text answers about the round-table format and the event agenda This is a wider audience than the [Forms](/docs/platform/forms) module itself. Anyone who can see the timeline can open the answers, so an HR administrator who has no access to a form at all can still read that form's answers for a member in their own chapter. If a form collects anything you would not show your chapter administrators, do not rely on form permissions to keep it from them. *** ## Filtering and searching The chips above the feed narrow it. They combine, and they all apply at once. | Filter | What it does | | --------------------------------------------- | ----------------------------------------------------------------------------------------------------- | | **Donations**, **Notes**, **Tags**, **Forms** | Type chips. Select any combination; none selected means all four | | **Date** | Three presets only: **Last 7 days**, **Last 30 days**, **This year**. There is no custom range picker | | **Author** | One person from the list of people who appear in this feed, searchable by name | | **Search** | Free text | Filter bar with the Notes and Tags chips highlighted and the Date pill open, offering Last 7 days, Last 30 days and This year as the only options **Search matches note text and form names, and nothing else.** It does not match tag names, donation amounts or author names, so searching for a colleague's name finds notes that mention them rather than notes they wrote. Use the **Author** filter for that. When nothing matches, the feed says so and offers **Clear filters**, which resets every chip at once. Activity feed with the Donations chip selected and a Date filter set to Last 7 days, showing the message No activity matches your filters above a Clear filters button *** ## Reading the feed Entries are grouped under a day heading, in reverse date order, and each row shows its own time under the label. Days with nothing in them are skipped, so a quiet year collapses to a handful of headings. The feed loads **40 entries** at a time. When there are more, a **Load more** button appears at the bottom and adds the next 40 below what you are already looking at. Filters apply to the whole feed, not to the page on screen, so narrowing by type or date searches everything and not only the first 40 rows. *** ## Common questions Two gates, and both have to pass. First, **Enable Profile Notes & Activity** under **Settings** → **Modules** → **Users & Profiles** → **Configuration**. It is off by default, and a tenant administrator has to switch it on once for the whole organisation. Second, your permission over the person you are looking at: `HR_LOCAL` or `FINANCIAL_LOCAL` on their chapter, or `ADMIN_TENANT`. `EVENT_LOCAL`, `COMMUNICATION_LOCAL` and `ADMIN_LOCAL` on their own are not enough. Do not use the **Logs** tab as a guide. That one asks for `ADMIN_TENANT` and nothing else, so seeing Logs but not Activity means the setting is off, and seeing Activity but not Logs is entirely normal for a chapter administrator. Expected for several kinds of entry. Donations and form submissions never have one, because they record something the person did rather than a change somebody made. Tag changes have one only when a signed-in person made them. A workflow automation adding a tag, or someone subscribing through the public newsletter form, has nobody signed in to attribute the change to, so the entry lands with the tag name and the time but no author. Contact notes carried over from the older single-box notes field also show without an author, and those can only be edited or deleted by an `ADMIN_TENANT`. That is how it works, not a fault. The tab appears on every profile you hold HR or Financial permission over, and your own profile is one of them. The setting's help text claims the feature is never visible to the member themselves. That holds for ordinary members, who have no HR or Financial permission and get no tab. It does not hold for staff. Brief your team on that before you switch the feature on, and keep anything sensitive about a colleague out of the notes field. Deleting a note leaves a **Note removed** entry in its place, with the time and the person who removed it, but no text: the text is gone rather than hidden, and the row does not open. The deletion is also written to the [Activity Log](/docs/platform/logs) as a **remove** action, so a tenant administrator can see it there alongside everything else that happened that day. Neither record brings the text back, so treat deletion as final. *** ## Related * [Members](/docs/platform/users) - the profile the Activity tab sits on * [Contacts](/docs/platform/contacts) - the same notes and feed on a contact record * [Activity Log](/docs/platform/logs) - profile field edits, with before and after values * [Permissions](/docs/platform/permissions) - the HR and Financial permissions named here * [Forms](/docs/platform/forms) - the module that owns the submissions this feed links to * [Donations](/docs/platform/fees/donations) - where the donation entries come from # Profile Fields Source: https://orgo.space/docs/platform/users/profile-fields Choose which fields appear on member profiles, in which order, and which ones members must fill in The profile form decides what a member profile contains: which built-in fields are switched on, which of your [custom fields](/docs/platform/users/custom-fields) go with them, what order they appear in, and which ones a member has to complete before they can use the platform. It is separate from the [registration form](/docs/platform/users/registration-form), so you can ask for very little at sign-up and build the profile out later. Profile Form builder with an Available Fields panel split into System Fields and Custom Fields, and a Profile Fields panel listing the chosen fields with Required checkboxes *** ## How to access **Settings** → **Users & Profiles** → **Profile Form**. Requires `ADMIN_TENANT`. *** ## Building the form **Available Fields** has two tabs: **System Fields** (Orgo's built-in profile columns) and **Custom Fields** (the ones you created). The Custom Fields tab is disabled until you have at least one custom field. Click a field or drag it across to add it. Fields already in the form are greyed out and marked **in form**. Drag rows in the right panel to reorder. The order you set is the order members see, with built-in and custom fields interleaved however you arrange them. Tick **Required** on any row. Custom field rows also offer **Immutable**. Nothing is stored until you press **Save** at the top right. Removing a field with the **X** takes it off the form. It does not delete data already collected: values stay in the database and reappear if you add the field back. *** ## Built-in fields you can add | Group | Fields | | ------------ | ----------------------------------------------------------------------------------------- | | Identity | First Name, Last Name, Date of birth, Gender, Bio | | Location | Town born, Town current, Location on members map, Address, Postal code | | Contact | Phone number, Website | | Social | Signal, Bluesky, Facebook, Twitter, LinkedIn, Instagram, Telegram, TikTok | | Profession | Profession headline, Profession industry, Profession sector | | Organisation | Current company/organization name, website, and role | | Billing | Company legal name, Company identifier, Company address, Company commerce registry number | Profile picture is not on this list. It is always available and is not configurable here. The profession, organisation, and billing fields do not render on the **Profile** tab. They appear on a separate **Profession** tab on the member's profile, and only when the Professions module is active. Profession headline is the exception: with Professions switched off it renders inline on the Profile tab instead. *** ## Required fields and the completion screen Marking a field **Required** does more than star it on the form. On their next page load, any member with an empty required field is redirected to a completion screen at `/hello-member` and cannot navigate away until they fill it in. That screen is shared with the other things Orgo asks a member to settle on first sight: profile, privacy, notifications, timezone, groups, and unsigned e-documents. Only the steps that actually apply are shown. Two exceptions are worth knowing: * **Admin-only custom fields are never required of members.** If a custom field's visibility is Admin, it is skipped when checking whether the member's profile is complete. * **Not every built-in field can enforce itself.** The completion check only recognises first name, last name, date of birth, gender, phone number, address, town born, town current, and the Facebook, Twitter, LinkedIn, Instagram, Telegram, and TikTok fields. Marking any other built-in field required (bio, postal code, website, map location, Signal, Bluesky, or any profession, organisation, or billing field) shows it as required on the form but does not trigger the completion screen. Required custom fields are always enforced. A custom field counts as filled when it has any value, or, for file fields, an uploaded file. Requiring a field is the fastest way to backfill data from existing members: you do not have to email anyone, they are asked the next time they open Orgo. Keep the list short, though, because every required field stands between the member and the thing they logged in to do. *** ## Immutable custom fields **Immutable** is available on custom field rows only. Once the field has a value for a member, it becomes read-only on the profile form. Immutable locks the field for everyone editing through the profile form, administrators included. It is a form-level lock, so it does not block changes made through an import or the API. Use it for values that should be entered once, such as a licence number or an externally issued member ID, and expect to correct mistakes outside the profile screen. *** ## Profile completion percentage When **Profile Completion Enabled** is on (**Settings** → **Users & Profiles** → **Configuration**, on by default), members see a completion ring in the header and sidebar with the fields they are still missing. The percentage is calculated over profile picture and email, which always count, plus first name, last name, date of birth, gender, and town current when those are on the profile form, plus one combined "social profile" item when any social field is on the form. Having any single social link filled satisfies that item. Fields that are not on your profile form are not counted against members. *** ## Registration form compared with the profile form | | Registration form | Profile form | | ------------------ | ----------------------------- | ----------------------------------------- | | When it is asked | During sign-up | After login, on the member's profile | | Effect of Required | Blocks the sign-up submission | Sends the member to the completion screen | | Immutable option | Not available | Available for custom fields | | Ordering | Fixed list of toggles | Drag and drop, custom fields interleaved | A field can sit on both with different settings. Phone can be optional at registration and required on the profile, so new members can skip it while signing up and get asked for it on their next visit. *** ## Common scenarios Create the [custom field](/docs/platform/users/custom-fields), add it to the profile form, tick **Required**, and save. Members are prompted the next time they open Orgo. Check it against the enforced list above. Several built-in fields, including bio, postal code, website, and everything on the Profession tab, display as required but do not drive the completion screen. Use a custom field if you need enforcement. The profile form will not let you change it, and that applies to administrators too. Untick **Immutable**, correct the value, then tick it again. Add it back and save. The values members had already entered were never deleted, so they show up again. *** ## Related * [Custom Fields](/docs/platform/users/custom-fields) for creating the fields this form offers * [Registration Form](/docs/platform/users/registration-form) for what is asked at sign-up * [Privacy Settings](/docs/platform/users/privacy-settings) for who can see profile data * [Adhesion](/docs/platform/users/adhesion) for the membership application form * [Permissions](/docs/platform/permissions) for what `ADMIN_TENANT` covers # Referral Program Source: https://orgo.space/docs/platform/users/referral Require existing members to vouch for a new signup before their account is activated The Referral Program is a vouching gate on new registrations. Someone signs up normally, then has to collect a set number of vouches from existing members before their account is activated. Each voucher answers three questions you write, and those answers stay on the new member's profile. **Built for** membership organisations that admit people on the word of existing members: professional networks, associations with sponsorship rules, alumni bodies. **Replaces** the email thread where two board members confirm they know the applicant. This is not the same feature as [Invitations](/docs/platform/users/invitations). Invitations are an existing member reaching out to someone new. The referral program is other members vouching for someone who has already registered. They are configured on the same settings page but work independently. *** ## Setting it up **Settings** → **Users & Profiles** → **Referral Program**. Requires ADMIN\_TENANT. Referral Program settings with the Enable Referral Program switch, the Enable User Invitations switch, the Number of Referrals Needed for Signup selector and three referral question fields | Setting | What it does | | ----------------------------------------- | ------------------------------------------------------------------------------------------------------------- | | **Enable Referral Program** | Turns vouching on and adds the referral cards to member profiles. | | **Number of Referrals Needed for Signup** | **None**, or a number from 1 to 10. This is the gate: **None** means nobody is held for vouching. | | **Referral Questions** (1, 2, 3) | The three free-text questions every voucher answers. All three are required before the settings can be saved. | Both switches have to be considered together: the program only holds new signups when **Enable Referral Program** is on **and** the number is 1 or more. With the number left at None, the program is on but nothing is gated. Write questions that ask for something concrete, for example "How long have you known this person?", "In what capacity have you worked with them?", "Why should they be a member?". The answers are stored verbatim and are visible on the profile, so they double as your admission record. *** ## What happens to a new signup Registration itself is unchanged: your normal registration form, the usual email confirmation code. Once the email is confirmed, their status becomes **Awaiting referral** and a referral record with a unique link is created for them. They cannot sign in while they are in this state. An email tells them how many referrals they need and gives them a link of the form `https:///refer/`. The confirmation screen shows the same link with a copy button and the message that they need referrals from N members of your community. Anyone signed in who opens that link sees the applicant's name, answers your three questions and submits. One member can only vouch once for the same applicant. When the number of vouches reaches the configured number, the account is activated, or set to Unapproved if **Manual Approval** is on. The applicant is emailed that they can proceed, and administrators are emailed too. Every single vouch, not just the last one, emails all tenant administrators with the applicant's name, the voucher's name and the progress so far, for example 2 of 3\. That email is controlled by **Settings** → **Emails & Notifications** → **System Emails** → **Referral Notifications**, which also covers the applicant's own referral emails. Someone whose account is awaiting referral cannot log in. Attempting to sign in returns them to their referral link rather than the dashboard. Plan for applicants sitting in this state for as long as it takes their contacts to respond. *** ## Who can vouch | Route | Who | Where | | ----------------------------- | ----------------------------------------------------------------------------------- | ---------------------------------- | | The applicant's referral link | Any signed-in member of your organisation | `/refer/` | | Vouch on someone's behalf | Members with HR\_LOCAL on the applicant's local center, whose own account is active | **Referrals** tab on their profile | The profile route also lists the ten most recent people awaiting referral as shortcut buttons, and has a member search restricted to applicants awaiting referral, so staff can work through the queue without collecting links. Vouching is not anonymous. Each vouch is stored with the voucher's name and their three answers, and appears on both profiles: under **Referred by** on the applicant's Referrals tab and under **Referrals given** on the voucher's. There is no rating, score or approval step on a vouch: submitting one counts. *** ## Members you add yourself are exempt The gate only applies to self-signup. A member created by a signed-in administrator keeps the status you configured for admin-created users and gets no referral record, so you can always add people directly. Imported members are not gated either. Completion is checked when a vouch is submitted and compares the count against the current requirement exactly. Lowering the requirement afterwards does not release people who already have more vouches than the new number. If you change the number while applicants are mid-flow, activate the affected people from the member directory by setting their status to Active. *** ## Seeing referral activity On a member's **Referrals** tab: * **Referred by** shows every vouch that member received, with the voucher and the full answers. * **Referrals given** shows every applicant that member vouched for, with the same answers. Organisation-wide, the statistics page carries a **Referrers** leaderboard ranking members by completed referrals over 7 days, 30 days or all time, showing the top 20 with an option to expand to 50. That card is driven by the invitation link mechanism and appears when **Enable User Invitations** is on. A local center analytics page shows the same card for its own members. If the Gamification module is running with tiers, completing a referral awards points to the member who referred the newcomer through an invitation link. The amount comes from your gamification point rules and defaults to 100. *** ## Common scenarios There is no partial mode: while the requirement is 1 or more, applicants cannot sign in until they reach it. If you want new people to have access immediately and be reviewed afterwards, leave the requirement at None and use **Manual Approval** or [Adhesion](/docs/platform/users/adhesion) instead. The link is stable and can be regenerated by attempting to sign in: the login response returns them to their referral page. Administrators can also find the applicant in the member directory by filtering status to Awaiting referral, and vouch for them directly from the Referrals tab if they hold HR\_LOCAL. Filter the member directory by the Awaiting referral status to see the backlog. Staff with HR\_LOCAL can clear it from the Referrals tab, and any member can still be activated directly by changing their status to Active, which bypasses the gate. A second vouch from the same member for the same applicant is rejected, so the backlog cannot be cleared by one person vouching repeatedly. No. They are shown on the applicant's profile and on the voucher's profile to anyone who can see those tabs. Do not ask for anything you would not want the applicant to read. *** ## Related * [Invitations](/docs/platform/users/invitations) - members bringing in new people by email or link * [User Statuses](/docs/platform/users/statuses) - what Awaiting referral and Unapproved block * [Registration Form](/docs/platform/users/registration-form) - the signup that precedes vouching * [Adhesion](/docs/platform/users/adhesion) - a formal application instead of vouching * [Permissions](/docs/platform/permissions) - what HR\_LOCAL and ADMIN\_TENANT cover # Registration Form Source: https://orgo.space/docs/platform/users/registration-form Design what new members fill out when joining your organization The registration form decides what a new person fills in before they have an account. Orgo gives you one **General Registration Form** at `/register`, plus an optional form per [user type](/docs/platform/users/user-types) at `/join/`. **Built for** any organization that lets people sign up themselves, and for organizations that need to ask different questions of different kinds of member. **Replaces** a website form plus a spreadsheet plus manual account creation. Self-registration is one of four ways somebody gets an account. To create one yourself, invite a specific person, or import a spreadsheet, see [Adding Members](/docs/platform/users/adding-members). Registration form builder: System Fields and Custom Fields tabs, ordered form fields with Required checkboxes, and the Form Settings card *** ## Where it lives **Settings** → **Users & Profiles** → **Registration Form**. Requires `ADMIN_TENANT`. The entry appears only when **Enable Registration Form** is on (**Settings** → **Users & Profiles** → **Configuration** → Registration & Membership). While it is off, self-registration is refused with "Registration is not possible." and the Register link disappears from the login page. [Invitation](/docs/platform/users/invitations) links are the exception: a valid one opens the form as normal, so you can close the door to the public and still admit the people you invite. Registration Forms page showing a table of forms with slug, status, URL and Iframe copy buttons and Configure actions, and the Floating and Side Panel layout choices below it The table lists the General Registration Form first (tagged **Default**, always active), then one row per user type showing **Active**, **Inactive**, or **Not configured**. **URL** and **Iframe** copy buttons appear once the type has a slug; without one the row reads "Set slug first". *** ## Registration page layout | Layout | What it looks like | | -------------- | -------------------------------------------------- | | **Floating** | Centered card on a background | | **Side Panel** | Image on the left, form on the right (the default) | The side image is the login background image set in [Branding](/docs/platform/organisation/branding). Phones and iframe embeds always render the centered layout regardless of this setting. *** ## Building a form Two panels: **Available Fields** on the left with a **System Fields** and a **Custom Fields** tab, **Form Fields** on the right. Click or drag a field to add it, drag the handle to reorder, tick **Required**, and use the X to remove it. **Email is permanent**: always in the form, always required, never removable or optional, and the login identifier. ### System fields | Field | Notes | | --------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | | **Email** | Always present and required | | **First Name**, **Last Name** | Rendered side by side on the public page | | **Birthday** | Day, month and year selectors | | **Gender** | Female, Male, Other | | **Phone number** | Country prefix plus number, normalized to international format on save | | **Address**, **Postal code** | Free text | | **Town current**, **Town born** | Searchable town lookup; if empty, both are filled from the chosen chapter | | **Chapter** | Searchable chapter (local center) selector | | **User Types** | General form only. Lets the applicant pick their own type | | **Fee level** | Membership price selector. Appears only if a membership fee product is configured | | **Profession headline**, **Profession industry**, **Current organization**, **Current role** | Professional profile | | **Company identifier**, **Company name**, **Company address**, **Company registry number** | Company details on the member record. For Romanian organizations the identifier gets a **Search** button that looks the company up | | **Website**, **Facebook**, **Twitter**, **LinkedIn**, **Instagram**, **Telegram**, **TikTok** | Links on the member profile | These are the default labels. Rename vocabulary in [Labels](/docs/platform/customization/labels) and both the builder and the public form show your wording, from the same catalogue. **Signal** and **Bluesky** appear in the builder's field list but are not rendered by either public registration page. Adding them has no effect. Collect those handles with a [custom field](/docs/platform/users/custom-fields) instead. Some older forms contain fields the builder no longer offers, such as a members-map location pin or a personal identification number. They keep working on `/register` if they were already enabled, but you cannot add them to a new form. Use a [custom field](/docs/platform/users/custom-fields) for identification numbers, which also lets you encrypt the value. ### Custom fields Every profile [custom field](/docs/platform/users/custom-fields) is on the **Custom Fields** tab and can sit anywhere in the order, including between system fields. Two exclusions: file-upload custom fields cannot be used on a registration form, and admin-only custom fields never reach the public page. ### Form settings | Setting | What it does | | --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Company registration form** | Adds a Company Details block (company name, legal name, registration number, VAT number, address, website, town) and creates a company alongside the member account | | **Title** | Heading above the form. Leave empty for the default | | **Text displayed above the form** | Intro text | | **Text displayed below the form** | Text between the last field and the submit button | | **Default Membership Fee Price** | User type forms only. Preselects a membership price; the applicant can still choose another | Registration form builder for a single user type, with the Active switch and the Copy URL and Iframe buttons in the header, and the Title, intro texts and Default Membership Fee Price selector in Form Settings Consent checkboxes are added automatically and are required when the matching link is filled in on your [organisation profile](/docs/platform/organisation/organisation-info): GDPR policy, terms of service, and internal rules. *** ## Publishing and embedding | Form | Public URL | | --------- | ------------------------------------- | | General | `https:///register` | | User type | `https:///join/` | Set the slug on the user type itself (**Roles & User types** → edit the type → **URL Slug**). Use the **Copy URL** and **Iframe** buttons to grab either address. ```html theme={null} ``` `iframe=1` strips the logo and outer chrome. `workspace=` names the organization, which matters when you embed on your own domain. `lang=` forces the interface language: `bg`, `cs`, `de`, `en`, `es`, `et`, `fr`, `it`, `lt`, `nl`, `pr`, `ro`, `sk`, `ua`. *** ## What happens after someone submits A hidden field must stay empty and the form must take at least three seconds to fill in. Failing either returns "Invalid submission detected". No password is asked for. Orgo generates one and requires the member to set their own at first login. A six digit code is emailed, valid for five minutes. In this order: eligible for the [waitlist](/docs/platform/users/waitlist) becomes **Waiting list** with a queue position; a [referral program](/docs/platform/users/referral) requiring referrals becomes **Awaiting referral** with a personal referral link; **Manual Approval** on becomes **Unapproved**; otherwise **Active**. Organization admins and the member's chapter admins are emailed about the new registration. At Active, the welcome message goes out if **Send Welcome Message** is on. An Active member is signed in immediately. Anything else lands on a status screen explaining what happens next. Side panel registration page: photo left, form right with email, name, phone, date of birth, gender, town, chapter and two custom fields *** ## Settings that change registration Found under **Settings** → **Users & Profiles** → **Configuration**. | Setting | Effect | | ------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Enable Registration Form** | Off blocks all self-registration and hides the Register link. [Invitation](/docs/platform/users/invitations) links still open the form | | **Manual Approval** | New members land in Unapproved after verifying their email, and wait for an admin | | **Default User Type After Registration** | Stamps this user type on every account created through a registration route, and overrides any type chosen on the form or implied by a `/join` slug. See the troubleshooting entry below before setting it | | **Send Welcome Message** | Sends the welcome email the moment a member becomes Active | | **Notify Admins of New Registrations** | Listed here, but the admin notification currently goes out for every new registration regardless of this switch | | **Default Status for Admin-Created Users** | Applies to members an admin creates, not to self-registration | The registration form has no age gate. Birthday is collected as data only. The minimum-age value is used only when a parent registers a child from inside the app, where a child below the threshold is flagged as underage on their waitlist entry, and the parent's action is recorded as the consent. That value is not editable in the settings screens today. *** ## Troubleshooting **Enable Registration Form** is off. Turn it on to reopen self-registration, or leave it off and [invite](/docs/platform/users/invitations) the people you want: a valid invitation link opens the same page and is not refused. Three causes: the user type form has never been saved, its **Active** switch is off, or the slug in the URL does not match a user type. Check the row's status on the Registration Forms page. The user type has no **URL Slug**. Open **Roles & User types**, edit the type, and set one. Orgo refuses to save a user type registration form while the type has no slug. That email already has an account in this organization. The form offers a **Sign in here** link unless that account is inactive, suspended, excluded, or deleted. Emails are per organization, so one address can belong to several. Correct: the form applies only to new sign-ups. To collect something from existing members, use the [profile form](/docs/platform/users/profile-fields) instead. **Default User Type After Registration** is applied last and wins. It is applied after the type the applicant picked in the **User Types** field, after the type implied by a `/join/` form, and after the type an administrator chose while creating a member by hand. Whatever any of those said, the finished profile carries the default. The clue that this is what happened: the member still holds the *role* for the type they signed up under, visible on their Roles tab, while the **User type** on their profile shows the default. The role was granted at sign-up and never touched. Clear the setting if you use per-type forms or let applicants pick their own type. A default only makes sense when there is exactly one answer for everyone, which is precisely the case where the form does not ask. **Required** on a registration form is enforced by the browser. That is enough for someone filling the form on your registration page, and it is not enforced anywhere else, so an account created by any other route arrives without those answers: * A member an administrator creates with **Register member** from the directory * Anyone loaded through [Import](/docs/platform/customization/import) * A child registered by their parent from inside the app None of these pass through the form, so none of them are asked. People arriving through an [invitation](/docs/platform/users/invitations) link are the exception: they do fill in this form, so their required fields are collected normally. If a field must genuinely be present on every profile, put it on the [profile form](/docs/platform/users/profile-fields) and mark it required there: that one is re-checked on every visit and members are redirected until it is filled in. A separate cause for the public form specifically: custom fields set to **User** or **Admin** visibility render on the page and are then discarded, whether or not they are marked required. Only Public custom fields survive registration. See [Custom Fields](/docs/platform/users/custom-fields#where-a-value-actually-saves). Search covers the settings catalogue rather than the page you land on, and a few entries in the catalogue are for controls that are not currently built into the Configuration screen. **Minimum Registration Age** and **Children Auth Restriction Age** are the two you will meet from this page: both are findable in search, both take you to **Users & Profiles** → **Configuration**, and neither has a control there to scroll to. Nothing is broken and nothing is hidden by your permissions. For an age limit on the public form, there is nothing to configure: the form has no age gate at all, as noted above. Collect the birthday and review applications with **Manual Approval**, or gate joining behind [Adhesion](/docs/platform/users/adhesion). **Enable Registration Form** is checked when the account is created, not when the page is served. The `/join/` pages keep loading and keep looking completely normal while the switch is off; the applicant fills everything in, presses submit, and only then is refused with "Registration is not possible." So switching registration off is not a way to take a campaign link down. If you are closing sign-ups for one user type, turn off that form's **Active** switch on the Registration Forms page, which makes the link show "This registration form is not available or has been disabled." before anyone types anything. If you are closing sign-ups altogether, turn off every user type form as well as the master switch, or put people in a queue with the [waitlist](/docs/platform/users/waitlist) instead of turning them away after the fact. *** ## Related * [Adding Members](/docs/platform/users/adding-members): all four routes into the platform compared * [User Types & Roles](/docs/platform/users/user-types): per-type forms, slugs and what a type changes * [Custom Fields](/docs/platform/users/custom-fields): organization-specific questions * [Profile Fields](/docs/platform/users/profile-fields): what members fill in after joining * [Waitlist](/docs/platform/users/waitlist): queueing sign-ups instead of admitting them * [Adhesion](/docs/platform/users/adhesion): formal membership application after registration # Resignation Source: https://orgo.space/docs/platform/users/resignation A member-initiated departure with a mandatory reason and an admin approval step Resignation is a formal departure with a reason attached. A member submits a request, an administrator approves it, and the approval closes out their roles and (usually) sets them to Inactive. Nothing is deleted: the record of who left, when and why stays in the organisation. **Built for** organisations that want to know why people leave. **Replaces** someone quietly going Inactive with no explanation and no record. Resignations list with all, pending and processed filter chips and a table of requests showing date, member, requested by, chapter, stay active and status *** ## Settings Resignation is off by default. | Setting | Where | What it does | | ------------------------------------------------------- | --------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- | | **Enable Resignation Module** | Settings → Users & Profiles → Configuration → Resignation & Membership Termination (`ADMIN_TENANT`) | Shows the Resign button to members and the Resignation requests screen to admins | | **Automatically Inactivate Accounts After Resignation** | Same section, once the module is on | Forces every approved resignation to set the member Inactive. The member's "Close my account" choice disappears from the form and is ignored | | **Resignation Notifications** | Settings → Emails & Notifications → System Emails | Sends the two resignation emails (request to admins, approval to the member). On by default; off keeps the workflow but stops both emails | *** ## What the member does Profile → **Settings & Privacy** → **Close account** → **Resign**. The form opens in place. Resignation form with a resignation reason box, a what would determine you to continue as member box, a Close my account toggle and Submit and Cancel buttons | Field | Required | What it does | | --------------------------------------------------- | ------------------ | ----------------------------------------------------------------------------------------------------------- | | **Resignation reason** | Yes | Free text. The request is rejected without it, in the browser and on the server | | **What would determine you to continue as member?** | No | The retention question, stored on the request and shown to whoever reviews it | | **Close my account** | No, off by default | On, the approval sets the member to Inactive. Off, the resignation is recorded and the account stays Active | When **Automatically Inactivate Accounts After Resignation** is on, the toggle is replaced by a line in red: "This account will be closed after resignation is approved." After **Submit**, the Close account page shows "Your resignation is pending and it will be processed by administration" with a **Cancel resignation** button. The account works normally until an admin acts. A member may have only one pending request at a time. Submitting a second one is refused with "Your current resignation request is pending, we will email you once is processed." Guest accounts do not see the Resign button at all. An administrator with `HR_LOCAL` over the member's local group sees the same form on that member's Close account page, headed "Record the resignation of this member", plus a shortcut with that label on the member's Permissions tab. Use it when somebody resigns by email or in person. *** ## What administrators do The queue is **Resignation requests** in the sidebar under MANAGEMENT, visible to `HR_LOCAL` and above once the module is on. The screen is titled **Resignations**: 30 requests per page, newest first, chips for **All**, **Pending** and **Processed**, and columns for date requested, member, requested by, chapter, StayActive and status. StayActive is hidden when automatic inactivation is on, because the answer never varies. Opening a row shows the reason, the retention answer and an **Exit conclusion** box for the reviewer's note. The exit conclusion is hidden from the resigning member and read-only once approved. **Approve** processes the resignation; **Delete** removes the request entirely and is only offered in the queue to `ADMIN_TENANT`. Resignation request detail showing status, date, member, requested by, stay active, resignation reason, retention answer, exit conclusion box and Approve and Delete buttons | Action | Permission | | --------------------------------------- | ----------------------------------------------------------------------------- | | Submit a resignation for yourself | Any member (not guests) | | Record a resignation for another member | `HR_LOCAL` over that member's local group | | See a request | The member, whoever submitted it, or `HR_LOCAL` over the member's local group | | Approve a request | `HR_LOCAL` over the member's local group | | Delete a request | `ADMIN_TENANT`, or the member themselves, or whoever submitted it | `HR_TENANT` and `ADMIN_TENANT` cover every local group. *** ## What approval actually changes Approval, in one step: * stamps the request as approved, with the approving admin and the date; * sets the member **Inactive** if automatic inactivation is on, otherwise Inactive or Active according to their "Close my account" choice; * sets the member's **user type** to the configured **Guest User Type**; * clears the member's **adhesion** link, if the Adhesion module is on and a guest user type is configured; * **end-dates every open role** the member holds, as of the resignation date; * emails the member the resignation-approved notice. The user type is reassigned on every approval. If your organisation has no **Guest User Type** configured (**Settings** → **Users & Profiles** → **Configuration** → User Types & Roles), approving a resignation leaves the member with no user type at all. Set a guest user type before you turn the module on if user type drives anything in your setup. Nothing is deleted: the profile, the payment history, the event attendance and the ended roles all remain. *** ## Emails | Email | Who gets it | When | | -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- | | Resignation request | `HR_LOCAL` holders in the member's own local group, plus `HR_PARENT_LOCAL` holders in that group or in any group above it in the chapter tree; tenant admins if none of those exist | On submission | | Resignation approved | The resigning member | On approval | Both are governed by **Resignation Notifications** under System Emails. A member asking for their **data to be removed** is making a different request: handle that through [account deletion](/docs/platform/users/deletion-of-account), and read that page first so you can tell them what survives. The two are independent: deletion does not require a resignation, and resigning does not start a deletion. *** ## Common questions While it is pending, the member withdraws it with **Cancel resignation** on their Close account page, or an `ADMIN_TENANT` deletes it from the queue. After approval, set their status back to Active on the Permissions tab and reassign the roles the approval end-dated. The member left "Close my account" off and your organisation does not force automatic inactivation. The resignation is on record and the roles are closed, but the account still works. That is a supported outcome. Nothing expires or auto-approves a request. A member who says the form "did not work" has usually submitted one that is still sitting there. No. Approval is one request at a time, from the detail view. Delete is for invalid or test entries. It notifies nobody, so the member is left thinking they resigned when nothing was recorded. *** ## Related * [User statuses](/docs/platform/users/statuses) - what Inactive blocks, and how to reverse it * [Deletion of account](/docs/platform/users/deletion-of-account) - the separate erasure request * [Adhesion](/docs/platform/users/adhesion) - the joining flow this mirrors * [Permissions](/docs/platform/permissions) - the permissions named on this page * [Troubleshooting member access](/docs/platform/users/troubleshooting-access) - when a departure was not the cause # User Statuses Source: https://orgo.space/docs/platform/users/statuses What each member status blocks, how statuses change, and who can change them Status is the field that decides whether a member can sign in. Only **Active** members can. Every other status stops the login, hides the profile from the member directory and ends the member's role assignments. If someone reports an access problem, status is the first field to check. **Built for** organisations that need lapsed, pending and blocked members to behave differently. **Replaces** the "archived" column in a spreadsheet that nothing actually enforces. The status field is on the **Permissions** tab of a member's edit page (**Members** → open a member → **Edit** → **Permissions**). Status field set to Active at the top of the Permissions tab of a member edit page, beside the Record the resignation of this member button *** ## The statuses Three statuses always exist. The rest are switched on per organisation (see [Turning on the extra statuses](#turning-on-the-extra-statuses)). | Status | Shown in the app as | Can sign in | What it means | | --------------- | ------------------- | ----------- | ------------------------------------------------------------------------------------------------------------------------ | | `ACTIVE` | Active | Yes | The normal state. The only status that permits a login. | | `INACTIVE` | Inactive | No | Lapsed, on a break, or closed their own account. Non-punitive, and reversible. | | `UNAPPROVED` | New request | No | Registered and confirmed their email, waiting for an admin to approve them. Only offered when **Manual Approval** is on. | | `WAITING_LIST` | Waiting list | No | Parked. Used by the registration waitlist and for under-age child registrations. | | `SUSPENDED` | Suspended | No | Blocked by an administrator. On by default. | | `EXCLUDED` | Excluded | No | Removed from the organisation. Same effect as Suspended, different wording for your records. | | `UNREACHABLE` | Unreachable | No | For members you have lost contact with. | | `HELPING_HANDS` | Helping hands | No | An organisation-specific label. | | `CONTRIBUTOR` | Contributor | No | An organisation-specific label. | Three more statuses exist but are never chosen by hand: | Status | Set by | | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `UNCONFIRMED_EMAIL` | Registration, until the member verifies their email address. | | `AWAITING_REFERRAL` | The referral programme, while the new member is still collecting the referrals your organisation requires. | | `DELETED` | The Delete account action, and the merge tool on the record that is merged away. See [Deletion of account](/docs/platform/users/deletion-of-account) and [Merging duplicates](/docs/platform/users/merging-duplicates). | Only **Active** permits a sign-in. Inactive, Waiting list, Excluded, Unreachable, Helping hands and Contributor all block it, exactly as Suspended does. If you use one of the descriptive statuses as a filing label on a member who still needs to sign in, they will be locked out. *** ## What a status change actually does | Effect | Detail | | -------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | | Open sessions are cut | Moving a member to Inactive, Suspended, Excluded or Deleted signs them out at once rather than letting the session run to expiry | | Role assignments are end-dated | Any move away from Active end-dates every open role. The rows stay in the history with a closed date; they are not deleted | | They leave the member directory | The directory lists Active members by default, and a non-Active profile page is refused for everyone except an admin with HR access over their local group | | Moving back to Active restores the basics, not the roles | Their user-type role and local group follows come back; roles that the earlier change end-dated do not, so reassign them on the Roles tab | The date of the most recent change is stored on the member automatically, so "when did this member go inactive" is answerable without an audit trail. *** ## Who can change a status Status is edited through the admin edit endpoint, which requires `HR_LOCAL` over that member's local group; `HR_TENANT` and `ADMIN_TENANT` cover every local group. Turning off **Allow Local Admins to Modify User Permissions** (**Settings** → **Users & Profiles** → **Configuration**) leaves only `HR_TENANT` and `ADMIN_TENANT`, and local admins are refused with "Only tenant administrators can modify user status." Members have one self-service route: **Close account** on their **Settings & Privacy** → **Close account** page sets them to Inactive. See [Deletion of account](/docs/platform/users/deletion-of-account). *** ## Where a new member's status comes from Self-registration creates the account as **Unconfirmed email**; once the member clicks the verification code or link it becomes, in this order, **Waiting list** if the [registration waitlist](/docs/platform/users/waitlist) is on and they chose a local center, else **Awaiting referral** if the referral programme requires referrals, else **New request** (`UNAPPROVED`) if **Manual Approval** is on, else **Active**. Accounts created by an administrator use **Default Status for Admin-Created Users** instead, which offers Active, Inactive, Unapproved, Waiting list, Suspended and Excluded. These settings all live under **Settings** → **Users & Profiles** → **Configuration**: | Setting | What it does | | ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------- | | **Manual Approval** | New registrations land on New request instead of Active, and the New request option appears in the status dropdown. | | **Default Status for Admin-Created Users** | Status given to members an admin registers. Defaults to Active. | | **Send Welcome Message** | Sends the welcome email whenever a member's status becomes Active, not only at registration. On by default. | | **Notify Admins of New Registrations** | Emails admins for each new registration. | | **Notify Admins on Account Deactivation** | Emails admins when a member closes their own account. Off by default. | | **Allow Account Reactivation** | Lets an Inactive member ask to come back from the login screen. On by default. See below. | *** ## Approving new members With **Manual Approval** on, the member directory grows a **New requests** button showing the count awaiting approval. Each row has two inline actions, **Approve** (sets Active) and **Add to waiting list** (parks them on Waiting list), both needing the same permission as any other status change. If you want an application process with a form, documents and a review record rather than a plain approve or reject, use [Adhesion](/docs/platform/users/adhesion) instead. New request is a gate, not a workflow. *** ## Reactivation from the login screen With **Allow Account Reactivation** on (the default), an Inactive member who tries to sign in is offered a reactivation prompt instead of a flat refusal. Accepting puts them on **New request** and emails your administrators, who approve them like any other pending member: deliberately the same review a new registration gets, not a jump back to Active. With the setting off, they are told to contact support and an administrator changes the status by hand. *** ## Turning on the extra statuses Waiting list, Excluded, Unreachable, Helping hands and Contributor are off by default, switched on under **Settings** → **All Modules** → **Extra User Statuses** (`ADMIN_TENANT`). Suspended is on out of the box. Only the statuses you switch on appear in the status dropdown and in the member directory's status filter. The **Statuses** screen under Settings → Contacts is a different feature. Those are contact statuses (your own labels for people in the CRM, with a colour and an ordering) and they do not apply to members. See [Contacts](/docs/platform/contacts). *** ## Common questions For access, nothing: both block the login and cut open sessions. The difference is what they mean and what they allow next. Inactive is where a member lands by lapsing or by closing their own account. It is the only status the reactivation prompt works with, so it is the one to use when you expect the person back. Suspended is an administrator blocking someone, and the only way out of it is an administrator changing the status by hand. Use Excluded rather than Suspended when the departure is permanent and you want your records to say so. The access effect is identical. No profile data is removed by an ordinary status change. Role assignments are the exception: every open role is end-dated, and the rows stay in the member's history with a closed date rather than disappearing. Reinstating someone does not reopen them, so check the Roles tab after any reinstatement. Deletion is the one status that does remove things. See [Deletion of account](/docs/platform/users/deletion-of-account) for exactly what it clears. Expected: a non-Active profile is only reachable by an admin with HR access over their local group. Ordinary members get a refusal, which is usually what an exclusion is meant to achieve. If an **Active** member's profile is unreachable, that is privacy rather than status, see [Privacy settings](/docs/platform/users/privacy-settings). Only Inactive, Suspended, Excluded and Deleted cut open sessions immediately. Waiting list, Unreachable, Helping hands, Contributor and New request block the next sign-in but leave the current session running until its token expires. So the descriptive statuses are filing labels with a delayed effect, not an eject button. If you need someone out now, use Suspended or Inactive. That message comes from **Allow Local Admins to Modify User Permissions** being off, under **Settings** → **Users & Profiles** → **Configuration**. With it off, only `HR_TENANT` and `ADMIN_TENANT` can change any status, including approving new registrations and parking someone on the waiting list. Either turn the setting back on, or handle status changes centrally. There is no middle setting that allows approvals but blocks other status changes. A different message ("Access Denied") usually means the admin lacks `HR_LOCAL` over that member's local group, which is a separate check that applies even when the setting is on. The dropdown is built from what your organization has switched on. * Waiting list, Suspended, Excluded, Unreachable, Helping hands and Contributor each appear only when that status is enabled under **Settings** → **All Modules** → **Extra User Statuses**. Suspended is on out of the box, the rest are not. * **New request** appears only while **Manual Approval** is on. * Awaiting referral and Deleted are never offered: the referral programme and the Delete account action set them. * Unconfirmed email appears only while the member is already in it. Once you move them to something else you cannot put them back; resend the verification instead. **Send Welcome Message** fires on every transition into Active, not only at registration, and it is on by default. Reinstating a lapsed member, approving a New request and bulk-activating an imported list all trigger it. Turn it off under **Settings** → **Users & Profiles** → **Configuration** before a bulk reactivation, then turn it back on. Then status is not the cause. The sign-in refusal names the status it rejected, so an Active member being refused means the block is somewhere else: an unset password, an unverified email address, multi-factor authentication, or a gate the app applies after the login succeeds. Work through [Troubleshooting member access](/docs/platform/users/troubleshooting-access). Closing sets them to Inactive and signs them out at once. Their profile data, history and role records stay, with the roles end-dated. If **Allow Account Reactivation** is on, they can start the return themselves from the login screen: accepting the prompt moves them to **New request** and emails your administrators, who approve them like any other pending member. Those admin emails are the local center's admins when local centers are active, and your tenant admins otherwise, and they are silenced along with the rest of **New Member Admin Notification** if you have that system email switched off. **Notify Admins on Account Deactivation** only covers closures a member performs themselves. Setting someone to Inactive from the admin side does not send it, on the assumption that the admin doing it already knows. *** ## Related * [Troubleshooting member access](/docs/platform/users/troubleshooting-access) - what to check when a login fails * [Resignation](/docs/platform/users/resignation) - formal departure with a reason on record * [Deletion of account](/docs/platform/users/deletion-of-account) - what deletion removes and what it keeps * [Registration form](/docs/platform/users/registration-form) - where new members enter the chain * [Permissions](/docs/platform/permissions) - the permissions named on this page # Troubleshooting Member Access Source: https://orgo.space/docs/platform/users/troubleshooting-access What to check, in order, when a member cannot sign in "I cannot get in" almost never means the platform is broken. It usually means the address, the workspace, the status or the sign-in method is not what the member thinks it is. Work through these in order: knowing what you ruled out is what makes an escalation fast to answer. **Built for** whoever answers the "I cannot log in" emails. **Replaces** guessing and resetting passwords at random. *** ## The five-minute pass An account is identified by email plus workspace, so a work address and a personal one are two different accounts. Compare what they typed against the address on their profile. If the same address belongs to more than one organisation on Orgo, the login screen has to pick one. Ask whether they belong to another community; they will not think to mention it. A paid fee does not grant access. Open **Members** → the member → **Edit** → **Permissions** and read **Status**. Only **Active** permits a sign-in, while the fee tab looks perfectly healthy either way. See [User statuses](/docs/platform/users/statuses). Password, one-time code and social sign-in do not fail the same way, and do not even find the same accounts. See below. A stale session shows the symptoms of a broken account, and this rules it out in thirty seconds. *** ## The workspace picker hides some accounts When a member enters their email on the shared login page, Orgo looks up which workspaces that address belongs to. That lookup only returns accounts whose status is Active, Unconfirmed email, New request, Inactive or Awaiting referral. A member whose account is **Suspended, Excluded, on the waiting list or deleted** is therefore not shown their organisation at all. They report "it says my organisation does not exist", which reads like a platform fault and is the status doing its job. Check the status before you believe the message. The lookup also surfaces workspaces where the address is only an event contact rather than a member. Those route to the event app's own code login, not to the member login, and they carry no password. See [the event app](/docs/platform/events/event-app). *** ## The three sign-in methods behave differently | Method | Finds accounts with status | Typical failure | | ------------------------ | -------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Password | Any status, but the status is checked **before** the password | "The email or password you entered is incorrect" therefore means the password really is wrong; a blocked account gets a status message instead, whatever they typed | | One-time code by email | Any status except Deleted; the status check runs when the code is verified | A silent "if this email exists, a code has been sent" with no email arriving means the address is not registered in that workspace | | Google, Microsoft, Apple | Only Active, New request and Awaiting referral | An **Inactive** member is told there is no organisation for this email, and never sees the reactivation prompt they would get with a password | An Inactive member who only ever uses Google sign-in will keep hitting a dead end. Ask them to sign in with the one-time code instead: that path offers the reactivation prompt, or at least reports the real status. A refused social sign-in always finishes on `app.orgo.space`, never on your own address. A member on your custom domain or inside your branded app who picks Google and is turned away will report being thrown onto a different website; that is the refusal, not a separate fault. The `auth_error` value in the address bar there names the real reason, and it is one of the reasons in the table above. Which method the login screen offers first is a setting: **Default to Password Login** (**Settings** → **Users & Profiles** → **Configuration**). Members can always switch to the other one. *** ## What each blocked status tells the member | Status | What they see | | --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | **Unconfirmed email** | "Account not confirmed", with a resend button and a countdown of up to 5 minutes before a new confirmation email can be sent | | **New request** (Unapproved) | An account-not-approved message. Someone with `HR_LOCAL` has to approve them from the member directory. | | **Inactive** | The reactivation prompt, if **Allow Account Reactivation** is on. Accepting it moves them to New request and emails your admins for approval. If the setting is off, they are told to contact support. | | **Suspended** and everything else | "Your account is suspended/inactive, please contact support" | | **Awaiting referral** | They are sent back to the registration flow to finish collecting the referrals your organisation requires | *** ## Password problems **Self-service reset.** The member uses the forgot-password link, receives a code, and sets a new password. It only works for accounts on Active, Inactive, Awaiting referral or Unconfirmed email. A suspended or excluded account is refused. Completing a password reset also moves the account's status: an Unconfirmed or Inactive member who resets their password becomes **Active**, or **New request** if Manual Approval is on, or **Awaiting referral** if the referral programme requires referrals. This is the fastest way to unstick a member who never confirmed their email address. **Admin-initiated reset.** On the member's profile you can send them a password-reset email. It requires `HR_LOCAL` over their local group, works only for the same four statuses, and is throttled to one per minute per member. Each send is written to the audit log against the administrator who sent it. **Members who never had a password.** Anyone created by an invitation, an import, an admin, or by signing in with Google has a randomly generated password they have never seen. They must use the one-time code or a reset. **One password across workspaces.** If the same address is a member of several organisations on Orgo, changing the password changes it in all of them. *** ## One-time code problems The email code path has hard limits. Quote them when a member says the code "does not work": | Limit | Value | | ------------------------------- | ------------------- | | Code validity | 5 minutes | | Wait between requests | 20 seconds | | Requests allowed | 10 in any 5 minutes | | Wrong entries allowed per code | 15 | | Lockout after repeated failures | 10 minutes | A member who has requested several codes is usually typing an older one. Have them use the most recent email, or wait out the lockout rather than requesting again. *** ## Multi-factor authentication When the MFA module is on, everyone with tenant-level admin, HR or finance permissions has MFA forced on and cannot switch it off. Every other member has a switch on their own **Settings & Privacy** → **Multi Factor Authentication** page. The verification code is valid for 5 minutes, and a device that has passed the check stays trusted for 2 days. After that, or on a new browser or device, the member is asked again. "It asked me for a code again" after a couple of days is expected behaviour, not a fault. *** ## Email changes Changing the email address on an account is a two-step verification: a code to the current address, then a code to the new one. Only when both are verified does the address change, and the member is signed out and must sign in with the new address. A member stuck halfway through this still has their old address. If they cannot receive mail at the old address at all, an admin with `ADMIN_LOCAL` over their local group (or `HR_TENANT`) sees a plain address field on the member's Email settings instead of the two-step flow, and can change it directly. *** ## When it is worth reporting Report it, rather than working around it, when: * the same member has the same problem again after it was fixed once; * a member is reactivated, suspended or deleted with no administrator action; * the login page shows an internal error rather than a specific message; * text renders as odd characters instead of apostrophes or quotation marks. Include the address they used, the workspace, the method they tried and what they saw. Those four together are what makes a report reproducible; without them the first reply is always a request for them. *** ## Related * [User statuses](/docs/platform/users/statuses) - what each status permits * [Deletion of account](/docs/platform/users/deletion-of-account) - why a deleted account cannot sign in at all * [Resignation](/docs/platform/users/resignation) - the departure that leaves the account working * [Permissions](/docs/platform/permissions) - the permissions named on this page * [Renewals](/docs/platform/fees/renewals) - when the problem really is the fee # User Types & Roles Source: https://orgo.space/docs/platform/users/user-types Categorize members by type and model your organizational structure with positions User types and roles are the same object in Orgo, separated by one setting called **level**. A role with the level **User type** is a membership category. A role with any other level is a position in your structure. * **User type**: what kind of member someone is (Scout, Student, Honorary Member). One per member. * **Role**: a position they hold (President, Treasurer, Troop Leader). A member can hold several, each with its own term. * **Permission**: what they can do in the software. See [Permissions](/docs/platform/permissions). **Built for** organizations whose members are not interchangeable, either because they pay different fees, see different menus, or fill in different forms. **Replaces** a "category" column in a spreadsheet and a separate document listing who holds which office. Roles list with Level and Permissions filters, and columns for role, plural name, level tag and attached permissions *** ## Where it lives **Settings** → **Users & Profiles** → **Roles & User types**, which requires `ADMIN_TENANT` and appears when **Enable Roles** is on. Every role is listed with its plural name, a **Level** tag and any attached permissions. Filter by **Level** or **Permissions**, open the [organisational chart](/docs/platform/organisational-chart), or press **Add role**. *** ## Creating a role or user type **title** and **Plural title**. The plural, prefilled from the title as you type, is used wherever Orgo lists several holders. One choice only: **None**, **User type**, **Chapter**, **Parent chapter**, **Organisation**, or one of your unit types. Chapter and Parent chapter need local centers enabled, unit types need units enabled, User type needs **Enable User Types** on. Available for every level except User type. Holders gain the ticked permissions and lose them when the role ends. The role is assignable immediately. A user type can never carry permissions. The permissions section is hidden as soon as you set the level to **User type**. If a category also needs access, create a separate role for the position and attach the permissions there. ### Extra settings on a user type | Setting | What it does | | ------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Not eligible for fee** | Never assigned a membership fee, at organization or chapter level | | **Parent** | Marks the type used for parent accounts. Requires **Enable Family Members** | | **Volunteer** | Marks the type used for volunteers. Requires **Enable Volunteer Roles** | | **Select a font color**, **Select a background color** | Colors the type's tag wherever it is displayed | | **URL Slug** | Gives the type its own registration page at `/join/`. A per-type [registration form](/docs/platform/users/registration-form) will not save until the slug is set | Role editor with the level radio group set to User type, and the user type controls below it: Not eligible for fee, Parent, font and background colour, and URL Slug *** ## Assigning a user type A member has exactly one user type; if someone fits two categories, pick the primary and use a role or tag for the other. * **On the member's profile**: edit the member → **roles** tab → the **userType** selector. * **When an admin creates a member**: a user type selector on the create form. * **Automatically on registration**: **Default User Type After Registration** stamps a type on every self-registration. * **From the registration link**: signing up through `/join/` applies that type and the matching role. * **The applicant chooses**: add the **User Types** field to the general registration form. * **On adhesion approval**: approving an [adhesion](/docs/platform/users/adhesion) sets the type configured for successful applications, and emails the member if their type changed. * **Bulk import**: set the type during a member [import](/docs/platform/customization/import). Editing roles on a profile requires `HR_TENANT`, or `HR_LOCAL` over the member's chapter. Local admins can view but not change them unless **Allow Local Admins to Modify User Permissions** is on. *** ## What a user type actually changes * **Fees**: a type flagged **Not eligible for fee**, or the type chosen as fee-exempt, drops the member out of fee assignment entirely. * **Registration**: each type can have its own [registration form](/docs/platform/users/registration-form), public URL and preselected membership price. * **Menu**: categories and items can be shown only to selected types. See [Menu Organizer](/docs/platform/customization/menu-organizer). * **Dashboard**: widgets can carry a different image per user type. See [Dashboard Organizer](/docs/platform/customization/dashboard-organizer). * **Directory**: the member list can be filtered by type, subject to **Who Can Filter Users by Type**. * **Guest accounts**: the type chosen as **Guest User Type** marks its members as guests; approving a resignation switches the member to it. * **Units**: a unit type can require its members to hold a specific user type. *** ## Roles and terms Assign a role from the member's **roles** tab, where each assignment has a **dateBegin** and an optional **dateEnd**. Ending a role ends the permissions it carried, and the assignment stays visible as history. That is why permissions belong on roles rather than people: a handover is one assignment ended and another started. Where each level applies: **Organisation** is the whole organization, **Chapter** one local center, **Parent chapter** a parent local center and every local center beneath it at any depth, a unit type a specific unit or team of that type, and **None** a label with no scope and no permissions. A chapter role attaches to the member's own chapter when assigned. A parent-chapter role attaches to the member's own chapter when that chapter is flagged **It's a parent chapter**, and otherwise to the chapter directly above it, never higher. A member whose chapter is neither a parent nor has one cannot hold a parent-chapter role at all. [Role Groups](/docs/platform/groups/role-groups) can also fill groups from role, age, gender, chapter, region or fee tier with no manual assignment. *** ## Settings reference Under **Settings** → **Users & Profiles** → **Configuration**. | Setting | Options and effect | | ---------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Enable User Types** | Turns the whole concept on. Off hides the level option, the profile selector and every user type filter | | **Enable Roles** | Turns positions on and reveals the Roles & User types screen | | **Enable Volunteer Roles** | Adds the **Volunteer** flag to user types | | **Who Can See User Types** | All Users, HR Local, HR Tenant, Admin Local, Admin Tenant. Controls where the type label shows (member list, member profile, unit member lists); it does not remove the type from exports or the API | | **Who Can Filter Users by Type** | All Users or Admin Tenant. Enforced on the server: filtering by type without the right level is refused | | **Default User Type After Registration** | The type stamped on every new self-registration | | **Guest User Type** | The type that marks someone as a guest rather than a member | *** ## Common questions Add a type when it changes something concrete: a different fee, registration form, menu or report. If it only changes what you call someone, use a tag. A category of member is a user type; a post someone is elected or appointed to is a role with the right level and permissions. Need both, create both: they are separate rows on the same screen. The type has no **URL Slug**, or its registration form is not saved and active. Set the slug on the type, then configure the form under **Registration Form**. *** ## Related * [Permissions](/docs/platform/permissions): what each permission level unlocks * [Registration Form](/docs/platform/users/registration-form): per-type forms and public sign-up links * [Role Groups](/docs/platform/groups/role-groups): groups that fill themselves from roles and member data * [Organizational Chart](/docs/platform/organisational-chart): the structure your roles produce * [Adhesion](/docs/platform/users/adhesion): assigning a type when an application is approved # Waitlist Source: https://orgo.space/docs/platform/users/waitlist Queue new registrations per local center and admit them when there is room The waitlist puts new registrations into a queue attached to the local center they signed up for, instead of letting them straight into the platform. Each person gets a position, a status link they can bookmark, and an email when things change. Chapter staff work the queue and admit people when there is room. **Built for** organisations whose local groups have real capacity limits: scout troops, sports clubs, chapters with a room and a leader-to-member ratio. **Replaces** a spreadsheet of names per branch and the emails asking "where am I on the list?". The waitlist is per local center, and it applies to every new self-registration for a center, not only to overflow. While it is on, someone who registers for a center is queued whether that center is full or not. Their account status becomes **Waiting list** and they cannot sign in until an administrator approves them and sets their status to Active. Organisation administrators are exempt. *** ## Turning it on **Settings** → **Users & Profiles** → **Registration Waitlist**. Requires ADMIN\_TENANT. The entry is in the menu whether or not the waitlist is on, and every setting below lives on that page, starting with the switch that enables it. Registration Waitlist settings with the enable switch, Allow Self Removal, Notify Admins On New, Volunteer Trigger Slots and per user type priority levels | Setting | What it does | | -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Enable Registration Waitlist** | Turns queueing on for new registrations that have a local center. | | **Allow Self Removal** | Intended to let people take themselves off the list. There is no button for it in the interface today, so removals are done by staff from the Waitlist screen. | | **Notify Admins On New** | Emails everyone with HR\_LOCAL in that center whenever someone joins its queue. Off by default. | | **Volunteer Trigger Slots** | When a volunteer's waitlist entry is approved, this many places are added in total to the center's user type capacities, going first to the types furthest below their limit. Leave empty to release nothing. | Below those, **Waitlist Priority Settings** assigns each user type a priority of **Normal**, **High** or **Emergency**, which anyone joining the queue picks up. Saving these requires HR\_TENANT, and **Reset to Default** puts every type back to Normal. **Capacity per local center.** Each center's capacities live in its own **Waitlist Settings** (`/local/settings/waitlist`), reachable with FINANCIAL\_LOCAL: enable the user types the center accepts, give each a **Maximum Capacity**, and the page shows the current count and available spots. Capacity is a planning figure, not a barrier. It drives the "spots available" readouts and the volunteer slot mechanism; it does not stop people joining the queue. *** ## What a new registration experiences Nothing about the form changes, including the local center choice. A registration that does not name a local center is never queued: there is no queue to join, so it follows your normal registration rules instead. This is the moment the entry is created, not the moment they submit the form. Their account status becomes **Waiting list**, the entry goes to the back of that center's queue, and the confirmation screen shows their position and estimated processing date. It repeats the position and estimated wait and links to a status page that needs no login, so it can be bookmarked and shared. For a child registered by a parent, this and every later waitlist email goes to the parent who owns the family instead of to the child. The entry moves to **Approved**, the queue behind them is renumbered, and the person gets an approval email pointing at the dashboard. Approval does not do this for you. Until you change the status from Waiting list to Active in the member directory, the person has an approval email in their inbox and still cannot sign in. This is the single most common complaint the waitlist generates. *** ## Children and the minimum age If your organisation has a minimum registration age and a parent registers a child below it, the entry gets the **Underage** status rather than Waiting: hidden from the waitlist screen unless you filter for it, and not offered to the bulk approve, reject or priority actions, which only act on Waiting entries. Orgo ships a job that promotes those children when they reach the minimum age, flipping the entry to Waiting, giving it a position at the back of the queue and emailing the parent. **That job is not currently scheduled**, so nothing happens automatically on the birthday. Until it is, review the Underage filter yourself and move children into the queue when they become eligible. The minimum age is stored per organisation but there is no control for it in the settings interface at the moment. Ask support to set it if you need it. *** ## What priority actually does Priority does **not** move anyone up the queue. Positions are assigned strictly in order of joining, per local center, and renumbered when entries leave. What it changes is the estimated wait shown to the person, calculated at half the normal estimate for High and 30% of it for Emergency, and the priority filter staff use to decide who to admit first. Priority comes from the person's user type and can be changed for selected entries at any time. One special case: if the person registering a child is an active volunteer anywhere in the organisation, the child's entry is created at High priority regardless of user type. The table does group entries by priority before position, but not in the order you would expect: with priorities mixed, Normal entries come first and Emergency ones last. Use the priority filter to find your urgent cases rather than reading the top of the list. *** ## Working the queue **Waitlist** in the main menu (`/waitlist`) needs ADMIN\_LOCAL to open; the bulk actions themselves check HR\_LOCAL. What you see is scoped to your permissions: ADMIN\_TENANT sees every center, HR\_PARENT\_LOCAL its anchor center and every center beneath it at any depth, ADMIN\_LOCAL or HR\_ASSISTANT\_LOCAL only their own. The bulk actions apply that same scope entry by entry, not once at the door: an entry in a center you do not cover is skipped rather than processed. You will not normally see that happen, because the list is already scoped before you can tick anything. Waitlist screen with local center, status and priority filters, bulk action bar, and a table of entries showing position, local center, user, priority, status, type and requested date Three filters sit at the top: local center, status (defaults to **Waiting**) and priority. Pick a single local center and you also get four tiles, **Total Waiting**, **Processed Today**, **Avg Wait Time** and **High Priority**, plus a capacity bar per user type showing count against capacity and spots left. Total Waiting and Avg Wait Time are calculated from the queue. Processed Today and High Priority currently display 0 whatever the data: use the status and priority filters to count those instead. The table pages 30 at a time: position, local center, the person with a link to their profile, priority, status, type (their user type, or Parent, Volunteer or Parent & Volunteer, with self registered or parent registered underneath) and the request date with days waited. Tick the entries you want, then use the action bar: | Action | Applies to | What happens | | ---------------------- | ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Approve Selected** | Waiting entries | Marks them Approved, stamps who approved and when, renumbers the queue, emails each person, and releases volunteer slots if that is configured. | | **Reject Selected** | Waiting entries | Asks for a rejection reason, which is required, stores it and emails it to the person. | | **Send Notifications** | Any selected entry | Sends a position update email with their current place and how many people are ahead. This is the one action that does not filter to Waiting entries. | | **Change Priority** | Waiting entries | Sets Normal, High or Emergency on the selection. | | **Export CSV** | Any selected entry | Downloads position, first and last name, email, phone, local center, priority, status, requested date, waiting days and estimated processing date, built from the rows on screen rather than fetched from the server. | Every action confirms first, and the counts in the confirmation reflect only the entries the action can actually process. The toast after **Approve Selected** reads "undefined entries approved successfully". The approvals themselves are fine: reload the list, or filter by status Approved, to see the real result. Admitting a group of people end to end: The tiles and the per user type capacity bars only appear once a single center is selected, and they are what tells you how much room you actually have. It is the default. Add the priority filter if you triage by priority, and remember that priority never reorders the queue: positions stay in joining order, so you are choosing to skip people, not being shown a reordered list. Confirm the dialog. Approved entries are stamped with who approved them and when, the queue behind them is renumbered, everyone approved is emailed, and volunteer slots are released if you configured them. In the member directory, not here. See [User Statuses](/docs/platform/users/statuses). *** ## The status page Every waitlist email links to a public status page at `/waitlist/status/`. It needs no login and shows the person's name, local center, queue position, status, estimated wait, priority, when they registered, how many people are ahead and what happens next. Approved and rejected entries show the outcome instead, with the rejection reason if there is one. Estimated wait is a projection from how quickly that center has been processing entries, adjusted for priority, with a buffer. Treat it as an indication, not a promise. *** ## Entry statuses | Status | Meaning | | ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Waiting** | In the queue with a position. | | **Underage** | A child below the minimum registration age. Hidden until you filter for it, and skipped by the approve, reject and priority actions, which only act on Waiting entries. It does hold a position number from when it was created, which is why a position update email to an underage entry quotes a place in a queue it is not really in. | | **Approved** | Admitted by staff. The queue behind them is renumbered. | | **Rejected** | Declined with a stored reason that was emailed to them. | | **Withdrawn** | Taken off the list at their own request. Available through the API; there is no button for it in the interface today. | | **Expired** | Reserved status. Nothing sets it automatically. | *** ## Common scenarios Approval marks the queue entry and emails the person. It does not touch the account, so their status is still Waiting list, and Waiting list blocks the sign-in exactly as Suspended does. Change the status to Active in the member directory. If you approve in batches, make the status change part of the same routine, because nothing in the interface will remind you and the person's own view of it is an approval email followed by a refused login. See [User Statuses](/docs/platform/users/statuses). Work through the four filters that hide people, in this order. 1. **Status.** It defaults to Waiting, so anyone already approved, rejected or withdrawn is out of view. 2. **Underage.** Children below the minimum registration age are only listed when you filter for Underage specifically. 3. **Local center.** The list is scoped by the center filter and by your own permissions: `ADMIN_LOCAL` sees only their own center, `HR_PARENT_LOCAL` its anchor center and every center beneath it at any depth, `ADMIN_TENANT` everything. 4. **Whether they were ever queued.** Someone who registered without choosing a local center is never queued, and neither is anyone with organisation-wide admin rights. Registrations from before you switched the waitlist on are not queued retroactively either. If they are missing from all views, they are a normal member: check the member directory instead. Not from the interface. **Enable Registration Waitlist** is one switch for the whole organisation, and while it is on every registration that names a local center is queued, full center or not. A per-center opt-out does exist in the underlying data, but no screen and no API field writes it, so it is not something you can configure yourself. The practical options are to leave the waitlist off and control intake with **Manual Approval** instead, which reviews everyone without queueing them, or to turn the waitlist on and admit the unconstrained centers' queues promptly so the delay for them stays close to zero. Setting a generous **Maximum Capacity** for those centers does not help: capacity is a planning figure that feeds the readouts, not a gate. Prune it in one pass rather than entry by entry. 1. Sort by the Requested column so the oldest surface first, and use the days-waited figure under each date to decide your cut-off. 2. Select that block and **Export CSV** if you want a record before you change anything. The export is built from the rows currently on screen, so export page by page rather than expecting one file for the whole queue. 3. **Send Notifications** to the same selection. Everyone gets their current position and how many people are ahead, which is usually enough for the people who have moved on to reply or ignore it. 4. **Reject Selected** for the ones you are closing. The reason is required and is emailed to them, so write it for the person reading it, not for your records. Rejected entries stay in the data with their reason and are visible under the Rejected status filter, so this is reversible in the sense that you can see what you did, though the person has to register again. **Notify Admins On New** is off by default, so check that first. When it is on, the email goes to a narrower group than most people expect: active members whose own local center is the center that was joined, and whose permissions include `HR_LOCAL` directly. An admin who covers that center through a role, or a tenant-level admin who is not assigned to the center, is not on the list. The link in that email points at a page that does not exist. Open the queue from **Waitlist** in the main menu instead. They do, whatever the data, because those two tiles are not wired to anything the statistics endpoint returns. **Total Waiting** and **Avg Wait Time** are real. Use the status filter to count what was processed and the priority filter to count High entries. The tiles also need `HR_LOCAL`, so an `ADMIN_LOCAL` without it sees the table but no tiles at all. The **Waitlist Settings** page under local settings always edits the local center of the person opening it, so it needs `FINANCIAL_LOCAL` and a local center on your own account. An administrator with no local center is bounced straight back with "You need to be assigned to a local center", and there is no center picker on that screen: to set capacities for several centers, an admin in each one has to do it. The waitlist queues people per local center with a visible position, an estimated wait, a public status page and its own emails. Manual Approval parks new registrations as Unapproved for review, with no ordering and no capacity view. Use the waitlist when place scarcity is the problem, Manual Approval when vetting is. You can have both on. Queueing wins: a registration that names a local center goes to Waiting list and Manual Approval never sees it, so it is you setting the status to Active after approval that admits them. Manual Approval still governs registrations with no local center, which the waitlist never touches. *** ## Related * [User Statuses](/docs/platform/users/statuses) - Waiting list and the statuses around it * [Registration Form](/docs/platform/users/registration-form) - the signup that feeds the queue * [Local Groups](/docs/platform/groups/local-groups) - the local centers the queue is attached to * [Family Members](/docs/platform/users/family-members) - parents registering children * [Permissions](/docs/platform/permissions) - ADMIN\_LOCAL, HR\_LOCAL and the parent-local levels # Webhooks Source: https://orgo.space/docs/platform/webhooks Push member, payment, registration, contract, role and contact events to your own systems in real time A webhook tells your system that something happened in Orgo the moment it happens. Orgo sends an HTTP POST with the full record to a URL you control, so a CRM, a data warehouse or an automation platform stays current without polling the API. **Built for** teams keeping another system in step with Orgo. **Replaces** scheduled exports and "sync every 15 minutes" scripts. Webhooks page listing subscriptions with their URL, subscribed events, status, success and failure counts, last trigger time and per-row test, logs, edit and delete actions *** ## Where it lives **Settings → Developers → Webhooks** Creating, editing and deleting a subscription requires **ADMIN\_TENANT**. Testing a webhook and reading its delivery logs are available on the same page. *** ## Creating a subscription Create Webhook form with the Active switch, name, endpoint URL, description and the six event type groups A descriptive name: the receiving system, not the event. Must be `https` and must resolve to a public address. A URL that resolves to a private or loopback address is rejected when you save it, and again at delivery time. At least one. They are grouped by family (see below). The play button on the list sends a synthetic `webhook.test` delivery to the URL so you can confirm your endpoint answers before real traffic arrives. *** ## Events you can subscribe to | Group | Events in the UI | | -------------------- | ------------------------------------------------------------------ | | **User** | User Created, User Updated, User Deleted | | **Contact** | Contact Created, Contact Updated, Contact Deleted | | **Payment** | Payment Created, Payment Updated, Payment Deleted | | **Event Attendance** | Registration Created, Registration Updated, Registration Cancelled | | **Contract** | Contract Signed, Contract Updated, Contract Removed | | **Role** | Role Assigned, Role Updated, Role Removed | Eighteen events in total. Each delivery carries the full record as it stands at that moment, and update events also carry the fields that changed. Passwords, tokens and connected-account identifiers are stripped before sending. The exact payload envelope, headers and per-event schemas are in the [Webhooks reference](/docs/api-reference/concepts/webhooks). *** ## Settings reference | Field | What it does | | ------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **active** | Turns delivery on or off without deleting the subscription. An inactive subscription receives nothing. | | **Webhook Name** | Label shown in the list. Required. | | **Endpoint URL** | Where the POST goes. Required, `https`, publicly resolvable. | | **Description** | Free text for your own reference. | | **Event Types** | Which events trigger this webhook. At least one required. | | **Max Retries** | Retry attempts after a failed delivery. 0 to 10, default 3. | | **Timeout (seconds)** | How long Orgo waits for your response. 1 to 300, default 30. | | **Webhook Secret** | Optional. When set, every delivery carries an `X-Webhook-Signature` header: an HMAC-SHA256 of the delivery, keyed with this secret. See [Verifying the signature](#verifying-the-signature). | | **Custom Headers (JSON)** | Extra HTTP headers sent with every delivery, for example an `Authorization` header your endpoint checks. | | **Metadata (JSON)** | Notes stored on the subscription. Never sent with the request. | Secret, custom headers and metadata sit behind **Advanced Options** on the form. *** ## Verifying the signature Set a **Webhook Secret** and every delivery to that subscription carries a signature your endpoint can check, so you can prove the request came from Orgo and not from someone who found your URL. Use a long random string, at least 32 characters, and store it in your own configuration exactly as you typed it here. The header looks like this: ``` X-Webhook-Signature: t=1754413200,v1=<64 lowercase hex characters> X-Webhook-Timestamp: 1754413200 ``` `t` is the moment Orgo signed the delivery, in Unix seconds, and repeats the value in `X-Webhook-Timestamp`. `v1` is an HMAC-SHA256, hex encoded, over the string `t`, a full stop, and the request body exactly as it arrived: ``` v1 = HMAC-SHA256(key = your webhook secret, message = ".") ``` Sign the bytes you received. A body that has been decoded and re-encoded to JSON is a different string, and the signature will not match. Take the value after `t=` and the value after `v1=`. Reject the delivery if the header is missing and you expect one. Concatenate `t`, `.` and the raw body, run HMAC-SHA256 over it with your secret as the key, and hex encode the result. Use your language's constant-time comparison (`hash_equals`, `crypto.timingSafeEqual`, `hmac.compare_digest`), not `==`. Reject the delivery if it differs. Compare `t` against your own clock and refuse anything outside a tolerance you choose, five minutes being the usual figure. Because `t` is inside the signed string, nobody can change it without breaking the signature, which is what makes a captured delivery unusable later. Working receivers in Node and Python are in the [Webhooks reference](/docs/api-reference/concepts/webhooks#authenticating-the-sender). Two things to know before you set a tolerance. Each retry is signed again at the moment it is sent, so a redelivery arrives with a fresh `t` and a different `v1`, and a short window does not cause retries to fail. And because the same delivery can therefore carry different signatures, deduplicate on the payload `id` or on `X-Webhook-Delivery`, never on the signature. The signature format changed in August 2026. Until then the header carried a short non-cryptographic checksum, which could be reproduced by anyone who had seen one delivery. A receiver written against the old value must be updated to the recipe above; the old header is not sent alongside the new one. Deliveries keep arriving either way, so nothing stops working while you migrate, but a receiver still comparing the old value is authenticating nothing. *** ## Delivery and retries Deliveries are queued, not sent inside the request that caused them, so a slow endpoint never slows down the app. * A `2xx` response marks the delivery successful. * Anything else, a timeout or a TLS error counts as a failure and is retried until **Max Retries** is reached. * Retries back off exponentially, starting around 20 seconds and capped at 10 minutes between attempts. * Every attempt is logged, including the ones that eventually succeed. A subscription is never deactivated automatically after repeated failures. Watch the Success / Failed / Total counters on the list, or your own monitoring. Because retries exist, the same event can arrive more than once. Make your handler idempotent by keying on the delivery's `id`. *** ## Delivery logs The list icon on each row opens the delivery log for that subscription. Webhook delivery log table showing status, event type, response code, response time, attempt number, delivery ID and timestamp for recent attempts Each row shows the status (success, failed, pending), the event type, the HTTP response code your endpoint returned, the response time, which attempt it was, the delivery ID and when it was sent. The page loads 50 attempts by default and can show more; the API caps a single request at 500. The delivery ID also travels with the request as `X-Webhook-Delivery`, so a line in your own logs can be matched to a row here. *** ## Troubleshooting The endpoint must use `https`, the hostname must resolve, and it must not point at a private or loopback address. A local tunnel with a public https hostname works; `http://localhost` does not. Check the subscription is **active**, that it is subscribed to the event you expect, and run the test delivery. If the test succeeds but real events do not appear, the action you are testing may not be one of the eighteen events above. The request never completed: DNS, TLS or a timeout. Raise **Timeout (seconds)** if your handler does slow work, or better, acknowledge with `200` first and process afterwards. Expected. Retries and at-least-once delivery mean duplicates happen. Deduplicate on the payload `id`. Three usual causes, in order. Your framework parsed the body before you signed it, so you are hashing re-serialised JSON instead of the bytes that arrived. You hashed the body alone instead of `.`. Or the secret in your configuration is not character for character the one saved on the subscription, which you can settle by saving a new secret in both places at once. If you are checking a receiver written before August 2026, it is comparing the old checksum format and will never match the new header. Poll the relevant endpoint on a schedule, or build the flow in [n8n](/docs/platform/integrations). The event list is fixed. *** ## Related * [Webhooks reference](/docs/api-reference/concepts/webhooks) - payload envelope, headers and event schemas * [Handle webhooks](/docs/api-reference/recipes/handle-webhooks) - a full receiver with idempotency and replay * [API Access](/docs/platform/api) - tokens for pulling data the other way * [Integrations](/docs/platform/integrations) - HubSpot, n8n, analytics and SSO * [OAuth Server](/docs/platform/oauth) - sign-in for your own applications # Workflows Source: https://orgo.space/docs/platform/workflows Automate emails and tagging: pick an event in Orgo, add a delay if you want one, and let the platform do the rest A workflow watches for something happening in your organization (a member registers, a contract is signed, a membership expires) and reacts: send an email, add a tag, remove a tag. You build it on a canvas by dragging a trigger, connecting an action to it, and switching it on. **Built for** onboarding sequences, renewal nudges, and any follow-up you currently send by hand. **Replaces** exporting a list every Monday and pasting it into a mail tool. **Settings → Customization → Workflows** Requires **ADMIN\_TENANT**. Every workflow endpoint, including the trigger and action catalogues the builder loads, checks the tenant admin role server side. Workflows list showing workflow cards with trigger and action counts and an active toggle on each *** ## The list Each card shows the workflow's name, description, trigger and action counts, when it was last saved, and an **Active** / **Inactive** switch you can flip without opening it. Clicking the card opens the builder; the three-dot menu offers: * **View Logs**: every run of that workflow. * **Clone**: a full copy, always created inactive, with " (Copy)" appended to the name. * **Delete**: permanent, and it takes the triggers, conditions and actions with it. *** ## Building a workflow The name sits in the top bar, beside Save. An unnamed workflow saves as "Untitled Workflow". The left sidebar lists every trigger, grouped by category and searchable. Drop one on the canvas and it becomes a **When** node. Drag **Send Email**, **Add Tag** or **Remove Tag** from the sidebar, or click **Add action** on the prompt below a node. Actions become **Then** nodes wired to the trigger above them. Click a node to open its settings, then **Done** to apply. **Save** persists the workflow and the canvas layout. **Test** only becomes available once the workflow is saved and has at least one trigger and one action. Flip the **Active** switch. Activation is refused server side unless the workflow has at least one trigger and at least one action, so a canvas holding only a trigger, or only notes, stays inactive. A **Text Note** can also sit on the canvas: an annotation for whoever edits the workflow next, never executed. Workflow canvas with a trigger node connected to a send email action node, and the trigger and action palette in the left sidebar *** ## Triggers The catalogue, grouped as it appears in the dropdown: | Category | Triggers | | ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | User Events | User Registered, Email Verified, User Status Changed, User Approved, User Activated, User Deactivated, Profile Updated, Profile Completed, User Inactive (X Days), Tag Added, Tag Removed | | Adhesion Events | Adhesion Created, Adhesion Submitted, Adhesion Status Changed, Adhesion Approved, Adhesion Rejected | | Course Events | Course Enrolled, Course Completed, All Onboarding Courses Completed | | Contract Events | Contract Assigned, Contract Signed, Contract Completed, Contract Expiring Soon, Contract Expired | | Membership Events | Membership Payment Success, Membership Payment Failed, Membership Expiring Soon, Membership Expired, Membership Renewed | | Identity Events | Identity Submitted, Identity Validated, Identity Rejected | | Donation Events | Donation Payment Success | | Event Attendance | Event Attendance | Three triggers narrow further with a filter on a specific record: **Donation Payment Success** by donation product, **Event Attendance** by event, and **Tag Added** / **Tag Removed** by tag. An empty selection means "any". The event picker loads up to 500 events alphabetically, so a very large calendar will not offer every event as a filter option. **User Inactive (X Days)** asks for a number of days between 1 and 365. It fires once, on the day a member crosses that threshold, based on the last time their record changed, and is evaluated by a daily job at 06:00 UTC. Person-related triggers can also be restricted **by user type** with checkboxes; all unchecked means every type. Trigger configuration panel with the event type selector set to User Approved and, below it, the Filter by User Type checkboxes for every user type the organization uses *** ## Actions | Action | What it does | | -------------- | -------------------------------------------------------------------------------------------------------- | | **Send Email** | Sends an email you write in the editor, to the person the trigger was about | | **Add Tag** | Adds a tag to the member's profile. You can pick an existing tag or type a new name and create it inline | | **Remove Tag** | Removes a tag from the member's profile | **Send Email** needs a **Subject Line** and **Email Content** in the rich editor; the builder refuses to save without both, as tag actions refuse to save without a tag. These placeholders are replaced per recipient at send time, in the subject line as well as in the body. The **Insert Placeholder** control writes into the body editor only, so type them by hand in the subject. `{{firstName}}` · `{{lastName}}` · `{{fullName}}` · `{{userEmail}}` · `{{userCompanyName}}` · `{{platformLink}}` · `{{profileLink}}` · `{{unsubscribeUrl}}` ### Delays Every action has an optional **Delay**: days, hours (0 to 23), minutes (0 to 59). Without one the action runs as soon as the trigger fires. With one, Orgo records the action as scheduled and a job picks it up every 5 minutes once it is due, so it runs within about five minutes of its scheduled time. A delayed action that fails is recorded as failed and is not retried automatically. Send Email action configuration with the action type chosen, a subject line carrying a placeholder, the email body in the rich text editor, and the delay section expanded showing the days, hours and minutes inputs set to 0, 0 and 5 *** ## Testing before you switch it on **Test** is a dry run against yourself: it checks the configuration and reports whether the workflow would run, without sending anything or changing any record. It tests the stored version, not the unsaved canvas, so save first. A dry run is not a delivery test. To confirm an email's wording and placeholders, trigger the workflow once on a real test account. *** ## Execution logs Open **View Logs** from the list, or **Logs** from the builder's top bar. Each row is one run: the date, which trigger fired, who it ran for, the status, and how long it took. Filter by status, or hit **Refresh**. | Status | Meaning | | --------------- | ---------------------------------------- | | **Pending** | Queued, not started yet | | **In Progress** | Running now | | **Completed** | Every action either ran or was scheduled | | **Partial** | At least one action failed | | **Failed** | The run itself errored out | The eye icon opens the detail view: start and finish timestamps, the person, any error message, a timestamped step-by-step execution log, and the raw trigger payload. A run for a non-member (an external event attendee held as a contact) shows the person with an **External** tag. Workflows run in the background, so a run appears in the log a moment after the triggering event. Workflow execution log table with date, trigger, user, status and duration columns, one row per run covering Completed, Partial, Failed, In Progress and Pending, above a status filter and a Refresh button *** ## Things worth knowing * **Actions belong to the trigger they are connected to.** With two triggers on one canvas, only the actions wired to the trigger that fired will run. * **A clone does not carry those connections over.** The drawing is copied, the links are not, so every action in the copy would run for every trigger. Open the copy, check the wiring, save once before activating. * **Editing replaces, it does not merge.** Saving rewrites the workflow's triggers and actions from what is on the canvas. * **Deactivating keeps everything.** An inactive workflow stops reacting to events but keeps its configuration and its logs. *** ## Troubleshooting Check the execution log first. No rows means the trigger never matched: confirm the event really occurs in your organization, and that the user type filter or the product/event/tag filter is not excluding everyone. **Completed** rows with no email mean the action was configured but delivery failed, which the detail view's execution log names. Open the run in the execution log. A delayed action is logged as scheduled with its target time. If it failed, the reason is stored against it and it is not retried on its own: fix the cause and trigger the workflow again. *** ## Related * [Email templates](/docs/platform/emails/email-templates) * [Notifications](/docs/platform/notifications) * [Activity log](/docs/platform/logs) * [Permissions](/docs/platform/permissions) * [Webhooks and the API](/docs/platform/api)