# 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 # 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 # 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. # Add a category to the list Source: https://orgo.space/docs/api-reference/website/add-a-category-to-the-list /api-reference/openapi.json post /api/v1/website-article-categories Body: {"name": "Field notes"}. Adds a label with nothing filed under it yet, which is what lets the first article of a new category choose one. Duplicates differing only in case are refused - that is the whole reason the list is stored rather than derived from the articles. Requires ADMIN_TENANT and the website module. # Add a redirect Source: https://orgo.space/docs/api-reference/website/add-a-redirect /api-reference/openapi.json post /api/v1/website-redirects `from` is a path on this site; a full url is accepted and reduced to its path. `to` is a path here or a full http(s) address. `code` is 301 (permanent, the default, and what a migration wants) or 302 (temporary). Refused: a rule pointing at itself, a second rule for the same `from`, a chain that loops, and a target that is neither a path nor an http(s) url - a protocol-relative `//host` in particular, which would turn the site into an open redirect. To carry a whole migration across at once use POST /api/v1/website-import with a `redirects` list instead; that replaces the set wholesale. Requires ADMIN_TENANT and the website module. # Apply a starter site template Source: https://orgo.space/docs/api-reference/website/apply-a-starter-site-template /api-reference/openapi.json post /api/v1/website-templates/{key}/apply Creates the template's pages and menus and sets its theme. With replace=true this first deletes every existing page and menu entry, so it is destructive; with replace=false it aborts on the first slug collision, which is the safer default. For migrating an existing website, prefer POST /api/v1/website-import - a template is a starting point, not an import. Requires ADMIN_TENANT and the website module. # Apply a whole site in one transaction Source: https://orgo.space/docs/api-reference/website/apply-a-whole-site-in-one-transaction /api-reference/openapi.json post /api/v1/website-import Writes design, pages and both menus from a SiteSpec. Body: {"mode": "dryRun"|"apply", "replace": bool, "spec": SiteSpec}. mode=dryRun validates everything and writes nothing, returning the same report an apply would produce - always run it first and show the result to the person before applying. mode=apply takes a snapshot, then writes in one transaction: if any part of the spec is invalid, nothing changes. replace=true deletes pages the spec does not mention. Menus are replaced wholesale whenever the spec carries them and left alone when it does not. Both modes return the normalized spec: the site as it would actually be stored after sanitization, which is not always what was sent. Pages land published unless the spec says DRAFT - a status about a page, not about the site - and this call never puts the site live. If no page claims `isHomepage`, one is elected from `sourceUrl`, then from the slug, then the first page; an election never moves a homepage the tenant already has. Requires ADMIN_TENANT and the website module. Rate limited per tenant. # Change a redirect Source: https://orgo.space/docs/api-reference/website/change-a-redirect /api-reference/openapi.json patch /api/v1/website-redirects/{uuid} Merge-patch: send only `from`, `to` or `code`. The same rules as creating one apply, checked against the rest of the table. Requires ADMIN_TENANT and the website module. # Create or replace one article by slug Source: https://orgo.space/docs/api-reference/website/create-or-replace-one-article-by-slug /api-reference/openapi.json put /api/v1/website-article/{slug} The same tool as PUT /api/v1/website-page/{slug}, for a news article. An article is a page with a date: the body is the same block list, through the same sanitizer, and everything the section vocabulary can express is available in one. Idempotent, and the block list is replaced entirely rather than merged. The editorial fields - title, excerpt, category, coverImage, publishedAt, seoTitle, seoDescription - are patched: a key you do not send keeps its stored value, an explicit null clears it. That is what lets the visual editor save a rearranged body without resending the metadata it does not show. A publishedAt in the future schedules the article: the public index filters on the date, so it stays unseen until then. Requires ADMIN_TENANT and the website module. # Create or replace one page by slug Source: https://orgo.space/docs/api-reference/website/create-or-replace-one-page-by-slug /api-reference/openapi.json put /api/v1/website-page/{slug} The tool for changing one page - a whole-site rewrite belongs in POST /api/v1/website-import. Idempotent: re-running converges rather than accumulating duplicates, and no lookup round-trip is needed because the slug addresses the page. The block list is replaced entirely, not merged, so send the whole page. The response echoes the stored blocks, which may differ from what was sent: unknown fields are dropped and rich text is sanitized. Requires ADMIN_TENANT and the website module. # Delete a document the website hosts Source: https://orgo.space/docs/api-reference/website/delete-a-document-the-website-hosts /api-reference/openapi.json delete /api/v1/website-documents/{file} Takes a hosted document off the CDN. `file` is the name a `files` row stores. Refused with 409 while any page still links it - the response names the pages. Remove the rows first, or pass `force=true` to delete anyway; the answer then lists the pages left pointing at a missing file in `stillLinkedFrom`. Returns `{"deleted", "stillLinkedFrom"}`. 404 for a name that is not one of this tenant's documents. Drive shares are not affected - revoke those in Drive. Requires ADMIN_TENANT and the website module. # Export the whole site as a SiteSpec Source: https://orgo.space/docs/api-reference/website/export-the-whole-site-as-a-sitespec /api-reference/openapi.json get /api/v1/website-snapshot The tenant's entire website as one document: design settings, every page with its blocks, and both menus - drafts and inactive menu entries included. This is the same shape POST /api/v1/website-import accepts, so it doubles as a backup, a diff baseline, and the thing to read before deciding what to change. Applying it back unchanged is a no-op. Requires ADMIN_TENANT and the website module. # Find documents the site may offer for download Source: https://orgo.space/docs/api-reference/website/find-documents-the-site-may-offer-for-download /api-reference/openapi.json get /api/v1/website-drive-files The files a `files` section may list: documents this tenant has already shared publicly from Drive. A Drive row links at the file where it lives, with Drive's permissions and revocation. For a document that belongs to the website alone - above all the downloads of a site being migrated in - use /api/v1/website-documents instead and store `file` rather than `slug`. Query: `search`, matched against the file's title. Omit it to browse; most tenants have few enough public files to read the list. Returns `{"files": [{"slug", "title", "fileType", "size", "url", "thumbnailUrl"}]}`. Put `slug` in the block, and copy `title`, `fileType` and `size` alongside it - a published page is a static file on a CDN and cannot ask Drive what a slug points at. Never store `url`: the section rebuilds it from the slug, which is what stops a block naming an origin nobody checked. `thumbnailUrl` is for a picker's own preview; the section lists files as files and draws no thumbnails. Only files with a public share come back, and only ones this admin can already see in Drive. A document nobody has shared is not listed at all - share it in Drive first. Revoking that share later takes the download down and leaves the row pointing at a 404, which is what revoking a share is asking for. Requires ADMIN_TENANT and the website module. # Find forms the site may embed Source: https://orgo.space/docs/api-reference/website/find-forms-the-site-may-embed /api-reference/openapi.json get /api/v1/website-forms The forms a `form` section may embed: this tenant's, in a state a visitor can actually fill in. The page builder does not author forms, it points at ones the form builder already owns - a second question editor here would be a second copy of every membership application, out of step with the first a week later. So the block stores the form's `uuid` and the section fetches the questions when the page renders, which is what keeps a published page correct after somebody adds a question, and what makes closing a form close it everywhere at once. Query: `search`, matched against the form's name. Omit it to browse the twenty most recently updated. Returns `{"forms": [{"uuid", "name", "title", "status", "fieldCount"}]}`. Put `uuid` in the block; the rest are labels for a picker. Drafts are never listed - a section pointing at one renders "not available" to every visitor until an admin happens to look. Requires ADMIN_TENANT and the website module. # Get a template homepage Source: https://orgo.space/docs/api-reference/website/get-a-template-homepage /api-reference/openapi.json get /api/v1/website-templates/{key}/preview The template's design settings and the blocks of its homepage, for showing what applying it would look like. Reads nothing and writes nothing. Requires ADMIN_TENANT and the website module. # Get the site design settings Source: https://orgo.space/docs/api-reference/website/get-the-site-design-settings /api-reference/openapi.json get /api/v1/website-settings Theme, colours, typography, corner radius, header and footer options, default SEO, custom code, the site's own hostname and its storage region. Also returns websiteHostDefault (the .orgo.cloud address every site has), websiteRegionDefault (what the organisation's country implies) and websiteRegions (what may be chosen). Requires ADMIN_TENANT and the website module. # Get the website block vocabulary Source: https://orgo.space/docs/api-reference/website/get-the-website-block-vocabulary /api-reference/openapi.json get /api/v1/website-schema Everything needed to compose a valid page in one call: every block type with the fields it accepts, what each type is for, one valid example of it, the shared layout object, every allowed enum value, and which platform-backed sections this tenant may use. Read this before writing any page. It is generated from the sanitizer itself, so it cannot drift from what a write will actually accept. Requires ADMIN_TENANT and the website module. # How to migrate a website into Orgo Source: https://orgo.space/docs/api-reference/website/how-to-migrate-a-website-into-orgo /api-reference/openapi.json get /api/v1/website-guide The whole workflow as one markdown document: what a SiteSpec looks like, the nine phases from crawling a source site to publishing, the mapping from common web patterns to Orgo sections, and the two points where you must stop and ask the person. Read this first when the task is "move my website to Orgo". Read GET /api/v1/website-schema alongside it - that one is the vocabulary, this one is the process. Requires ADMIN_TENANT and the website module. # Import a document into the site by url Source: https://orgo.space/docs/api-reference/website/import-a-document-into-the-site-by-url /api-reference/openapi.json post /api/v1/website-documents/import Fetches a document - the statute, annual report or form a migrated site offered for download - stores it publicly on the website's CDN and returns the row a `files` section stores. Body: {"url": "https://..."}. Same guards as an image import: http and https only, no private or internal address anywhere in the redirect chain. At most 25 MB. The bytes are checked, not the name or the Content-Type: PDF, Word, Excel, PowerPoint (old and new), OpenDocument, RTF, EPUB, plain text and CSV are accepted; HTML, SVG, archives, images and executables are refused. Returns `{"file", "title", "fileType", "size", "url", "reused"}`. Importing the same url twice returns the stored file without fetching again. A hosted document is public until deleted; it has no share to revoke. Requires ADMIN_TENANT and the website module. Rate limited per tenant, on the same budget as image imports. # Import an image into the site by url Source: https://orgo.space/docs/api-reference/website/import-an-image-into-the-site-by-url /api-reference/openapi.json post /api/v1/website-media/import Fetches an image and stores it, returning the bare filename that a block's image field expects. This is how a picture from another website gets into Orgo: blocks store filenames, never urls, so an external address can never be referenced directly. Body: {"url": "https://..."}. Only http and https, only the standard ports, no credentials in the url, no private or internal addresses at any point in the redirect chain, at most 10 MB. The image is re-encoded to WebP, so an animated GIF is kept as its first frame and says so in the warnings. Importing the same url twice returns the existing file rather than fetching again. Requires ADMIN_TENANT and the website module. Rate limited per tenant. # List the article categories in use Source: https://orgo.space/docs/api-reference/website/list-the-article-categories-in-use /api-reference/openapi.json get /api/v1/website-article-categories Every category label the tenant's articles carry, with how many articles carry each. Drafts included. A category is a free label on the article rather than a record of its own, so this is the only list of them there is - read it before setting one, or you will invent a second spelling of a category that already exists. Requires ADMIN_TENANT and the website module. # List the documents the website hosts Source: https://orgo.space/docs/api-reference/website/list-the-documents-the-website-hosts /api-reference/openapi.json get /api/v1/website-documents Documents stored by the website itself for a `files` section - the other source beside Drive shares. Newest first, at most 20. Query: `search`, matched against the file name. Returns `{"files": [{"file", "title", "fileType", "size", "url"}]}`. Put `file` in the row, never `url` (the section rebuilds the address), and copy `title`, `fileType` and `size` alongside it. Requires ADMIN_TENANT and the website module. # List the redirects Source: https://orgo.space/docs/api-reference/website/list-the-redirects /api-reference/openapi.json get /api/v1/website-redirects Every old address the site still answers on, with its uuid, and `max` - the cap per site. Requires ADMIN_TENANT and the website module. # List the site snapshots available to restore Source: https://orgo.space/docs/api-reference/website/list-the-site-snapshots-available-to-restore /api-reference/openapi.json get /api/v1/website-snapshots One is taken automatically before every import and before every restore, newest first, ten kept per tenant. Requires ADMIN_TENANT and the website module. # List the starter site templates Source: https://orgo.space/docs/api-reference/website/list-the-starter-site-templates /api-reference/openapi.json get /api/v1/website-templates Each entry describes what applying it would create. Requires ADMIN_TENANT and the website module. # Publish an uploaded document Source: https://orgo.space/docs/api-reference/website/publish-an-uploaded-document /api-reference/openapi.json post /api/v1/website-documents/upload Step two: checks the staged file the way an import does, publishes it and removes the staged copy. Body: {"uploadKey": "", "fileName": "Annual report 2025.pdf"}. The name becomes the readable part of the stored name and the title; it never decides the format. Returns the same row as the import. Uploading identical bytes twice returns the first file. Requires ADMIN_TENANT and the website module. # Publish pages, and put the site live Source: https://orgo.space/docs/api-reference/website/publish-pages-and-put-the-site-live /api-reference/openapi.json post /api/v1/website-publish The one call that makes work visible to visitors, and the only one - an import sets page statuses but never the live switch, a page save leaves the status alone, and applying a template does not switch the site on. Body: {"pages": ["about", "contact"] | ["all"], "only": ["about"], "goLive": true, "force": true}. All four keys are optional: send pages alone to publish content without putting the site live, or goLive alone once the content is ready. `pages` changes a status - it moves drafts to published. `only` changes what this build renders: the pages named take their current content and every other page keeps the version already on the internet, which is how one page is published without dragging another's unfinished draft online. Omit `only` to publish the whole site. A slug that is not one of yours is refused rather than ignored. Design, menus, articles and redirects belong to the whole site, so they ride along with any publish, `only` or not. There is nowhere to hold half a menu. `force` renders even when nothing has changed. Publishing is otherwise skipped when the site is byte-identical to the last build, which is right for content and wrong after the renderer itself is upgraded. Putting the site live with no published homepage is refused - the result would be a domain serving a 404. Ask the person before calling this. Everything up to here is reversible from a snapshot; this is the step that is not. Requires ADMIN_TENANT and the website module. # Put the site back to a snapshot Source: https://orgo.space/docs/api-reference/website/put-the-site-back-to-a-snapshot /api-reference/openapi.json post /api/v1/website-restore/{uuid} Destructive: pages created since the snapshot are deleted, and the design and both menus go back to what they were. A snapshot of the current state is taken first, so restoring the wrong one loses nothing. Requires ADMIN_TENANT and the website module. Rate limited per tenant. # Remove a category Source: https://orgo.space/docs/api-reference/website/remove-a-category /api-reference/openapi.json delete /api/v1/website-article-categories/{name} Removes the label from the list and clears it from every article carrying it. The articles stay - it is a label being deleted, not the work filed under it - and the response reports how many were cleared. Requires ADMIN_TENANT and the website module. # Remove a redirect Source: https://orgo.space/docs/api-reference/website/remove-a-redirect /api-reference/openapi.json delete /api/v1/website-redirects/{uuid} The old address stops being honoured; visitors arriving on it get a 404. Requires ADMIN_TENANT and the website module. # Rename a category everywhere Source: https://orgo.space/docs/api-reference/website/rename-a-category-everywhere /api-reference/openapi.json patch /api/v1/website-article-categories Body: {"from": "Field notes", "to": "Field work"}. Renames the label in the list and on every article carrying it, in one write. To remove one, use DELETE - a half-renamed category is two categories. Requires ADMIN_TENANT and the website module. # Reorder the header or footer menu Source: https://orgo.space/docs/api-reference/website/reorder-the-header-or-footer-menu /api-reference/openapi.json post /api/v1/website-menu/reorder Moves several entries at once. To change a single entry use PATCH /api/v1/website_menu_items/{uuid}. Requires ADMIN_TENANT and the website module. # Start a document upload Source: https://orgo.space/docs/api-reference/website/start-a-document-upload /api-reference/openapi.json post /api/v1/website-documents/upload-url Step one of uploading bytes you hold. The API cannot carry a 25 MB body, so the file goes straight to storage: POST it as multipart/form-data to `url` with every entry of `fields`, then a `Content-Type` field, then the file as `file`. Returns `{"uploadKey", "url", "fields", "maxBytes"}`. The key is private and valid for 15 minutes. Then call POST /api/v1/website-documents/upload. Requires ADMIN_TENANT and the website module. Rate limited per tenant. # Store an image from base64 data Source: https://orgo.space/docs/api-reference/website/store-an-image-from-base64-data /api-reference/openapi.json post /api/v1/website-media/upload-base64 The fallback for an image Orgo's servers cannot fetch themselves - one behind a login, or on a host that is not publicly reachable. Prefer POST /api/v1/website-media/import whenever the url works. Body: {"data": "", "reference": ""}. At most 2 MB, since the payload rides in the request. The reference is what makes a re-run converge instead of duplicating the image. Requires ADMIN_TENANT and the website module. Rate limited per tenant. # The status of the last static render Source: https://orgo.space/docs/api-reference/website/the-status-of-the-last-static-render /api-reference/openapi.json get /api/v1/website-build Publishing queues a render of the site into files; it happens outside the request, so the publish call can only ever answer "queued". This is where you find out whether it finished, and when it did not, why. Returns the latest build and a short history. `status` is QUEUED, RUNNING, DONE or FAILED. Null before the site has ever been published. Also returns what is live, page by page: `pages[].publishState` is LIVE (on the internet as written), STALE (edited since), NEVER_PUBLISHED, WITHDRAWING (a draft here, still being served until the next publish) or DRAFT. `pendingCount` is how many a publish would move, and `settingsChanged` says the same for design, menus, articles and redirects. Read this before publishing to know whether there is anything to publish. Poll this after publishing rather than assuming; a site of thirty pages is usually done in seconds. Requires ADMIN_TENANT and the website module. # Update the site design settings Source: https://orgo.space/docs/api-reference/website/update-the-site-design-settings /api-reference/openapi.json patch /api/v1/website-settings Merge-patch: send only the keys to change. Colours are hex values, and a null colour means "inherit the theme preset" rather than "no colour". This is also where a site is published or unpublished, through isActive. Four keys sit at the top level of the payload rather than inside the design object, because they are not design: - `social` — the organisation's links (facebook, instagram, linkedin, youtube, tiktok, x). Stored on the tenant, shared with the tenant form, so changing one here changes it everywhere. - `websiteHost` — the domain the organisation owns. A hostname, no scheme and no path; anything under orgo.space or orgo.cloud is refused, as is a name another organisation already answers on. - `websiteRegion` — where the site is stored: eeur, weur, enam or wnam. Null means "decide from the country", and an unrecognised value clears the choice rather than being stored. - `code` is inside the design object: `code.head` and `code.bodyEnd` are markup added to every published page exactly as written, 8000 characters each. It runs on the published site only — never in the builder or the preview, which is a security boundary rather than an omission. An absent key is left alone; an empty one clears it. Requires ADMIN_TENANT and the website module. # Create a website article Source: https://orgo.space/docs/api-reference/websitearticle/create-a-website-article /api-reference/openapi.json post /api/v1/website_articles Creates an article. The tenant is taken from the authenticated user, the slug is normalised and checked for collisions, and the block list is sanitized before storage. Publishing without a date sets it to now, since the public index filters on one. Requires ADMIN_TENANT. # Delete a website article Source: https://orgo.space/docs/api-reference/websitearticle/delete-a-website-article /api-reference/openapi.json delete /api/v1/website_articles/{uuid} Deletes an article of the current tenant's website. Requires ADMIN_TENANT. # Get a website article Source: https://orgo.space/docs/api-reference/websitearticle/get-a-website-article /api-reference/openapi.json get /api/v1/website_articles/{uuid} Retrieves one article of the current tenant's website by uuid, including its block list. Requires ADMIN_TENANT. # List website articles Source: https://orgo.space/docs/api-reference/websitearticle/list-website-articles /api-reference/openapi.json get /api/v1/website_articles Returns the articles of the current tenant's website, drafts included, newest first. Requires ADMIN_TENANT. # Update a website article Source: https://orgo.space/docs/api-reference/websitearticle/update-a-website-article /api-reference/openapi.json patch /api/v1/website_articles/{uuid} Updates an article. Re-runs slug normalisation and block sanitization on every write. Requires ADMIN_TENANT. # Create a website menu item Source: https://orgo.space/docs/api-reference/websitemenuitem/create-a-website-menu-item /api-reference/openapi.json post /api/v1/website_menu_items Adds an entry to the header or footer menu. Validates the link target, refuses a second level of nesting, and rejects a linked page belonging to another organisation. Requires ADMIN_TENANT. # Delete a website menu item Source: https://orgo.space/docs/api-reference/websitemenuitem/delete-a-website-menu-item /api-reference/openapi.json delete /api/v1/website_menu_items/{uuid} Deletes a menu entry. Its submenu entries cascade with it. Requires ADMIN_TENANT. # Get a website menu item Source: https://orgo.space/docs/api-reference/websitemenuitem/get-a-website-menu-item /api-reference/openapi.json get /api/v1/website_menu_items/{uuid} Retrieves one menu item of the current tenant's website by uuid. Requires ADMIN_TENANT. # List website menu items Source: https://orgo.space/docs/api-reference/websitemenuitem/list-website-menu-items /api-reference/openapi.json get /api/v1/website_menu_items Returns every header and footer menu item of the current tenant's website, inactive ones included, in render order. Requires ADMIN_TENANT. # Update a website menu item Source: https://orgo.space/docs/api-reference/websitemenuitem/update-a-website-menu-item /api-reference/openapi.json patch /api/v1/website_menu_items/{uuid} Updates a menu entry. Re-validates the link target and the nesting depth. Use /website-menu/reorder to move several items at once. Requires ADMIN_TENANT. # Create a website page Source: https://orgo.space/docs/api-reference/websitepage/create-a-website-page /api-reference/openapi.json post /api/v1/website_pages Creates a page on the current tenant's website. The tenant is taken from the authenticated user, the slug is normalised and checked for collisions, and the block list is sanitized before storage. Requires ADMIN_TENANT. # Delete a website page Source: https://orgo.space/docs/api-reference/websitepage/delete-a-website-page /api-reference/openapi.json delete /api/v1/website_pages/{uuid} Deletes a page of the current tenant's website. Menu items pointing at it keep their row and stop rendering. Requires ADMIN_TENANT. # Duplicate a website page Source: https://orgo.space/docs/api-reference/websitepage/duplicate-a-website-page /api-reference/openapi.json post /api/v1/website_pages/{uuid}/duplicate Creates a copy of the page - same sections, SEO fields and sharing image - at the first free "-copy" address. The copy is always a draft and is never the homepage, so duplicating cannot put anything on the internet; publishing it is a separate call. Requires ADMIN_TENANT. # Get a website page Source: https://orgo.space/docs/api-reference/websitepage/get-a-website-page /api-reference/openapi.json get /api/v1/website_pages/{uuid} Retrieves one page of the current tenant's website by uuid, including its block list. Requires ADMIN_TENANT. # List website pages Source: https://orgo.space/docs/api-reference/websitepage/list-website-pages /api-reference/openapi.json get /api/v1/website_pages Returns the pages of the current tenant's website, drafts included, ordered by position. Requires ADMIN_TENANT. # Update a website page Source: https://orgo.space/docs/api-reference/websitepage/update-a-website-page /api-reference/openapi.json patch /api/v1/website_pages/{uuid} Updates a page of the current tenant's website. Re-runs slug normalisation and block sanitization on every write. Requires ADMIN_TENANT. # Changelog Source: https://orgo.space/docs/changelog/index What's new in ORGO platform **New Features** **Importing** * **Column Mapping Wizard**: Upload a spreadsheet and map its columns on screen instead of renaming headers to match Orgo. The wizard shows your own file as a sheet, suggests a destination for each column, lets you create custom fields as you go, and writes nothing until you press Start import. Every import type now goes through it, so a legacy id column is no longer required: [Importing Data](/docs/platform/customization/import). * **See What Will Link Before You Import**: For imports that reference existing records, such as payments or role assignments, the wizard reports how many rows it can match, how many would create something new, and how many it cannot place, before anything is written: [Linking to Existing Records](/docs/platform/customization/import/linking-records). * **Import Form Responses**: Bring historic form responses in through the same wizard: [Importing Data](/docs/platform/customization/import). * **Match Payers by Personal Number**: A payments import can identify the payer by personal number, not only by email or legacy id. **Events** * **Preview and Share a Draft**: Open a draft event as attendees will see it, and send a share link for sign-off before you publish: [Create an Event](/docs/platform/events/create-event). * **Duplicate an Event in Full**: Duplicating now copies the whole configuration, including the registration form and its fields, rather than the basics: [Create an Event](/docs/platform/events/create-event). * **Tickets Attached to Reminders**: The 24 hour and 1 hour reminders carry the attendee's ticket PDF, so nobody arrives hunting for the original email: [Ticketing](/docs/platform/events/ticketing). * **Tickets Reserved for a Chapter**: Restrict a ticket to chosen chapters, alongside the members-only setting: [Ticketing](/docs/platform/events/ticketing). * **Members-Only Tickets Pinned to the Buyer**: A members-only ticket is now tied to the signed-in member, so it cannot be bought under someone else's name: [Ticketing](/docs/platform/events/ticketing). **Payments & Fees** * **Let Payers Cover the Processing Fee**: Turn on an option for your organization and the card step offers to add the processing fee, re-pricing in place when the payer accepts: [Membership Fees](/docs/platform/fees/fees). * **Quick-Pick Amounts on Donation Levels**: Offer suggested amounts on a donation level that grants membership, instead of a free-text box: [Donations](/docs/platform/fees/donations). * **Restrict Who Can Take a Product's Payments**: Limit a product's payments to your finance team: [Products](/docs/platform/fees/products). * **Export Invoices as CSV**: Export the invoices you have filtered to, or all of them: [Invoices](/docs/platform/fees/invoices). * **Donation Campaigns for Top-Level Chapters**: A donation campaign can be scoped to top-level chapters only: [Donations](/docs/platform/fees/donations). **Reports** * **Two-Pane Report Builder**: Build on one side, see the result on the other, and share a read-only view of a finished report: [Reports](/docs/platform/reports). **Tasks** * **My Tasks**: One page for everything assigned to you, grouped, with the status control on each row: [Tasks](/docs/platform/tasks). **Newsletter** * **Informational Campaigns**: Mark a campaign as informational and it reaches everyone it is addressed to, regardless of newsletter subscription. For operational notices rather than marketing: [Newsletter](/docs/platform/newsletter). * **Stop a Campaign Mid-Send**: Halt a send that is already running, and resume a paced campaign where it left off. **Emails** * **Email a Member From Their Profile**: A redesigned compose window built around the recipient, with placeholders filled in, and the message recorded on their activity timeline. * **Email Log Export and Access**: Communication managers can reach the email log, open the template behind a message, and export the log as CSV: [Email Log](/docs/platform/emails/email-log). **Members & Lists** * **More Ways to Build a List**: A list can select by user type, and its chapter criterion can match several chapters at once: [Lists](/docs/platform/users/lists). **Website** * **Upload Documents to the Website**: The Files section can take a document uploaded straight from the builder, beside files shared from Drive: [Website Builder](/docs/platform/organisation/website-builder). * **Documents Move With a Migrated Site**: When an assistant moves your site into Orgo, the PDFs and Office files it offered for download come across too and land in a Files section: [Orgo MCP](/docs/platform/mcp). * **Public Company Map**: The company directory's map is now a section you can place on your public site: [Website Builder](/docs/platform/organisation/website-builder). **Customization** * **Rename Terminology in Bulk**: Review a set of wording changes before they are applied across the platform, then apply them, and undo the batch if it reads wrong: [Texts](/docs/platform/customization/labels). **Files** * **Limit Personal Files to Admins**: Restrict who can change members' personal files to administrators and HR: [Files](/docs/platform/files). **Custom Domain** * **DNS Set-Up That Knows Your Provider**: Enter your domain and Orgo identifies the DNS provider, leads with the automatic path, and stops showing tables you do not need: [Custom Domain](/docs/platform/custom-domain). **Improvements** **Events** * **Clearer Event Analytics**: Chart legends, a bucket for attendees who never responded, and slice labels that stay readable at large totals: [Event Analytics](/docs/platform/events/analytics). * **Events Tab on a Profile**: Each event appears once, with the member's RSVP shown and filterable. **Payments & Fees** * **Better Filtering**: Filter the payments list by the payer's chapter, and by product or event name. * **Redesigned Editors**: The product, membership level, ticket, add-on and voucher editors have been reworked: [Products](/docs/platform/fees/products). **Analytics** * **Fee Revenue Credited to the Payer's Chapter**: Organization-level fee revenue can be attributed to the chapter the payer belongs to, so chapter analytics reflect what their members contributed: [Insights](/docs/platform/insights). * **What Each Figure Means**: Stat cards carry an explanation of how the number is calculated: [Insights](/docs/platform/insights). **New Features** **Reports** * **Custom Report Builder**: Build a report across your members, payments, events and more, preview it before you commit, and export the result as a spreadsheet. Large exports run in the background and arrive as a download when they are ready: [Reports](/docs/platform/reports). **Discussions** * **Block a Member**: A member can block another member, and stops seeing their posts and comments: [Blocking Members](/docs/platform/discussion/blocking-members). * **Mention Contacts on Tasks**: Tag members and contacts on a task or a checklist row, with suggestions as you type: [Tasks](/docs/platform/tasks). **Newsletter** * **Tag Links**: Add a link inside the newsletter builder that tags whoever clicks it, so a campaign can segment your audience by what people are interested in: [Newsletter](/docs/platform/newsletter). **Events** * **Members-Only Events Stay Private**: An event whose audience is set to members no longer has a public page, and only its members-only tickets are offered. Ticketing alone no longer exposes an event publicly: [Public Event Page](/docs/platform/events/public-page). * **Event-Specific Terms**: Point a public event's registration consent at terms written for that event, with a label of your own: [Public Event Page](/docs/platform/events/public-page). **Payments & Fees** * **Donations as Membership**: A donation level can now grant membership, so a supporter who gives becomes a member without a separate fee: [Membership Fees](/docs/platform/fees/fees). * **Donors Told Why a Gift Stopped**: When a recurring gift is returned or ends because a cap was reached, the donor is told why rather than the payment simply disappearing: [Donations](/docs/platform/fees/donations). **Chapters** * **Chapters Within Chapters**: A chapter hierarchy can now go deeper than one level. A parent's member count rolls up the whole subtree, with the children's contribution shown inline, and how far down the tree a chapter sits decides who may create events there: [Local Centers](/docs/platform/groups/local-groups). * **Local Admins Can Request Transfers**: A chapter admin can request that a member move to their chapter and follow the request through: [Transfers](/docs/platform/groups/transfers). * **Assign a Chapter by State**: For organizations that opt in, a new member is placed in the chapter covering their state automatically, and their local fee moves with them: [Local Centers](/docs/platform/groups/local-groups). **Companies** * **Renewal Reminders per Organization**: Turn company fee renewal reminders on or off for your organization, and send a specific reminder to a single company. Inactive companies no longer receive reminders or invoices: [Companies](/docs/platform/users/companies). **Profiles** * **Connection-Based Visibility**: What a member can see on another member's profile, including their contact details, now follows whether the two are connected. **Workflows** * **Form Submission Trigger**: Start a workflow when a form is submitted, optionally only for one form: [Workflows](/docs/platform/workflows). **Platform** * **Greek**: Orgo is now available in Greek, with Greek regions for address and chapter data: [Languages](/docs/platform/customization/languages). * **Turn Off the Support Chat**: Hide the Orgo support chat for your organization if you would rather your members came to you. **Improvements** **Newsletter** * **Send Today**: Schedule a campaign for later the same day. Previously the earliest you could pick was tomorrow. **Events** * **Attendee Export Follows Your Filters**: Filter the attendee list and the CSV export contains exactly what you filtered to, instead of everyone: [Event Attendance](/docs/platform/events/attendance). **Payments & Fees** * **Exemption Tiers Aligned to the Cycle**: A fee exemption now runs to the end of the membership cycle rather than an arbitrary date, and the exemption appears in the member's fee history: [Membership Fees](/docs/platform/fees/fees). **Profiles** * **Notes in the Activity Tab**: Notes about a member live in the Activity tab alongside everything else recorded about them, and can be managed from there: [Profile Activity](/docs/platform/users/profile-activity). **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 # Turning a Contact into a Member Source: https://orgo.space/docs/platform/contacts/becoming-a-member Merge is the conversion: what moves onto the member record, what is lost on the way, and why Create user account is a different thing Sooner or later a contact needs to do something only a member can do. Two buttons look like they will handle it. Only one of them combines the two records into a single history, and only one of them shows you what it is about to do. **Built for** organisations whose donors, subscribers and ticket buyers eventually join. **Replaces** retyping a contact's details into a new profile and losing everything that was attached to the old record. *** ## When a contact needs to become a member A contact is a person record without a login. Convert one when the person now has to: * sign in to the member area * hold a membership fee, renew it, and appear in fee reports * belong to a chapter, a group or a unit * take a course * vote in an e-voting session * hold a role or a permission Everything else, a contact can already do: buy a ticket, donate, receive the newsletter, sign an e-document, pay an invoice, hold a recurring subscription. The side-by-side comparison of what each one can do is on [Contacts](/docs/platform/contacts). If nothing in the list above applies, leave them as a contact. *** ## Merge is the conversion **Merge Records** folds the contact into the member you keep. It moves the contact's history onto the member record, then deletes the contact. | | | | - | - | | **Where** | **Settings** → **Developers** → **Merge Records** | | **Permission** | `HR_TENANT` | | **Must be on** | the **Merge Profiles** toggle under **Settings** → **Users & Profiles**. With it off, the page redirects to the dashboard | The contact is the **source**, the record that goes away. The member is the **target**, the record you keep. The page labels them that way. **Duplicate Suggestions** at the bottom of the page has a **Contact-User Matches** tab: a contact and a member sharing an email address, scored 95%. That is the usual starting point. If you already know the two records, use **Manual Merge** at the top and search each side by name or email. The comparison puts the two records side by side, one row per field. Fields that agree are ticked. Fields that disagree are tagged **Conflict** with a pair of radio buttons, and Orgo preselects a suggestion. Read the email and phone rows even so. Underneath, **Related Records to Transfer** counts what will move. Everything runs in one transaction. If any part of it fails, nothing changes. Open the member profile and confirm the payments, tickets and tags landed. The chapter does not move, so if the two records sat in different chapters, check the Roles tab. A merge can be undone once, within 30 days, from **Merge History** at the top right of the page. After that the **Undo** button reads **Expired** and the merge is permanent. Undo recreates the deleted contact, with a new id. The full mechanics, including member-to-member merges, are on [Merging Duplicates](/docs/platform/users/merging-duplicates). *** ## What transfers and what does not Read this before you merge, not after. Undo restores field values, but it cannot bring back records that were deleted with the contact. | What | Where it ends up | | - | - | | Payments, and the payment records behind them | Move to the member | | Invoices | Move to the member | | Recurring subscriptions | Move to the member | | Event registrations and tickets | Move to the member, one per event. Where both records attended the same event, the contact's status, payment and ticket win and the duplicate row is dropped | | Company membership | Moves to the member, and is dropped rather than doubled if the member already held that company | | Tags | Move, deduplicated | | Custom field answers | Move, and the member's own answer wins where both have one | | ID document and the payment customer reference | Move, when the member does not already have one | | Newsletter subscription record | Moves to the member | | Uploaded files | Move to the member | | Profile fields: name, email, phone, address, organisation, role, town, social links | You choose per field in the preview | | **Contact notes** | **Deleted with the contact. Not moved, and not restored by undo** | | **Form submissions** | **Detached. They stay in the form's results but belong to neither record afterwards** | | Event app sign-in devices | Deleted with the contact | The contact's **Notes** are the one thing a merge destroys outright, and undo does not bring them back. If a note holds something you need, a phone call summary, a consent record, why the person was flagged, copy it onto the member profile before you merge. *** ## Before you merge * [ ] Both records are the same person, confirmed on more than a shared name. Compare email, phone and town, and open each record if you are unsure. * [ ] Anything worth keeping from the contact's **Notes** is copied onto the member profile. * [ ] You know which of the two records holds the payment history, so you can confirm afterwards that it moved. * [ ] You have decided which email address the person keeps. The survivor signs in with it, and their username is regenerated from it. *** ## Create user account is not the merge screen **Create user account**, on the contact record and in the contact list row menu, registers a new member from that contact's email and sends the welcome message. It never opens the comparison: there is no preview, no field-by-field choice, and no undo. What happens to the contact afterwards is decided by **Settings** → **Users & Profiles** → **Configuration** → **Default Status for Admin-Created Users**, not by anything the button asks you: | Default status | What happens to the contact | | - | - | | **Active**, the default | Orgo looks for a contact on the same email address and folds it into the new member. Payments, invoices, subscriptions, event registrations, custom field answers, the ID document, uploaded files and the newsletter record move across; name, social links, town, organisation, role, birthday, gender, bio and photo are copied; the contact record is then deleted. Notes, tags and company membership do not survive it, and form submissions detach | | Inactive, Unapproved, Waiting List, Suspended, Excluded | Nothing is folded in. The new member holds the email address, birthday, gender and joined dates, and nothing else. The contact stays exactly where it was, with no link to the new member and with the whole payment history still on it. The same person now exists twice | Because the outcome hangs on a setting rather than on the button, do not use **Create user account** when the contact has payments, tickets or notes worth keeping. Use **Merge Records** instead: you see what will move before you commit, and you have 30 days to undo it. If you already pressed **Create user account**, search Contacts for that email straight away. If the contact is still listed, merge it into the new member and the history follows. If it is gone, the fold already happened. Registering a member from scratch, and what the welcome email contains, is covered in [Adding Members](/docs/platform/users/adding-members). *** ## What merge refuses to do **A member cannot be merged into a contact.** Pick that direction and the page tells you to swap the two: contact as source, member as target. **There is no route back.** Nothing turns a member into a contact. Deleting a member or processing a resignation leaves no contact behind, and the member record survives only as a hidden, deleted row. If your aim is to stop someone signing in while keeping their history, change their status instead of looking for a downgrade. *** ## What changes for the person The moment the merge completes: * **They can sign in.** They use the surviving member record's email address and its own password or one-time code. A contact had no login of its own, apart from the one-time code that opens the event app for an event they hold a ticket to. * **Their event history follows them.** Past registrations, tickets and check-ins sit on the member profile and in the attendee exports, one row per event. * **Their money reads as a member's.** Payments, invoices and any recurring subscription now belong to the member, so reports that count members stop disagreeing with reports that count revenue. * **A membership fee can be assigned.** A contact never held one, so there is nothing to move: you assign the fee on the member profile after the merge. * **Their newsletter subscription carries over**, so a subscribed contact stays subscribed as a member. *** ## Troubleshooting Normal, and it is what merge is for. It happens when someone bought a ticket or donated before joining, or when a mailing list was imported. Open **Settings** → **Developers** → **Merge Records**, look in the **Contact-User Matches** tab, and merge the contact into the member. Do not delete the contact instead: its payments and tickets would go with it, and a contact with a payment attached refuses to be deleted anyway. Search the Contacts list for that email address. If the contact is still there, the new member holds only the email, birthday, gender and joined dates, and everything else is still on the contact. Merge the contact into the new member and the history moves across. If the contact is no longer listed, it was already folded into the member and there is nothing left to merge. Three things gate it. The **Merge Profiles** toggle under **Settings** → **Users & Profiles** must be on, or the page redirects to the dashboard. You need `HR_TENANT`, which is above the `HR_LOCAL` that lets you edit contacts. And the page itself lives under **Settings** → **Developers**, not in the Contacts screen. If you can open the page but the pair is rejected, check the direction: a member cannot be the source when a contact is the target. Contact notes belong to the contact record, and the contact record is deleted at the end of a merge. They are not copied onto the member, and undo restores field values rather than deleted notes. Copy anything you need onto the member profile before merging. Notes written on a member profile are unaffected. Once, within 30 days, from **Merge History**. Undo puts the transferred records back on the source and rewinds the fields the merge changed on the survivor, unless you edited them since. A contact that was deleted comes back with a new id, so anything outside Orgo that stored the old id will not reconnect. Anything created on the member since the merge stays there, so undo promptly if a merge was wrong. *** ## Related * [Contacts](/docs/platform/contacts) - what a contact is, and what it can do without an account * [Merging Duplicates](/docs/platform/users/merging-duplicates) - the merge screen in full, including member-to-member merges * [Adding Members](/docs/platform/users/adding-members) - the four ways a person gets an account * [Profile Activity & Notes](/docs/platform/users/profile-activity) - the notes a merge does not carry over * [Membership Fees](/docs/platform/fees/fees) - the fee a member can hold and a contact cannot * [Permissions](/docs/platform/permissions) - what HR\_TENANT unlocks # Contacts at Events Source: https://orgo.space/docs/platform/contacts/events How public event registration creates contacts, what they can do in the Event App, and how their event history follows them Public events are the largest single source of contacts in most organisations. Anyone who registers for one without an Orgo account becomes a contact, automatically, and from that point on they are a person in your records rather than a line on a ticket list. **Built for** organisers running open events, who end up with an audience far wider than their membership and need it to land somewhere useful. **Replaces** the exported attendee spreadsheet that nobody ever reconciles with the member database. *** ## What happens when someone with no account registers Every registration path that does not come from a signed-in member does the same three things with the email address entered on the form. If a member of your organisation already uses that email, the registration is attached to their member account and no contact is created. If no member matches but a contact does, that existing contact is reused. The registration joins the event history already on the record. If neither matches, a new contact is created with its **Source** set to **Event**, carrying the name, email and whatever else the registration form asked for. This runs on the free registration form, on paid ticket checkout, on the payment and invoice paths that complete a purchase later, on the **External** tab of the organiser's **Invite** dialog, and on the "fill in your details" link sent with a ticket bought on someone else's behalf. There is no setting that turns this off. Contact creation from event registration happens whether or not the contacts module is switched on. The module switch controls the contacts screens, not what gets recorded. What decides whether a non-member can reach the registration form at all is the event itself: it has to be **published** with its **Audience** set to **Public**. See [Public event page](/docs/platform/events/public-page) for that page and [Create event](/docs/platform/events/create-event) for where Audience lives. Registrations created this way land on registration status **Registered** and RSVP **Attending**. *** ## Which statuses let a contact in A contact's registration carries the same statuses a member's does, described in full on [Event attendance](/docs/platform/events/attendance). What matters here is that three gates read those statuses and they do not agree. | Registration status | Can open the Event App | Appears on their own **My events** list | Can vote | | - | - | - | - | | **Registered** | Yes | Yes | Yes | | **Invited** | Yes | Yes | Yes | | **Awaiting payment** | Yes | **No** | **No** | | **Pending approval** | No | No | No | | **Waiting list** | No | No | No | | **Canceled** | No | No | No | An attendee waiting on an unpaid invoice can sign in to the Event App and open the event through the link in their email, but the event does not appear on their own **My events** list and they cannot see or cast event votes. If someone says the app works but the event has vanished from their list, check for an unsettled invoice before anything else. *** ## The Event App for a contact A contact has no password, so they sign in with a code sent to their email address: six digits, valid for five minutes, reaching the Event App and nothing else in Orgo. The limits, and the alternative route through the link in their confirmation email, are on [Event App](/docs/platform/events/event-app). Inside, a contact is a full participant on almost every surface. | In the Event App | A contact can | | - | - | | **My events** | Yes. This screen exists for them; members are sent to their dashboard instead | | **Program** | Yes, including saying they will attend individual sessions | | **Details** | Yes | | **Feed** | Read, reply and react. They cannot start a top-level post, which is an organiser action | | **Networking directory** | Yes, both seeing others and being listed | | **1:1 meetings** | Yes, book, accept, decline and cancel | | **Badge and QR scanning** | Yes, show their own badge and scan another attendee to save them | | **Vote** | Yes, on **Registered** or **Invited** registrations | | **Profile** | Yes, including the photo, headline, bio, links and their own privacy switches | | **Connection requests** | **No** | **Connections are member to member.** The **Connect** button creates a lasting relationship in your member network, so it is not offered to a contact and a contact cannot receive one either. The equivalent for them is the **1:1 meeting**, which works in both directions between any two attendees regardless of kind. See [Event App networking](/docs/platform/events/event-app-networking). One more gap: the notification for a new feed post goes to member attendees only. Contacts see the post when they next open the Feed, but are not told about it. *** ## Privacy in the attendee directory The defaults are the opposite of what most people assume, and they differ by kind of attendee. | | Listed in the directory | Phone shown to other attendees | Email shown to other attendees | | - | - | - | - | | **Member** | Yes by default | **Yes** by default | **Yes** by default | | **Contact** | Yes by default | **No** by default | **No** by default | A contact never signed up for a profile and never agreed to share their details, so their card appears but the details on it stay withheld until they turn them on in the Event App **Profile** tab. A member's phone and email are shown unless they set them private themselves. Two rules apply to everyone: an attendee with **no email address on file gets no card at all**, for every viewer including organisers; and organisers see the full roster with phone and email unmasked, whatever each person chose. *** ## Badges and check-in There is no separate badge record. **The badge is the registration**, carried as a QR code that appears on the emailed PDF ticket, on the event page and on the **Badge** button in the Event App. Contacts get one exactly as members do. Scanning it at the door and confirming checks the attendee in, which sets their RSVP to **Attended**. The scanner card marks a contact as an external registration and shows no profile photo, but the flow is identical. The code is the credential. For a contact it is also their way into the Event App, so anyone holding their ticket QR effectively holds their event session. Cancelling the registration invalidates it. Full detail, including which permission each scanner needs, is on [QR check-in](/docs/platform/events/check-in). *** ## Where the history lives Open a contact and scroll to the **Events** card: the events that contact attended, past events first, with the empty state "No events for this profile". The same registrations show on the event side in **Participants** and in the attendee CSV export, which includes contacts alongside members. **If the contact later becomes a member, the history follows them.** Both routes re-point the existing registrations at the new member account rather than recreating them, so ticket numbers, QR codes, statuses, payments, custom field answers and add-ons all survive: * **Creating a member account on the same email address** moves the registrations across at the moment the account is created. * **Merging the contact into a member** moves them as part of the merge. Where both sides attended the same event, the merge keeps one registration and records the pre-merge values of both, so it can be rolled back. See [Becoming a member](/docs/platform/contacts/becoming-a-member) for the difference between those two routes, which is larger than it looks. *** ## Behaviour to know about Three behaviours surprise people regularly. None is a setting you can change. **A second ticket on the same email creates a second, emailless contact.** Registering again on an email that already holds an active registration for that event creates a fresh contact with **no email address**, so the second ticket carries its own registration answers instead of overwriting the first person's. That contact is a real row in your contacts list, cannot be emailed, can never sign in to the Event App (the code has nowhere to go), and does not appear in the attendee directory. On the free registration path this also leaves an existing member account unlinked, so the second ticket is a contact even when the email belongs to a member. The first registration is unaffected, and filling in a different email per attendee at checkout avoids it entirely. **An attendee with no email address is left out of the directory.** However the registration was created, no email means no card, for organisers as well as attendees. **The "Event attendees" newsletter audience only reaches subscribed contacts.** It filters contacts down to those whose newsletter subscription is on, and registration sets that only when the person ticked the newsletter box. So a contact created by an event registration is, by default, outside the audience named after the event they attended. Members usually are inside it, because most organisations default members to subscribed. Check the recipient count against the participant count before sending, and see [Contacts and the newsletter](/docs/platform/contacts/newsletter). *** ## Troubleshooting In this order. Does the email on their registration match the one they are typing? A typo at registration is invisible until this moment. Is their status one that grants access, and not cancelled? **Pending approval** and **Waiting list** do not open the app. Does the registration have an email address at all? A second ticket bought on an email that already had one produces an emailless contact that can never sign in; add the address to that contact, or cancel the row and re-register the person. Note that the code screen answers the same way for unknown and known addresses, so silence proves nothing: confirm the address against **Participants** rather than by retrying. Four causes, worth checking in this order. The registration has no email address, which removes them for everyone including you. Their status does not grant access. They turned profile visibility off in the Event App **Profile** tab, in which case you still see them as an organiser and other attendees do not. Or they are listed but hard to find: the directory is ordered by surname and contacts have no separate surname, so they gather at one end of the list. Search by name instead of scrolling. Expected when the second registration used an email that already held an active one for that event. The second contact is created without an email address on purpose, so the two tickets keep separate answers. Both are valid and both scan at the door. In the contacts list, the emailless row is the extra ticket: add the real address to it if that person needs the Event App and a directory card, or merge it away if it was a duplicate you did not want. The **Event attendees** audience includes a contact only if their newsletter subscription is on, and registration turns it on only when the attendee ticked the newsletter box. Open the contact and check the newsletter card. To reach everyone who registered regardless of subscription, use the event's own messages rather than a newsletter campaign, remembering that consent still applies to anything promotional. *** ## Related * [Event attendance](/docs/platform/events/attendance) - The participant list, both statuses, invitations and the export * [Public event page](/docs/platform/events/public-page) - The page a non-member registers on * [Ticketing](/docs/platform/events/ticketing) - Paid registration, add-ons and refunds * [QR check-in](/docs/platform/events/check-in) - Scanning at the door and who is allowed to * [Event App](/docs/platform/events/event-app) - Access, the email code sign-in and the tabs * [Event App networking](/docs/platform/events/event-app-networking) - The directory, connections and 1:1 meetings * [Contacts](/docs/platform/contacts) - What a contact is and how the module is switched on * [Where contacts come from](/docs/platform/contacts/sources) - Every other path that creates one * [Contacts and the newsletter](/docs/platform/contacts/newsletter) - Subscription, consent and audiences * [Becoming a member](/docs/platform/contacts/becoming-a-member) - Merging a contact into a member account # Contacts Source: https://orgo.space/docs/platform/contacts/index People you hold data about but who cannot log in: donors, subscribers, ticket buyers and partners A contact is someone you hold data about. A member is someone who can log in. That single line decides everything else in this section. Both live in the same organisation, side by side. A contact has a record, an email address and a history of what they paid, signed and attended. What a contact does not have is an account: no password, no permissions, no groups, and no membership fee. A member has all of that plus a login. **Built for** organisations whose audience is wider than their membership: donors, newsletter subscribers, event guests, partner staff, and people who have not joined yet. **Replaces** a separate CRM, or a spreadsheet kept alongside the member list. Contacts list showing name, email and phone icons, newsletter state, source, status and tags columns, with search and filters for status, tags and newsletter above the table *** ## Contact or member | | Contact | Member | | - | - | - | | **Login** | No account and no password. The one exception is the Event App, where a ticket holder signs in with a one-time code that works only there | Username and password, with optional two-factor | | **Roles and permissions** | None. The **Role** field on a contact record is a free-text job title, not a permission | Holds permissions (Admin, HR, Financial and so on) and a history of membership roles over time | | **Chapter membership** | One optional chapter, and only when **Enable Per-Chapter Contacts** is on | A chapter and a parent chapter, used across the whole platform | | **Groups and teams** | No | Yes | | **Membership fee** | **Never.** A fee payment records a member as its payer, and there is no route, import or setting that gives a contact fee status | Yes: fee validity dates, fee prices, renewals and reminders | | **Other payments** | Yes: donations, event tickets, invoices, and even a recurring subscription | Yes | | **Newsletter** | One flag with three states: subscribed, unsubscribed, or never asked | Per-topic subscription settings | | **Event registration** | Yes, as an external attendee, with a QR badge and Event App access | Yes | | **Company seats** | Yes, and the contact takes up a seat in the company's allowance | Yes | | **Courses** | No. A contact cannot be enrolled | Yes | | **Badges and points** | No. Gamification points are members-only (the Event App attendee badge, which is the QR pass, is a different thing and a contact does get one) | Yes | | **Governance votes** | Only Event App polls. The admin-run governance vote is members-only | Yes | **The deciding question.** If the person needs fee status, courses, badges or governance votes, they have to be a member. If they do not, a contact is enough, and it is cheaper to maintain: no invitation, no password reset, no seat in your member count. There is no way to give a contact a membership fee. Marking a fee paid, importing fee rows or editing the record will not do it. Someone who must pay a membership fee needs a member account first: see [Becoming a member](/docs/platform/contacts/becoming-a-member). *** ## What a contact can do * **Pay you.** Donations, event tickets, invoices and recurring subscriptions all attach to a contact. [Payments and the fee boundary](/docs/platform/contacts/payments) * **Receive newsletters.** Contacts and members are drawn into the same audiences, and only subscribed contacts are included. [Newsletter and consent](/docs/platform/contacts/newsletter) * **Register for events.** A non-member attendee is a contact, holds the same QR badge, and can sign in to the Event App. [Events and the Event App](/docs/platform/contacts/events) * **Arrive on their own.** Contact forms, newsletter signups, public event registrations, donation checkouts, form submissions, signing links, imports and Stripe all create contacts. [Where contacts come from](/docs/platform/contacts/sources) * **Carry a profile.** Status, tags, custom fields, notes and an activity feed. [The contact record](/docs/platform/contacts/record) * **Sign documents.** A contract or e-document can be assigned to a contact, and the signing link can create the contact from the signer's own details. See [e-Documents](/docs/platform/e-documents) * **Trigger automations.** A contact is a workflow subject for the form-submitted and event-attended triggers, and can be emailed or tagged by a workflow. See [Workflows](/docs/platform/workflows) * **Become a member.** Merging is the real conversion, and it moves their history across. [Becoming a member](/docs/platform/contacts/becoming-a-member) Who may see and edit any of this is a separate question with a longer answer: [Contact permissions](/docs/platform/contacts/permissions). *** ## Turning the module on **Settings** → **Modules** → **Contacts**. Requires `ADMIN_TENANT`. | Setting | Key | Default | What it does | | - | - | - | - | | **Enable Contacts Module** | `contacts.isActive` | On | Turns contacts on and puts **Contacts** in the sidebar | | **Enable Contact Statuses** | `contacts.hasStatuses` | On | Adds a status field to every contact and a **Contact Statuses** page where you define the list, its colours and its order | | **Enable Per-Chapter Contacts** | `contacts.perChapterContacts` | Off | Lets a contact belong to a chapter, and adds the chapter filter and column. Needs the Local Centers feature on as well, and the switch stays disabled until it is | Both extra switches stay disabled while **Enable Contacts Module** is off. **Enable Per-Chapter Contacts** does more than add a column. While it is off, chapter-level managers cannot reach contacts at all, and only tenant-level managers see the list. Turning it on is what opens contacts to chapter admins, scoped to their own chapters. *** ## Where contacts live **Contacts** sits in the **MANAGEMENT** section of the sidebar by default, next to Companies. The entry opens the contacts list; each row opens a contact record, which is one scrolling page rather than a set of tabs. Configuration is elsewhere, under **Settings** → **Modules** → **Contacts**. The sidebar entry is hidden unless you hold a contact permission and, on top of that, either a tenant-level permission (`HR_TENANT`, `FINANCIAL_TENANT` or `ADMIN_TENANT`) or **Enable Per-Chapter Contacts** is on. A chapter HR manager in an organisation that has not turned per-chapter contacts on will not see **Contacts** in the sidebar at all, and that is the expected behaviour rather than a permission fault. The sidebar itself is editable, so your organisation may have moved or renamed the entry. *** ## How many contacts do we have The nightly metrics job records `contacts_count` for the whole organisation only. It is never written per chapter, because contacts have no chapter dimension in that job's model. Two consequences: * Contact growth per chapter cannot be read from the metrics tables or dashboards. * Adding up the per-chapter rows to get an organisation total gives zero contacts, not the real number. Read the organisation-wide row instead. Member headcounts never include contacts. Revenue totals are the opposite case and mix the two, which matters when you divide one by the other: see [Payments](/docs/platform/contacts/payments). *** ## Related * [The contact record](/docs/platform/contacts/record) - fields, statuses, tags, custom fields, notes and activity * [Where contacts come from](/docs/platform/contacts/sources) - every creation path, imports and duplicates * [Payments](/docs/platform/contacts/payments) - donations, tickets, invoices, subscriptions, company seats and the fee boundary * [Newsletter](/docs/platform/contacts/newsletter) - subscription states, consent, audiences, unsubscribes and bounces * [Events](/docs/platform/contacts/events) - registration, badges, the Event App and attendee privacy * [Becoming a member](/docs/platform/contacts/becoming-a-member) - merge, the Create user account button, and what transfers * [Contact permissions](/docs/platform/contacts/permissions) - who sees what, chapter scoping, export and erasure * [Users and Profiles](/docs/platform/users/index) - the member directory a contact converts into * [Permissions](/docs/platform/permissions) - the permission set these rules are built from # Contacts and the newsletter Source: https://orgo.space/docs/platform/contacts/newsletter The three subscription states on a contact, which campaign audiences reach contacts, and how people subscribe, unsubscribe and bounce For most organisations the contact list is the mailing list. One field on the contact record decides whether a campaign ever reaches that person, and a handful of audiences decide whether contacts are in the send at all. This page covers both, plus what happens on an unsubscribe and on a bounce. **Built for** the person who has to answer "why did they get this" and "why did they not". The campaign tool itself, its editor, scheduling and reporting, is covered on [Newsletter](/docs/platform/newsletter). The campaign recipients card showing the audience options, including the ones that send to contacts rather than members *** ## Three states, not two The **Newsletter** field on a contact has three states, and the third one is real: a contact who has never been asked is not the same as a contact who said no. | State | How it arises | Receives campaigns | | - | - | - | | **Subscribed** | Someone said yes: a confirmed signup, a ticked box at registration or checkout, an import that carried a subscribed value, or an administrator pressing **Subscribe** on the record | Yes | | **Unsubscribed** | Someone said no: the unsubscribe link in a campaign, an administrator pressing **Unsubscribe**, an address that bounced or was reported as spam, an import that created the contact with a false value, or Orgo creating the record while checking whether an email already exists | No | | **Not subscribed** | Nobody ever asked. This is how most contacts start: a donor, a ticket buyer or a manually added record arrives with the field unset unless the path that created it carried an opt-in | No | Only an explicit yes is ever mailed. Every audience query tests for the subscribed state, so "never asked" and "unsubscribed" behave identically at send time. A contact with no email address is skipped as well. The **Newsletter** card on the record shows the current state with a single **Subscribe** or **Unsubscribe** button, and the **Newsletter** filter on the contacts list offers All, Subscribed, Not subscribed and Unsubscribed with a count beside each, which is the quickest way to see how the three states are spread across your database. The contacts list keeps the three states apart. [Lists and segments](/docs/platform/users/lists) do not: there, **Not subscribed** covers both the people who said no and the people who were never asked, because neither group can be mailed. *** ## Which audiences include contacts This is the thing readers get wrong most often. Two of the six audiences never touch a contact, whatever the contact list holds. | Audience | Members | Contacts | | - | - | - | | **All members and contacts** | Yes | Yes, subscribed only | | **Members from a group** | Yes | **No.** Members only, and with no group selected it is still every member and no contact | | **All subscribed contacts** | **No** | Yes, subscribed only | | **From a list** | Yes | Yes, when the list holds contacts. Its audience scope decides | | **Event attendees** | Yes | Yes, subscribed attendees registered without an account | | **Follow up with non-openers** | Yes | Yes, but see the warning below | "All members and contacts" means everyone subscribed, not everyone in the database. A contact who was never asked, has no email address, or sits outside the local center the campaign belongs to is not in it. When a campaign carries a local center, the resolved recipients are filtered to that center at send time, whichever audience was chosen. Contacts with no chapter are filtered out by the same rule, so a chapter campaign never reaches them, and the recipient count applies the same filter and therefore agrees with the send. **A follow-up send does not re-check the subscription field.** The non-openers audience is built from who received the original campaign, minus everyone the mail provider reported as bounced, complained or unsubscribed. It never reads the contact's own subscription state. Someone who received the first campaign, did not open it, and then used the unsubscribe link on your Orgo page is still in the follow-up and will receive it. Before sending a follow-up to an older campaign, check the contacts list for people who have unsubscribed since, and use **All subscribed contacts** or a list instead if that matters to you. *** ## How someone subscribes | Path | Confirmation email | What it does | | - | - | - | | [Newsletter signup widget](/docs/platform/newsletter-widgets) | Yes | Nothing is stored until the link in the confirmation email is clicked. Clicking it subscribes an existing member or contact, or creates a new contact with the source recorded as newsletter | | Registration, donation checkout, event checkout, public form | No | A checkbox reading "I want to subscribe to the newsletter". It subscribes at the moment the transaction completes | | [Import](/docs/platform/customization/import) | No | An `is_newsletter_subscribed` column on the contact import | | Administrator | No | **Subscribe** on the Newsletter card of the contact record | The signup widget is the only path with a confirmation step. An address that never clicks the link is never subscribed, never appears in the contacts list through that route, and never appears in the widget's **Subscribers** panel. On the donation page, the event checkout and public forms, the subscribe checkbox is ticked by default. An event or a payment page can hide it entirely through its own settings, in which case that checkout subscribes nobody. The embeddable **contact form** deliberately subscribes nobody. A submission creates or fills in a contact so you can reply, and leaves the newsletter field exactly as it found it. Writing to you is not consent to be marketed to, and the form's own consent checkbox covers the reply only. An import can raise a contact from "never asked" to subscribed, but it will not push an already subscribed contact back down: a false value in the file is ignored for an existing subscribed contact. Use the record, or the unsubscribe paths below, to remove someone. *** ## Unsubscribing Every campaign carries an unsubscribe link, and Orgo appends one to the footer if your design has no placeholder for it. The same emails carry one-click unsubscribe headers, so a mail client can offer its own unsubscribe button. The link does not act on the click itself. It points at Orgo, which records nothing and redirects the browser to an unsubscribe page on your organisation's address. That page then makes the change: for a contact, who is never signed in, it completes on arrival and confirms; for a signed-in member it offers a choice between the newsletter and all notifications. Because the address in the email only produces the redirect, a mail client or security scanner that pre-fetches links cannot opt anybody out. The link is also replaced after each use, so a link forwarded from an old email cannot be replayed. An administrator can do the same from the record: **Unsubscribe** on the Newsletter card. Subscribing someone who previously unsubscribed asks you to confirm that you are overriding their opt-out. Both buttons need `HR_TENANT`. ### Bounces and complaints When the mail provider reports a bounce or a spam complaint, Orgo switches that address off automatically. **A bounce unsubscribes the address everywhere it appears on the platform, not only in your organisation.** The update is made by email address alone, so if the same person is a contact of three organisations on Orgo, one bounce reported to any of them unsubscribes all three. There is also no distinction between a permanent failure and a temporary one: a full mailbox unsubscribes the contact just as a closed mailbox does. Their subscription can be restored by hand once the address works again, from the Newsletter card on the record. Bounced recipients are listed on the campaign's report, and the report's CSV export gives one row per recipient per recorded action, which is where to look before deciding whether a bounce was real. *** ## Lists and segments A [list](/docs/platform/users/lists) is a saved audience, and it can hold members and contacts together. Its **profile type** is fixed when the list is created: Members & Contacts, Members Only, or Contacts Only. A contact joins a list in one of three ways: * **By hand**, through **Add** on a manual list. Adding someone already in the list is reported as skipped rather than failing. * **By CSV**, importing into a manual list. Rows are matched to an existing member or contact first, and a row that matches nothing creates a contact. * **By criteria**, on an automated list. There is no membership row at all: the list is whoever matches when it is read. Two counts appear on every list, and they answer different questions: | Count | Meaning | | - | - | | **Total** | Everyone in the list, whatever their subscription state | | **Subscribed** | The ones who explicitly opted in, which is who a campaign to that list actually reaches | A manual list built from a search will usually show a Subscribed count well below its Total, because most of the people added were never asked. A list built on event attendance is the exception: it ignores the split entirely and reports its total as subscribed, because event mail is treated as informational rather than marketing. *** ## What is recorded when consent changes **A change to the subscription field does not appear on the contact's Activity feed.** The feed shows notes, tags, donations and form submissions, but not subscribes and unsubscribes. Nothing at all is written when the change comes from the unsubscribe link, a signup confirmation, an import, a ticked box at checkout, a bounce, or an edit through the API. So the record does not answer "when and how did this person opt in, and when did they opt out". The one place a change is written down is the organisation-wide [Activity Log](/docs/platform/logs): pressing **Subscribe** or **Unsubscribe** on a contact record writes an entry there naming the administrator, the contact and the time. That log needs `ADMIN_TENANT` to read, and it covers only those two buttons. If you need to evidence how someone came to be on your mailing list, do not rely on the field: * Prefer the [newsletter signup widget](/docs/platform/newsletter-widgets). Its **Subscribers** panel lists everyone who confirmed through that widget with the date they did it, which is the only dated subscription record Orgo keeps. * Read the record's **Source** and creation date together. They tell you which path created the contact, which is a strong hint at how they arrived even though it is not a consent record. * Write a note on the contact at the time, and keep the campaign CSV exports and the [email log](/docs/platform/emails/email-log), which are dated per recipient. * Keep your own record of the wording people agreed to, since Orgo stores the answer but not the question. Orgo records what is described above and nothing more. Deciding what your organisation needs to keep, for how long, and under which rules is a question for your own advisers; using any part of the platform does not by itself make an organisation compliant with data protection law. *** ## Permissions | Action | Permission | | - | - | | Create and send a campaign, including one that reaches contacts | `COMMUNICATION_TENANT`, or `EVENT_TENANT` for event messages | | Send within one chapter | `COMMUNICATION_LOCAL` | | Subscribe or unsubscribe a contact from the record | `HR_TENANT` | | See the contacts list and its newsletter counts | `HR_LOCAL` or `FINANCIAL_LOCAL`, which every tenant-level and parent-level administrator also satisfies | | Add or remove someone on a manual list | `ADMIN_TENANT` | A chapter campaign manager, meaning someone holding `COMMUNICATION_LOCAL` and no tenant-wide communication permission, is offered only the **Members from a group** audience in the form. That is a convenience, not the control. The real control is applied when the campaign is sent: the resolved recipients are filtered down to the chapters that manager holds, whatever audience was stored, so a request made outside the interface still cannot reach another chapter's contacts. Recipient counts follow the same rule and are refused when they would not be capped. *** ## Troubleshooting Open the record and read the **Newsletter** card. Only **Subscribed** is mailed, and a contact created by a donation, a ticket or by hand usually shows **Not subscribed** because nobody asked. Then check the contact has an email address, and that they fall inside the audience you used: **Members from a group** never includes contacts. If your organisation uses chapters and the campaign belongs to one, a contact with no chapter is filtered out. Once those are ruled out, the [email log](/docs/platform/emails/email-log) and the campaign's CSV export show whether the message left and what the provider did with it. Follow-ups to non-openers are built from who received the earlier campaign, minus the people the mail provider reported as bounced, complained or unsubscribed. They do not re-read the contact's subscription field, so an unsubscribe made through the link on your Orgo page does not remove that person from the follow-up. For an audience that is checked against the field, use **All subscribed contacts** or a list. Expected. The count includes only contacts that are subscribed and have an email address, and, on a campaign that belongs to a chapter, only contacts assigned to that chapter. Open the contacts list and use the **Newsletter** filter: the counts beside All, Subscribed, Not subscribed and Unsubscribed usually explain the gap in one glance, and a large **Not subscribed** number means those people were never asked rather than that they refused. The subscription field carries no date and the contact's Activity feed does not show the change, so the record cannot tell you. If an administrator used the button on the record, the organisation-wide [Activity Log](/docs/platform/logs) has an entry with the administrator, the contact and the time. Otherwise, narrow it down from the campaigns: the CSV export on each campaign report lists unsubscribes per recipient, and a bounce or complaint on a dated campaign explains an automatic opt-out. The signup widget only stores someone once they click the link in the confirmation email. Until then there is no contact and no subscriber row. Ask the person to check their spam folder, and re-send by submitting the form again, which is refused for five minutes after the previous attempt so a double click does not send two emails. If they were already a member or a contact, confirming switches that existing record to subscribed rather than creating a second one, so look them up by email rather than by source. *** ## Related * [Newsletter](/docs/platform/newsletter) - building, sending, scheduling and reporting on a campaign * [Newsletter signup widgets](/docs/platform/newsletter-widgets) - the confirmed-opt-in form for your website * [Newsletter builder](/docs/platform/newsletter-builder) - the editor, placeholders and templates * [Email lists](/docs/platform/emails/email-lists) - how a saved audience behaves once email starts moving * [Lists & Segments](/docs/platform/users/lists) - building a list criterion by criterion * [Email log](/docs/platform/emails/email-log) - what was sent to one address and what happened to it * [Contacts](/docs/platform/contacts) - what a contact is, and how it differs from a member * [The contact record](/docs/platform/contacts/record) - every field, the Newsletter card, statuses and tags * [Where contacts come from](/docs/platform/contacts/sources) - every path that creates a contact * [Contacts and money](/docs/platform/contacts/payments) - what a contact can pay for * [Contacts at events](/docs/platform/contacts/events) - registration, badges and the Event App * [Contact permissions](/docs/platform/contacts/permissions) - who sees, edits, exports and deletes contacts * [Activity Log](/docs/platform/logs) - the organisation-wide record of who changed what # Contacts and Money Source: https://orgo.space/docs/platform/contacts/payments What a contact can pay for, where that money appears, and why a contact can never hold a membership fee **Built for** organisations who take money from people outside their membership. A contact has no login, no password and no member profile, and can still pay you for almost everything you sell. Donations, event tickets, invoices and recurring subscriptions all work with a contact as the payer. There is exactly one thing a contact can never hold, and it is the thing people most often assume they can. The Payments and Subscriptions card on a contact record, listing four donations with amount, a paid status, date, product and a one-time type, and a Record payment button *** ## A contact can never hold a membership fee Membership fees belong to members and to companies. A contact record has no fee validity date and no membership status, so no payment made by a contact can ever put them in good standing. A fee payment records a member as its payer. The practical consequence is simple. If you need any of the following for a person, that person has to be a member, not a contact: * a membership validity date and an active or lapsed status * the renewal ladder and its reminder emails * membership inherited from a company * inclusion in the paying-members figures on Insights Turning a contact into a member is a separate job with its own rules about what moves across. See [Becoming a member](/docs/platform/contacts/becoming-a-member). Do not sell a membership fee product to an address that is not a member. A fee purchase made from an email Orgo cannot match to a member does not become a fee record. Take fee money through the member's own account, or use **Mark as paid** on their **Fee** tab. See [Recording a payment made outside Orgo](/docs/platform/fees/record-payment). *** ## Money follows the email Every checkout in Orgo resolves its payer the same way, whether it is a donation page, an event ticket, an invoice or a Stripe charge. The payer's email is matched against members in your organisation. A match books the payment to that member. No member match, so Orgo looks for a contact with that email in your organisation. No contact either, so a contact is created there and then, stamped with the source that produced it (Donation, Event or Stripe), and the money is booked against it. A payment from a complete stranger is therefore never orphaned. It arrives with a contact record attached to it. This is why your contacts list grows every time you run a public campaign. One safeguard is worth knowing. When the email does match an existing member, an anonymous public checkout is not allowed to rewrite that member's name or their stored identity details. Only that member, signed in, can change them. *** ## What a contact can pay for | Type | How it happens | Notes | | - | - | - | | **Donations** | Public donation page, one-off or recurring | The donor is created as a contact at the point the payload is built, before the card is charged | | **Event tickets** | Card checkout, free registration, or pay by invoice | A contact can be the buyer, the attendee, or both, and can buy tickets for other people | | **Invoices** | An invoice raised with a contact as the payer, including event registration invoices settled by bank transfer | An invoice has one payer: a member, a contact, or a company | | **Subscriptions** | A recurring product bought without an account | Each period's charge creates a payment against the contact | | **Payments you record by hand** | **Record payment** on the contact record | Needs `FINANCIAL_TENANT` | | **Membership fees** | Not possible | See the boundary above | *** ## Where a contact's money shows up **On the contact record.** The **Payments & Subscriptions** card holds a subscriptions table and the same payments table used on member profiles, plus a **Record payment** button for money taken offline. **In your organisation-wide lists.** A contact payer appears in the payments list and in the invoice list exactly like a member, shown as a link back to the contact record rather than to a member profile. Permissions differ by action, and the server enforces them regardless of what a screen shows you. | Action | Permission | | - | - | | See a contact's payment history | `FINANCIAL_TENANT` or `HR_TENANT` | | Record a payment against a contact | `FINANCIAL_TENANT` | | Refund a contact's payment | `FINANCIAL_LOCAL` for the payment's chapter, or `FINANCIAL_TENANT` | | Generate an invoice from a payment | `ADMIN_TENANT` | A chapter-level financial or HR permission on its own is not enough to open a contact's payment history. That list is an organisation-level view. A contact with any payment, invoice or signed document attached cannot be deleted, individually or through bulk delete. The money records would be left without a payer. *** ## Recurring payments by a contact Recurring works. A contact can hold a subscription, the card is charged every period, and each charge is written as a payment against the contact and shows on their record. Renewal notice emails are sent for subscriptions owned by members. A contact on a recurring donation or subscription is charged every period without receiving one. Plan for that. Say on the donation page how often the card will be charged and how to stop it, and check the subscriptions on the contact record when someone queries a charge they did not expect. *** ## Company membership A contact can be added to a company and given any of the company roles, including **Primary Contact**, and can carry a joined date. They appear in the company's **Team Members** panel and link back to the contact record. **A contact consumes one of the company's seats.** The seat allowance comes from the plan the company bought, and a contact row counts against it in the same way a member row does. What a contact does not get from the company: * **Membership validity.** When the company pays, its valid-until date is copied to members who have an account. A contact has no fee date to receive, so it is skipped. A contact inside a fully paid-up company is still a non-member. * **Any company power.** Roles held by a contact are stored and displayed but grant nothing, because company permissions are exercised by signing in and a contact cannot sign in. A contact who is the Primary Contact cannot administer the company, edit it, or manage its payments. Note the current behaviour of the company screen: **Remove** and the role controls on the **Team Members** panel act on member rows. A contact attached to a company cannot be removed from the company or given a different role from there, while still counting toward the seat allowance. Company mechanics in full: [Companies](/docs/platform/users/companies). *** ## Refunds Refunding a contact's payment is the same job as refunding a member's, with the same button, the same permission and the same result. The money goes back through Stripe, the payment is marked refunded, and any event tickets bought with it are cancelled so the places return to sale. The only difference is what a refund unwinds afterwards. A member refund rolls their membership validity date back. A contact has no validity date, so there is nothing to roll back and nothing happens. A refund on a contact-payer invoice marks the payment refunded and stops there. *** ## Reporting: the figure that misleads This one costs people a board meeting. * **Revenue totals include money paid by contacts.** Every successful payment counts, whoever paid it. * **The paying-members count does not.** It counts members with a membership fee period covering the date being reported. Contacts are excluded, and so is every purchase that is not a membership fee. So dividing revenue by paying members does not give you average revenue per paying member. In an organisation with a busy donation page or public ticket sales, the two numbers describe different populations and the result can be wildly overstated. Use revenue by product type, or the **Finance** tab, when you want to understand where money comes from. See [Insights](/docs/platform/insights). *** ## Troubleshooting The payer used an email address that does not match their member record, so the member lookup missed and a contact was found or created instead. The payment stays where it was booked. Merging that contact into the member moves their payments, subscriptions, invoices and identity records across. **Create user account** may do the same thing, but only when your organization creates admin-made accounts as Active, which is the default. On that setting the matching contact is folded into the new member and removed. On any other setting the contact is left behind with the money still on it. Merge is the reliable route, because it shows you what will move before you commit and can be undone. See [Becoming a member](/docs/platform/contacts/becoming-a-member). Check whether the payer is a member or a contact. A payment booked to a contact never produces membership validity, whatever was bought. If they should be a member, make them one and record the fee on their **Fee** tab. Contact rows in a company count toward the seat allowance, and the **Remove** and role controls on the **Team Members** panel act on member rows. If the company needs more room, the seat count comes from the plan it bought, so a plan with more slots raises the allowance. Expected behaviour. Renewal notices are sent for member-owned subscriptions. The charge itself is recorded normally and appears on the contact record. A payer who completes checkout without giving an email cannot be matched to anything, so a fresh contact with no name and no email is created for each payment. Ask for an email on the checkout if you want payers to accumulate on one record. *** ## Related * [Contacts](/docs/platform/contacts) what a contact is and how the module is switched on * [Becoming a member](/docs/platform/contacts/becoming-a-member) merging a contact into a member and what moves * [Contacts and events](/docs/platform/contacts/events) tickets, attendance and the event app * [Donations](/docs/platform/fees/donations) donation pages, one-off and recurring giving * [Stripe integration](/docs/platform/fees/stripe-integration) taking card payments online * [Invoices](/docs/platform/fees/invoices) raising and settling invoices * [Recording a payment made outside Orgo](/docs/platform/fees/record-payment) bank transfer, cash and cheque * [Membership fees](/docs/platform/fees/fees) how fee periods and validity dates work * [Companies](/docs/platform/users/companies) corporate membership, seats and inherited validity # Contact Permissions & Data Protection Source: https://orgo.space/docs/platform/contacts/permissions Who can see, edit, export and delete contacts, and what the product does and does not give you for a data-protection request Contacts hold personal data about people who never signed up for an account: donors, ticket buyers, newsletter subscribers, form respondents. This page answers two questions. Who on your team can reach that data, and what can you actually do when one of those people asks you about it. **Built for** the administrator who decides who is trusted with the contact list, and the person who has to answer a data-protection request with the tools the product really has. This page assumes the permission model on [Permissions](/docs/platform/permissions): every permission is a domain (HR, Financial, Admin) paired with a scope (organisation, regional, chapter). Only the contact-specific parts are covered here. Contacts module settings showing the Enable Contacts Module, Enable Contact Statuses and Enable Per-Chapter Contacts switches *** ## What each action needs | Action | Permission required | | - | - | | View the contact list | HR or Financial, at any scope (see the nine below) | | Open one contact record | The same, and the contact must be in a chapter you cover | | Create a contact | HR or Financial, at any scope | | Edit a contact | The same, on that contact | | Delete one contact | The same, on that contact | | Bulk delete from the list | HR or Financial, at any scope | | Export the contact list to CSV | `HR_TENANT` or `ADMIN_TENANT` only | | Manage tags on a contact | `HR_TENANT` or `ADMIN_TENANT` | | Subscribe or unsubscribe a contact from the newsletter | `HR_TENANT` or `ADMIN_TENANT` | | Email contacts | Communication Manager, through a campaign. There is no per-contact send | | Write a note on a contact | HR or Financial, on that contact | | Edit or delete a note | The note's author, or `ADMIN_TENANT` | | Reveal a stored personal identification number | `HR_TENANT`, `FINANCIAL_TENANT` or `ADMIN_TENANT` | Emailing is not a contact permission at all. Contacts are reached in bulk through [newsletter campaigns](/docs/platform/newsletter), which are governed by the Communication Manager domain. Someone can hold Communication Manager and send to your whole contact audience without ever being able to open a single contact record, and the reverse is equally true. *** ## The permission line is wider than it looks Every contact screen asks for the same thing: HR or Financial permission on the chapter. Written out, that sounds like two narrow chapter-level grants. It is not. Because a permission held higher up satisfies a check lower down, and because Admin covers the other domains at the same level, **nine different permissions open the contact list**: | Permission | Why it satisfies the check | | - | - | | `ADMIN_TENANT` | Passes every permission check in the product | | `HR_TENANT` | Organisation scope satisfies the same domain at chapter scope | | `FINANCIAL_TENANT` | The same, on the Financial side | | `ADMIN_PARENT_LOCAL` | Admin covers every regional and local permission in its branch | | `ADMIN_LOCAL` | Admin covers every local permission in its chapter | | `HR_PARENT_LOCAL` | Regional HR includes chapter HR | | `HR_LOCAL` | Named directly by the check | | `FINANCIAL_PARENT_LOCAL` | Regional Financial includes chapter Financial | | `FINANCIAL_LOCAL` | Named directly by the check | Granting a permission that sounds unrelated to contacts still grants the contact list. `ADMIN_LOCAL` for a chapter secretary, `FINANCIAL_PARENT_LOCAL` for a regional treasurer, `HR_TENANT` for a membership officer: all three open contacts. If the contact directory holds donor or subscriber data you would not hand to those people, decide that before you tick the box, not afterwards. **HR Assistant does not reach contacts.** It is the one HR-family permission that does not, and holding it changes nothing about the contact module. Event Manager and Communication Manager do not reach contacts either. *** ## Ordinary members cannot reach contacts A member with no administrative permission has no route to the contact directory: not the list, not a record, not search, not export. There is no minimum access level setting that opens contacts to regular users, and nothing in the member-facing product links to them. Contacts are an administrative surface only. *** ## Chapter scoping A contact can be filed under a chapter, and chapter administrators can then be limited to their own. This needs **two** settings switched on together: | Setting | Where | | - | - | | **Local Centers** module | **Settings** → **Modules** | | **Enable Per-Chapter Contacts** | **Settings** → **Modules** → **Contacts** | Both on, and scoping applies: * Organisation-scope managers (`HR_TENANT`, `FINANCIAL_TENANT`, `ADMIN_TENANT`) see every contact, including contacts with no chapter. * Everyone else sees only contacts in the chapters they cover. Someone who covers no chapter sees an empty list rather than an error. * Creating a contact files it under the creator's own chapter by default, and a chapter-scoped admin cannot file one outside the chapters they cover. * Editing is re-checked after the change, so a chapter admin cannot move a contact out of their scope or leave it unfiled. **With Per-Chapter Contacts off, chapter-scoped administrators get no contacts at all**, rather than a scoped view. `HR_LOCAL` and `FINANCIAL_LOCAL` holders are refused the list, the record and every write. Only organisation-scope managers keep access. Turning the setting off to "simplify things" therefore removes contacts from your chapter teams entirely. **A contact with no chapter is invisible to chapter administrators**, even with the setting on. Contacts created by donations, ticket sales and newsletter signups usually arrive unfiled, so on a scoped organisation most incoming contacts are visible only to organisation-scope managers until someone files them. *** ## CSV export, and what is recorded Export is the one contact action that does not follow the nine-permission rule. **It requires `HR_TENANT` or `ADMIN_TENANT`.** A chapter or regional administrator who can read every contact on screen still cannot export them, and adding a chapter filter to the request does not change that. Every export writes a row to the [Activity Log](/docs/platform/logs) recording who exported, when, and the exact request that was made, including any filters. That is your record of who took a copy of the directory. The same data pulled another way is not recorded the same way. Reading contacts through the [API](/docs/platform/api) or through an assistant on the [Orgo MCP connection](/docs/platform/mcp) is an ordinary read of the contact list: it leaves no export entry, because no export happened. If your controls depend on knowing when the directory left the product, treat API tokens and connected apps as their own control point, and scope them narrowly. The report builder is a second export route. It is `ADMIN_TENANT` only, it can include contacts and their payments, tags and custom fields, and its exports are recorded too. See [Reports](/docs/platform/reports). *** ## Data protection Below is what the product does and does not do with contact personal data. Read it as a description of the mechanics, not as advice about your obligations. ### What is stored A contact record holds name and middle name, email, phone, address, town and country, date of birth, gender, a personal identification number, a bio, employer and role, social profiles, company details, tags, status, source, notes, custom field answers, and links to payments, invoices, form submissions and event registrations. **Of everything on a contact, only the personal identification number is encrypted at rest.** Email, phone, address, date of birth and gender are stored as ordinary text. Individual custom fields can be marked as encrypted, one field at a time, but that is opt-in and off unless someone set it. The personal identification number is never returned by the normal record; the record only says whether one exists. Reading the value has a single door, restricted to `HR_TENANT`, `FINANCIAL_TENANT` and `ADMIN_TENANT`, and every reveal is recorded with who did it, when, and from where. If that record cannot be written, the reveal is refused. ### Identity documents An identity record can be attached to a contact, carrying an identification number, the document type, serial, number and dates, an address, a date of birth, and scanned images of the document itself. These usually arrive through the flows described in [Identity Validation](/docs/platform/identity-validation). Treat any contact with an attached identity as holding considerably more sensitive data than the record on screen suggests. ### What you can do for a data-protection request * **Produce a copy of what you hold.** There is no "download everything about this person" button. What exists is the contact record itself, which shows notes, activity, payments, invoices, event registrations and custom field answers on one screen, and the CSV export, which covers the directory fields but not notes, payments or emails. Assembling a full answer means reading the record and copying from it. * **Correct data.** Edit the record, in the normal way. * **Stop email.** Unsubscribe the contact, or let them use the unsubscribe link in any campaign. This does not remove the record. * **Clear the personal identification number** by saving an empty value on the record. * **Delete the contact**, subject to the limit below. ### What the product does not do * **There is no anonymisation.** Nothing replaces a contact's details with placeholders while keeping the record. Deletion is a real deletion of the row, not a flag, and it cannot be undone. * **Deletion is refused while the contact has any payment, invoice or contract.** There is no option to erase the person and keep the financial record. For most organisations this means a contact who has ever paid you anything, a donor, a ticket buyer, an invoiced partner, **cannot be deleted at all**, and those are exactly the people most likely to ask. The only contacts you can delete are ones with no money and no signed document attached. * **Deleting a contact destroys their activity history with them**, including the records of who exported the contact list containing them and who revealed their personal identification number. Export anything you need to keep before deleting. * **Deletion does not reach data already sent elsewhere**, such as email logs, records synced to a connected CRM, or payloads already delivered to your webhooks. * **There is no retention policy and no automatic expiry.** Contacts, notes and log entries stay until somebody removes them. Nothing ages out on its own. * **Consent is a single switch.** Newsletter subscription is subscribed, unsubscribed, or never asked. There is no consent timestamp, no record of where consent came from, and no per-purpose consent on a contact. Your organisation is the data controller for everything in your contact directory. Orgo gives you the mechanics described above and nothing more; deciding what you may collect, how long you may keep it, and how you answer a request from a data subject is yours to determine, with your own legal advice. Nothing on this page is legal advice and no feature described here makes an organisation compliant with any law. *** ## What is recorded about a contact Some, but not all, of what happens to a contact is written to the audit log. | Recorded | Not recorded | | - | - | | Changes to name, email, phone, town, date of birth, gender, chapter, photo and the social profile fields | Changes to address, company fields, bio, status, source, custom field answers and the newsletter flag | | CSV exports of the directory, with the exporter and the full request | Reads: opening a record leaves no trace | | Personal identification number revealed, changed or exported | Creating a contact | | Newsletter subscribe and unsubscribe | Deleting a contact | | Tags added and removed, and notes deleted | | Two more limits are worth knowing. Nothing is logged for changes made by an import, by an automation, or by any unauthenticated flow such as a public form or a donation checkout, so a field that changed by itself changed through one of those. And demo organisations write no log entries at all. **The field-change history is written, but no screen presents it.** The Activity card on a contact record deliberately leaves field edits out; it shows notes, tags, donations, form submissions and personal identification number changes. The [Activity Log](/docs/platform/logs) screen, which does show before and after values, exists for members and not for contacts. So "who changed this contact's email address" is recorded but not answerable from the product interface. *** ## Troubleshooting Check the two settings first. Chapter scoping needs the **Local Centers** module and **Enable Per-Chapter Contacts** switched on together. With Per-Chapter Contacts off, chapter-scoped administrators are refused contacts outright rather than given a scoped view, which looks identical to a permission problem. With both on, check what they hold. HR Assistant does not reach contacts, and neither does Event Manager or Communication Manager. They need HR, Financial or Admin at chapter, regional or organisation scope. If they hold the right permission and the list is still empty, the contacts probably have no chapter. Unfiled contacts are invisible to chapter-scoped administrators, and contacts created by donations, ticket sales and signups arrive unfiled. An organisation-scope manager can open those and file them. Deletion is refused while the contact has any payment, invoice or contract attached, and there is no way to override it or to erase the person while keeping the financial record. This is the expected behaviour, not a fault, and it applies to every donor and ticket buyer. If the request came from the person themselves, what you can do instead is unsubscribe them from email, clear the personal identification number, and remove notes and any detail you do not need to keep. The record and its financial history stay. A bulk delete from the list can also stop on the same rule. If a selection includes one contact with a payment, deal with that one separately rather than retrying the batch. Every CSV export writes an entry to the [Activity Log](/docs/platform/logs) naming the person, the time, and the exact request including any filters. Reading that log needs `ADMIN_TENANT`. Report builder exports are recorded too. Two gaps to keep in mind. Contacts pulled through the API, a connected app or an assistant over MCP are ordinary reads and produce no export entry, so the log answers "who used the export button", not "who has a copy". And deleting a contact deletes the export entries that mention them, so a log reviewed after a clean-up may be missing rows. Ordinary members have no access to the contact directory, so check what the member actually holds on their **Permissions** tab. `ADMIN_LOCAL` and `FINANCIAL_LOCAL` both open contacts even though neither is labelled HR, and a permission attached to their role counts the same as one ticked on their profile. See [Assigning Permissions](/docs/platform/permissions-assigning). If they hold nothing, they are almost certainly seeing a contact through another feature rather than through the directory: as an attendee on an event they can see, as a name on an invoice, or mentioned in a discussion. Those surfaces have their own visibility rules and show far less than a contact record does. *** ## Related * [Contacts](/docs/platform/contacts) - what a contact is and how the module is switched on * [Permissions](/docs/platform/permissions) - the domains and scopes this page builds on * [Assigning Permissions](/docs/platform/permissions-assigning) - granting and checking what someone holds * [Local Groups](/docs/platform/groups/local-groups) - chapters, regions, and what a scoped grant reaches * [Profile Activity & Notes](/docs/platform/users/profile-activity) - the Activity card on a contact record * [Activity Log](/docs/platform/logs) - where export and audit entries are read * [Identity Validation](/docs/platform/identity-validation) - identity documents attached to a contact * [Reports](/docs/platform/reports) - the second export route, and who can use it # The Contact Record Source: https://orgo.space/docs/platform/contacts/record Every field on a contact, how statuses, tags and custom fields work, and what the record page and the contacts list show A contact record is deliberately thinner than a member profile. It holds who the person is, how to reach them, where they came from, and whatever your organisation added on top through statuses, tags, custom fields and notes. It holds no login, no roles, no unit membership and no membership fee. **Built for** the person who has to keep the donor and subscriber list accurate. **Replaces** the columns you would otherwise invent in a spreadsheet. This page is the field-level reference. For what a contact is and how it differs from a member, start at [Contacts](/docs/platform/contacts). A contact record showing the contact information card with source and dates, the newsletter card, tags, the status pipeline, the payments card, e-documents and email logs *** ## Identity | Field | Notes | | - | - | | **Name** | One combined field. Required by the Add Contact form. | | **Middle name** | Shown when your organisation collects it at checkout, or when the contact already has one. | | **Email** | Lower-cased and stripped of stray spaces on save. Not required, and not unique. | | **Phone** | A single free-text field, not split into country code and number. | | **Gender** | Female, male, or other. | | **Date of birth** | Displayed with the current age beside it. | | **Personal identification number** | Stored encrypted. Only `HR_TENANT` and `FINANCIAL_TENANT` see the field, it is masked until revealed, and every reveal is logged. | | **Bio** | A short free-text description. | | **Photo** | Uploaded on create, or from the record's edit mode. | ### One name field, split on demand There is no first-name and last-name pair on a contact. There is one **Name** field, and Orgo derives a first and last name from it by splitting on spaces whenever something needs them separately, taking the first word as the first name and the last word as the last name. This is why imported names sometimes split oddly. "Maria del Carmen Ruiz" gives a first name of "Maria" and a last name of "Ruiz"; "Ruiz, Maria" gives a first name of "Ruiz,". Nothing is lost, because the full string is what is stored and displayed, but anywhere a first name is used on its own (a personalised email greeting, for example) will show the split, not your intention. Fix it by editing the **Name** field into the order you want. A contact created with an email address but no name is filed under the email address as its name. That happens on automatic capture paths such as a newsletter signup, so a list of contacts whose names look like email addresses usually means those records arrived without a name, not that anything went wrong. *** ## Social profiles | Field | Format | | - | - | | **LinkedIn URL** | Full URL, `https://www.linkedin.com/in/username` | | **Twitter URL** | Full URL, `https://twitter.com/username` | | **Instagram URL** | Full URL, `https://www.instagram.com/username` | | **Bluesky** | The handle, `handle.bsky.social` | The record page shows these as icon links. With none of them filled in, the card reads "No social profiles added". *** ## Address | Field | Notes | | - | - | | **Town** | Chosen from Orgo's town list, not typed freely. | | **Country** | Not entered directly. It is shown read-only, taken from the town. | | **Chapter** | The local center the contact belongs to. Only present when **Enable Per-Chapter Contacts** is on. | There is no personal street address field on the contact form. The address you can record is the **Company address** in Billing Details below, which is what invoices use. When a contact has no country of its own, the record and the list display the country of its town instead. The **Country** column in the list can therefore show a value that was never set on the record itself. Sorting and filtering by country read the stored field, so a contact showing a country by way of its town will not appear under that country in a filtered list. *** ## Organisation and role Two blocks, filled in by hand. **Professional Info** | Field | Holds | | - | - | | **Current Organisation/Company** | Where the person works or volunteers | | **Current role** | Their job title there | **Current role** is a job title, not a permission. Contacts have no permissions at all, and nothing you type here grants access to anything. If you want someone to be able to sign in, they need a member account. See [Becoming a member](/docs/platform/contacts/becoming-a-member). **Billing Details** | Field | Holds | | - | - | | **Company identifier** | The registration identifier. The search button next to it looks the company up and fills in the three fields below. | | **Company name** | Legal name for invoices | | **Company address** | Billing address | | **Company commerce registry number** | Registry number for invoices | | **Stripe customer** | Read-only. Present once the contact has paid you through Stripe, and links straight into your Stripe dashboard. | *** ## Provenance Every contact carries a **Source**, set once when the record is created and never changed afterwards. It is shown as a coloured tag on the record and as a sortable column in the list. | Source | Created by | | - | - | | `manual` | Someone adding the contact by hand | | `import` | A spreadsheet import | | `form` | A form submission | | `contact-form` | An embedded contact form on your website | | `newsletter` | A newsletter signup | | `event` | An event registration without an account | | `donation` | A donation checkout | | `stripe` | A Stripe customer arriving through a payment | | `contract` | Signing a document through a contract link | | `system` | Created by Orgo itself as a side effect of another action | Contacts created by an import also keep a link back to that import, which is what lets an import be rolled back. What each source fills in is covered in [Where contacts come from](/docs/platform/contacts/sources). *** ## Status and dates The contact statuses settings screen listing the tenant defined statuses with their colours and drag handles for reordering | Field | Notes | | - | - | | **Status** | One value from your own list. See [Statuses](#statuses) below. | | **Last status update** | Stamped whenever a status is set. Clearing a status back to none leaves the old timestamp in place. | | **Created at** | When the record was created, not when the person first heard of you. | | **Last update** | The last time any field on the record changed. | | **Newsletter** | Subscribed, Unsubscribed, or Not subscribed for someone who was never asked. Changed from the Newsletter card, never from the edit form. See [Newsletter and contacts](/docs/platform/contacts/newsletter). | *** ## Duplicate email addresses are possible **Email is not unique on a contact.** There is no database constraint on it, not even within one organisation, so the same address can appear on two or more contact records at once. This is normal data cleaning, not an error state. Duplicates arise because only one path checks for them. The **Add Contact** form refuses an email that already belongs to a contact or a member, and offers to update the existing record instead. Every other path writes without that check: * Spreadsheet imports * Newsletter signups and embedded contact forms * Event registrations, donations and other checkouts * Records created by Stripe or by contract signing A second reason is the name split described above: a nameless capture is filed under its email address, so the same person can end up once as "Ana Popescu" and once as "[ana@example.com](mailto:ana@example.com)". Clean them up with the merge tool, which finds duplicates by identical email address and by identical name, and folds one record into the other so the payments, tickets and documents on both end up on the record you keep. See [Merging duplicates](/docs/platform/users/merging-duplicates). Deleting one of two duplicates is not the same as merging them. Deletion is refused while the contact has any payment, invoice or signed contract, and where it does go through it takes the record's whole history with it. Merge first, delete second. *** ## Statuses A contact status is a label you define, not a fixed list Orgo ships. Think of it as a pipeline stage: New lead, Contacted, Qualified, Lapsed, whatever your team actually says out loud. Each status has three properties: | Property | Notes | | - | - | | **Name** | Required. Free text. | | **Colour** | Required. Chosen from a palette, and used for the tag everywhere the status is shown. | | **Order** | Set by dragging rows into the sequence you want. The record page renders the list in that order as a left-to-right pipeline. | ### Defining the list **Settings** → **Modules** → **Contacts** → **Contact Statuses**. Add rows, edit a name or colour in place, drag to reorder, and delete the ones you stop using. The list stays editable, so you can rename or reorder at any time. Deleting a status does not delete the contacts that held it; those records simply go back to having no status. Everywhere a status can be chosen, an organisation with none yet gets a **"No statuses. Manage Statuses"** link straight to this page. ### Setting a status on a contact Two places, and both save immediately: * On the record page, click a chip in the status pipeline. A short toast confirms. * In the contacts list, click the status tag on a row and pick from the dropdown. This is the fastest way to work through a batch of contacts. Statuses are gated by **Enable Contact Statuses** under **Settings** → **Modules** → **Contacts**. It is on by default. With it off, the status field, the status column and the status filter all disappear, and nothing is deleted. Contact statuses are a separate list from member statuses, which are fixed and decide whether someone can sign in. See [User Statuses](/docs/platform/users/statuses). *** ## Tags Tags are the multi-choice counterpart to the single-choice status. One contact can carry as many as you like. * **The tag catalogue is organisation-wide**, and it is shared with members. The same tag can sit on a contact and on a member, so you can filter both populations by it. * **Casing does not create duplicates.** Orgo normalises each tag name and keeps one entry per organisation, so "Volunteer", "volunteer" and " Volunteer " are the same tag, not three. * **Assignment is per contact.** Open the Tags card, type to search, and pick. The X on a chip removes it. | Action | Permission | | - | - | | Add a tag to a contact, or remove one | `HR_TENANT` | | Create a new tag name in the catalogue | `ADMIN_TENANT` | The two are separate. Someone with `HR_TENANT` can tag contacts all day using tags that already exist, but typing a name that is not in the catalogue yet and pressing Enter will be refused. Ask an organisation administrator to add the tag once, then everyone can use it. Tags are also written automatically by [workflows](/docs/platform/workflows), which can add or remove a tag as an action, and each of those changes is recorded on the contact's activity feed. *** ## Custom fields Custom fields are how you record anything Orgo has no column for. They are defined once under **Settings** → **Users & Profiles** → **Custom Fields** and reused across members and contacts. **Only profile fields attach to a contact.** A custom field belongs to one of several groups depending on where it was created; the profile group is the one that reaches a person's record. Fields built for a specific form stay on that form and never appear on a contact. There is one exception by design: the local center field type is form-only, because a contact already has a Chapter field of its own. Which profile fields appear on the contact form is decided by your profile form configuration, and the read-only **Additional information** card on the record only shows fields that actually have a value, so a contact with no answers has no card. **Field types available:** Input text, Input numeric, Textarea, Dropdown, Checkboxes, Radio choice, Switcher (True/False), Date and File Upload. **Visibility levels:** every field is Public, User or Admin, which controls who can read and write the value. **Encryption:** a small number of free-text fields per organisation can be encrypted at rest. The cap is five, and only Input text, Input numeric, Textarea and Date fields qualify. Choice, switch and file fields cannot be encrypted. All three of those are explained in full, with the exact rules on who can read what, on [Custom Fields](/docs/platform/users/custom-fields). *** ## Notes and activity Two cards that work together. **Notes** is what your team writes about the contact: what was said on the call, what to do next. Each note records its author and the time, is capped at 512 characters, and can carry an optional **Called** or **Emailed** action. The author of a note can edit or delete it, and so can `ADMIN_TENANT`; nobody else can change someone else's note. **Activity** is the feed underneath, merged newest first. It combines the notes with things Orgo records on its own. | Recorded automatically | When | | - | - | | Tag added or removed | Any time a tag changes, whether by hand or by a workflow | | Newsletter subscribed or unsubscribed | Only when an administrator uses the subscribe or unsubscribe button on the record, and only in the organization-wide activity log, not on this feed. See [Contacts and the newsletter](/docs/platform/contacts/newsletter) | | Profile field edited | Any change to a field on the record | | Personal identification number revealed | Every reveal, with who revealed it | | Personal identification number changed | Every change to the stored value | | Note deleted | So a removed note leaves a trace | | CSV export | Every export of the contacts list | | Merge and rollback | On both records involved | Donations and form submissions the contact made appear in the same feed, so the card reads as one running story rather than an audit dump. Profile field edits are recorded but are not shown in the feed, which is deliberate: a record edited in ten fields would otherwise bury the notes. The entries exist for auditing, so ask an organisation administrator if you need to see them. **Who can write and read:** `HR_LOCAL` or `FINANCIAL_LOCAL` over that contact, or `ADMIN_TENANT`. Both cards sit behind **Enable Profile Notes & Activity** under **Settings** → **Modules** → **Users & Profiles** → **Configuration**, which is **off** until you switch it on and needs `ADMIN_TENANT`. Switching it back off hides the cards and closes the endpoints behind them, but deletes nothing: existing notes reappear with their authors and dates when it goes back on. Full detail: [Profile Activity & Notes](/docs/platform/users/profile-activity). *** ## The record page Open a contact from the list and you get a modal; the maximise control and the `/contacts/show/` URL give you the same content as a full page. **There are no tabs.** The record is one scrolling page of cards in two columns, which stack into a single column on a phone. Several cards hide themselves when they have nothing to show, so not every contact displays every card below. Left column, top to bottom: 1. **Contact info** with the **Edit** button that turns the whole card into the form 2. **Status** (on a phone only, so it stays near the top) 3. **Newsletter**, with a single Subscribe or Unsubscribe button 4. **Social profiles** 5. **Tags** 6. **Notes** 7. **Activity** 8. **Additional information**, the custom field answers 9. **Create user account** and **Delete contact** buttons Right column, top to bottom: 1. **Status**, as a left-to-right pipeline of chips 2. **Events** the contact registered for 3. **Payments & Subscriptions**, with the subscription table above the payment list 4. **Company Membership**, when the contact is on a company account 5. **e-Documents**, when that module is on 6. **Email logs**, every message Orgo sent to this address On a phone the right column falls below the left one, and the Create user account and Delete buttons move into the menu at the top of the record. *** ## The contacts list **Contacts** in the main menu. The list is where most day-to-day work happens. ### Columns Name, Country, Town, Chapter, Email, Phone, Newsletter, Source, Status, Tags, Date created, Stripe. * **Name**, **Country**, **Town**, **Newsletter**, **Source** and **Date created** are sortable. The rest are not. * **Email** and **Phone** are icon-only to keep the row narrow. Hover to read the value, click to copy it. * **Status** is editable in place: click the tag and pick. * **Tags** are clickable, and clicking one filters the list by it. * **Chapter** appears only with **Enable Per-Chapter Contacts** on, **Status** only with **Enable Contact Statuses** on, and **Stripe** only on rows that have a Stripe customer. ### Search One box, and it matches **name and email**. It runs when you press Enter or click the search button next to it, not as you type, so a long list does not re-query on every keystroke. The X clears it and returns you to the first page. On a phone the box is behind the search icon in the header. ### Filters Four dropdowns, and they combine with each other and with the search. | Filter | Shown when | Notes | | - | - | - | | **Chapter** | Per-chapter contacts is on and you have at least one chapter | Has its own search box, and indents child chapters under their parent | | **Status** | **Enable Contact Statuses** is on | Each option carries a live count. With no statuses defined yet, the only entry links to the settings page | | **Tags** | Your organisation has at least one tag | Multi-select | | **Newsletter** | Always | All, Subscribed, Not subscribed, Unsubscribed, each with a count | Counts on the Status and Newsletter dropdowns are fetched the first time you open them, so they are current rather than cached from page load. ### Paging and bulk actions The list shows **20 rows per page** and paginates on the server, so filters and sorting apply across your whole database, not just the page you are looking at. **Select** turns on the checkboxes. Once rows are ticked, one action is offered: **delete selected**. There is no bulk tag, no bulk status change and no bulk newsletter action, so those stay one contact at a time. Bulk delete is the only bulk action, and it is not reversible. Contacts that cannot be deleted, because they have a successful payment against them, are skipped, and the confirmation tells you how many were skipped. Read that number: a batch that reports fewer deletions than you selected has left records behind on purpose. *** ## Related * [Contacts](/docs/platform/contacts) - what a contact is, and how it differs from a member * [Where contacts come from](/docs/platform/contacts/sources) - every path that creates a record, and what each one fills in * [Payments and contacts](/docs/platform/contacts/payments) - what a contact can pay for, and the membership fee boundary * [Newsletter and contacts](/docs/platform/contacts/newsletter) - the subscription field, audiences and unsubscribes * [Events and contacts](/docs/platform/contacts/events) - registration, badges and the Event App * [Becoming a member](/docs/platform/contacts/becoming-a-member) - turning a contact into an account that can sign in * [Contact permissions](/docs/platform/contacts/permissions) - who sees, edits, exports and deletes contacts * [Custom Fields](/docs/platform/users/custom-fields) - field types, visibility and encryption in full * [Profile Activity & Notes](/docs/platform/users/profile-activity) - the notes and activity feature end to end * [Merging duplicates](/docs/platform/users/merging-duplicates) - the fix for duplicate contacts * [Permissions](/docs/platform/permissions) - what each permission level unlocks # Where contacts come from Source: https://orgo.space/docs/platform/contacts/sources Every way a contact record is created in Orgo, from the import wizard to a donation checkout, and what each one fills in Most contacts are not typed in by hand. They arrive because someone bought a ticket, donated, subscribed, signed a document, or because you loaded a spreadsheet of ten years of history. Every contact records how it arrived, in a field called **Source**. **Built for** anyone who opens the contacts list and wonders where these people came from, and for the person planning a migration into Orgo. Source is a column in the contacts list and one of its filters, so it is also how you answer questions like "who came from the donation page this quarter" without tagging anyone. The import screen where a spreadsheet is uploaded and its columns are mapped onto contact fields *** ## Every way a contact is created | Source | What triggers it | What gets filled in | | - | - | - | | **Manual** | An admin uses **Add Contact** on the contacts list | Everything on the contact form, including custom fields. A chapter manager creating a contact without picking a chapter gets it filed under their own | | **Import** | A contact import runs from **Settings → Customization → Import** | Every column you mapped, plus tags and the newsletter flag when those columns are present | | **Contact form** | A visitor submits the contact form you embedded on your website | Email always. Name and phone are written on a new record, and on an existing one only where those fields are still empty. Nothing else is ever overwritten | | **Newsletter** | A visitor fills in a newsletter signup widget **and** clicks the confirmation link in the email | Email, name, subscription set to yes, and the tag configured on that widget | | **Form** | A non-member submits a form whose access is set to anyone with an email address | Email, name (first and last joined into one field), any answers you mapped onto profile fields, and the subscription flag if the opt-in box was ticked | | **Event** | A non-member registers for an event, buys a ticket, fills in a ticket details link, or is invited as an external guest | Name, email, phone, organisation, role, town, social profiles and company billing details, as far as the registration form asked for them | | **Donation** | Someone donates without signing in | Name, phone, address, plus middle name and personal identification number when the donation page collects them, and the subscription flag if they opted in | | **Stripe** | A payment or subscription arrives from Stripe for an address that matches no member and no contact | Email, name, and the Stripe customer id, which is what puts **Open in Stripe** on the record | | **Contract** | Someone outside your membership opens an e-document signing link and fills in their own details | Name, email, and whatever else the signing form collected | | **System** | Orgo itself creates the record, most often while checking whether an email address is already registered during a public signup or checkout | Email only. The name is set to the email address, and the contact is created not subscribed | Every path also stamps the date created and files the contact under your organisation. Records created before Orgo started recording provenance have an empty Source, which is why an old tenant can show a large group of blank rows in that column. The contact form and the newsletter widget are two different embeds. The contact form sends you a message and files the sender in Contacts. The newsletter widget does one thing: it collects confirmed subscribers. See [Newsletter signup widgets](/docs/platform/newsletter-widgets). *** ## The import wizard Import is how most contacts arrive, especially in the first month. It lives at **Settings → Customization → Import** and needs `ADMIN_TENANT`. Contacts go through the column-mapping wizard rather than the plain upload used by the older import steps. `.csv` and `.txt`, up to 50 MB. Comma, semicolon and tab separators are detected for you, and a UTF-8 byte order mark is stripped. A larger file is refused before it uploads, so split it and run the parts one after another. Nothing is created yet. Orgo reads the first 200 rows of the file and opens a sheet-style preview: your headers across the top, sample rows underneath, and a panel for the column you clicked. For each column you choose one of four destinations: a contact field, an existing custom field, a new custom field, or skip. Orgo suggests a destination per column and marks it **Suggested**, so a tidy spreadsheet usually needs only a few corrections. Contact fields you can map to: email, name, phone, address, organisation, role, town, country, chapter, newsletter subscription, gender, birth date, company name, company identifier, company address, company registry number, professional role, LinkedIn, Twitter, Instagram, status and tags. Each one can be filled by a single column, and the wizard tells you when two columns compete for the same field. A column that is neither a contact field nor an existing custom field can create a new one: give it a name and a type (text, long text, number, date, yes/no, dropdown, radio or checkboxes). For dropdown and radio columns you match the values in your file to the options; a value the sample missed is added as a new option while the import runs. Checkbox columns split on a separator you pick (comma, semicolon or pipe), with a live split preview. Encrypted custom fields cannot be an import target. Your mapping saves as a draft while you work, so closing the modal loses nothing. **Start import** creates any new custom fields you declared, then processes the file in the background in batches. **Discard** deletes the uploaded file and the mapping; nothing has been imported at that point. **Import History** shows a live percentage and running counts of successful, failed and skipped rows, then a per-row log with the row number, the message and the raw row data. **Email is the only required column.** Everything else is optional, so a one-column list of addresses is a valid contact import. ### Rows that match somebody you already have Matching is on the email address, within your organisation. * A row whose email belongs to an existing **member** is skipped. The member record always wins, so an import cannot split someone's history in two. * A row whose email belongs to an existing **contact** is also skipped, and the contact is left as it is. Two things still apply: tags in the file are added, and a contact who had never been asked about the newsletter is set to subscribed when the file says so. A contact who is already subscribed or has unsubscribed is never changed. * A row with a **blank email cell** has nothing to match on, so it creates a new contact every time you run that file. Re-running a file with blank emails is the one case where an import reliably produces duplicates. Because creating imports skip rather than update, re-uploading a corrected spreadsheet of names and phone numbers changes nothing and reports a large skipped count. Use the **Modify Contacts** import type instead: it matches on email, then phone, and writes only the columns you filled in. ### Rolling an import back Every completed import has a **Rollback** button in Import History, usable once. It runs as a single transaction, so it either completes or changes nothing. Rollback deletes the contacts that import created, along with the other records it created, in an order that leaves nothing pointing at a missing parent. Rollback spares contacts that already existed before the import. A record the import only touched (a tag added, a newsletter flag raised) is kept, not deleted. Custom fields and dropdown options the import created are also left in place, so a rollback followed by a corrected re-run maps onto the same fields. For a **Modify Contacts** import, Orgo stored a before-image of every row it changed, and rollback replays those values, including custom field answers. If somebody edited those records after the import, that later work is reverted too. Full mechanics of the import page, including the other seventeen import types and the order to run them in: [Data Import](/docs/platform/customization/import). *** ## Which paths subscribe someone to the newsletter Being in Contacts and being on your mailing list are different things. Only contacts marked **Subscribed** receive campaigns. | Path | Subscribes them? | | - | - | | Newsletter signup widget | Yes, and only after they click the confirmation link | | Public form with the newsletter opt-in ticked | Yes, immediately | | Event registration with the opt-in ticked | Yes, immediately | | Donation checkout with the opt-in ticked | Yes, immediately | | Stripe checkout carrying a newsletter choice | Yes, immediately | | Import, where the file has a newsletter column | Yes for new contacts; for existing ones only from "never asked" to subscribed | | Manual creation | Only if you set the field yourself | | **Embedded contact form** | **No, never** | | Email-availability check (`System`) | No, the contact is created unsubscribed | Two of those deserve spelling out. **The contact form deliberately subscribes nobody.** Writing to you is not consent to be marketed to, and the consent checkbox on that form covers replying to the message. The sender lands in Contacts so you have their details and their history, with the newsletter field left exactly as it was: untouched on an existing contact, and never asked on a new one. If you want those people on the list, ask them separately. **The newsletter widget is the only double opt-in path.** Nothing is created when the form is submitted. Orgo stores a pending signup, emails a confirmation link, and only creates or subscribes the contact when that link is clicked. Every other path above is a single checkbox at the moment of a transaction. Details of consent, unsubscribes and bounces: [Newsletter](/docs/platform/newsletter). *** ## Duplicates, honestly Contacts are matched by email address, and nothing in the database prevents two contacts sharing one. Every check happens as the record is created, and those checks are good but not perfect. What is handled: **capitalisation**. `Anna@example.org` and `anna@example.org` are the same person to every lookup in Orgo. What still slips through: * **Punctuation and spacing variants.** Some paths, notably paid event checkout and the ticket details link, look the address up exactly as typed, so `anna..s@example.org` misses the stored `anna.s@example.org` and creates a second record. The import path normalises before it looks up, so it does not have this problem. * **Extra tickets on one order.** Registering a second ticket for a person who already holds an active one creates a separate contact with no email address, on purpose, so each ticket carries its own attendee details. Those records look like duplicates in the contacts list and, having no address, cannot sign in to the event app. * **Import rows with a blank email**, as described above. * **Contacts who later become members.** Creating a member account from a contact does not remove or link the contact, so the person exists twice until you merge them. The fix in every case is the same: merge the two records rather than deleting one, so the payments, tickets, documents and email history end up on a single record. [Becoming a member](/docs/platform/contacts/becoming-a-member) covers merging in full, and [Merging duplicates](/docs/platform/users/merging-duplicates) covers the equivalent for members. *** ## Choosing how to bring people in * **A backlog of history** goes through import. One file, one mapping, one rollback button if the mapping was wrong. It is the only path that can create thousands of records and undo them. * **Ongoing capture from your website** goes through the embedded contact form or the newsletter widget. Use the contact form when you want the message and the person, and the newsletter widget when you want a mailing list you can defend, since it is the only path that proves the address belongs to the person who typed it. * **Event and donation contacts arrive on their own.** You do not set anything up: someone who buys a ticket or donates without an account becomes a contact as part of the checkout, with the details that page collected. * **Add Contact by hand** is for the handful of people who reach you by phone or in person, and for filling in someone you already know is missing. *** ## Troubleshooting Compare the successful count with the skipped count in Import History. Skipped almost always means the email already belongs to a member or to an existing contact, which is the expected result when you re-run a file or when your spreadsheet overlaps your membership. Open the per-row log to see the reason for each row. If you meant to update those people rather than create them, run the file again as a **Modify Contacts** import. Check the two email addresses character by character: a stray dot, a space or a completely different address is the usual cause, since identical addresses are matched regardless of capitalisation. A second record with no email address at all is normally an extra event ticket rather than a duplicate person. Merge the records rather than deleting one, so the payments and tickets survive. See [Becoming a member](/docs/platform/contacts/becoming-a-member). Look at the Source. A contact created by the **System** path carries the email address as its name, because it was created while checking whether that address was already registered and nobody had typed a name yet. Contacts from Stripe and from event checkouts carry only what the payment or registration form asked for. Add the name by editing the record; nothing later on will overwrite it. That is by design. The embedded contact form never sets the newsletter subscription: writing to you is not consent to be marketed to. Their record shows the newsletter field as never asked. Subscribe them from the contact record if you have their consent another way, or point them at your newsletter signup widget so they confirm it themselves. Contacts are processed in batches of several hundred rows, and the progress percentage moves one batch at a time, so a small file can sit at 0% until it is done. Larger files keep running after you close the tab; come back to Import History rather than waiting. A file whose town column names places Orgo has not seen before is the slow case, as each new place name is resolved one row at a time. If an import is still processing after fifteen minutes with no counts moving at all, split the file into smaller parts and run them one after another. *** ## Related * [Contacts](/docs/platform/contacts) - what a contact is and how the directory works * [Becoming a member](/docs/platform/contacts/becoming-a-member) - merging a contact into a member account * [Data Import](/docs/platform/customization/import) - the import page in full, and the other import types * [Newsletter signup widgets](/docs/platform/newsletter-widgets) - the double opt-in embed * [Newsletter](/docs/platform/newsletter) - campaigns, consent and unsubscribes * [Forms](/docs/platform/forms) - public forms that create contacts * [Donations](/docs/platform/fees/donations) - donor records and donation checkout * [Ticketing](/docs/platform/events/ticketing) - how ticket buyers become contacts * [Custom Fields](/docs/platform/users/custom-fields) - the fields an import can create # 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 # Custom fields in an import Source: https://orgo.space/docs/platform/customization/import/custom-fields How a spreadsheet column becomes a custom field answer: mapping onto existing fields, declaring new ones, choice options, value maps and encrypted fields Most spreadsheets carry columns Orgo has no field for: T-shirt size, dietary needs, the year someone joined the old association, which committees they sit on. The import wizard can put those columns into your existing [custom fields](/docs/platform/users/custom-fields), and it can create the field for you from the column itself. **Built for** the person doing a migration who does not want to define twenty fields by hand before uploading anything, and for anyone who has watched a "Small / small / S" column arrive as three separate options. This page covers the custom field destinations only. For the sheet, the settings panel and the rest of the mapping screen, see [Mapping columns](/docs/platform/customization/import/mapping-columns). A column set to a new single choice field, with the Match values to options table pairing each value found in the file against the option it will be stored as *** ## Which imports offer custom fields Custom fields belong to people, so only the four person imports offer them: | Import type | Custom field destinations | | - | - | | **Users** | Yes | | **Contacts** | Yes | | **Modify Users** | Yes | | **Modify Contacts** | Yes | | Every other type (payments, events, roles, badges, chapters, products, companies, units, lists) | No | On the other types the settings panel offers **System field** and **Skip** only. A payment row or a badge award has nowhere to put a profile answer, so there is no third option to give you. "This type has no custom fields" and "you have not defined any custom fields yet" are different situations. On a Users or Contacts import with no profile fields defined, the **New field** destination is still offered, and the first field you declare is created when the import starts. On a payments import there is no custom field destination at all, however many fields your organisation has. The fields offered are your organisation's **profile** custom fields, the ones at **Settings** → **Users & Profiles** → **Custom Fields**. Fields belonging to a single event or to a form in the form builder are not in the list. *** ## Mapping onto a field you already have Choose **Existing field** in the column's settings panel and search your profile fields by name. The picker shows each field's name with its type beside it, and once you pick one the panel prints **Type: Single choice** under the box. **The field's type is fixed.** The wizard reads it and uses it; there is no way to change a stored field's type from the import screen, and a mapping that disagrees with the stored type is refused when it saves. If a text field should really be a dropdown, change it in Custom Fields settings first, then come back and map the column. Two custom field types cannot be filled by an import at all: **File Upload** and the chapter picker. A spreadsheet cell has no file to upload, so those fields are refused if you point a column at one. Two columns pointing at the same custom field is not blocked, and the rightmost column wins for every row. The wizard warns you when two columns claim the same **system** field, but it says nothing about a duplicated custom field. If a column's values go missing after an import, check whether a second column was aimed at the same field. *** ## Declaring a new field from the wizard Choose **New field**. The panel pre-fills the field name from your column header, which you can rewrite, and asks for a type: | Field type | What the cell should contain | | - | - | | **Text** | Anything. Stored as typed, with surrounding spaces trimmed | | **Long text** | Anything, for longer answers | | **Number** | A number. Nothing checks this, so whatever is in the cell is stored as it stands | | **Date** | `YYYY-MM-DD`, for example `2026-03-14`. Any other spelling of a date is reported as an error on that row | | **Yes / No** | `true`, `1` or `yes`, in any capitalisation, for yes. Everything else is stored as no | | **Dropdown** | One option, chosen from a list | | **Single choice** | One option, shown as radio buttons | | **Multiple choice** | Several options in one cell, separated by a character you pick | Those eight are the whole set. **File Upload** and chapter fields are not offered, for the reason given above. **Nothing is created while you are mapping.** The field is created when you press **Start import**, once, before the first row is read. Until then you can rename it, change its type or switch the column to Skip with no trace left behind. What you get is an ordinary profile custom field, indistinguishable afterwards from one you created by hand: it belongs to the whole organisation, it is listed in Custom Fields settings, and it carries **Public** visibility. It is not put on any form for you, so members are not asked the question until you add it to the [profile form](/docs/platform/users/profile-fields). It also has no position yet, so it sorts to the top of the custom fields list until you drag it where you want it. An import never creates an encrypted field. If the answers are sensitive, import them, then turn encryption on in Custom Fields settings, and read what that does to the stored values first. *** ## Choice fields: how a value finds its option Dropdown, Single choice and Multiple choice fields do not store the text in your cell. They store the option it matched. For every cell, and for every value inside a multiple choice cell, Orgo works through four steps and stops at the first that hits: If you told the wizard that this value belongs to a particular option, that decision wins over everything else. Options are stored under short keys, usually numbers. A cell whose text is exactly one of those keys matches it. `chess`, `Chess` and `Chess ` all reach the option labelled **Chess**. Anything still unmatched becomes a new option on the field, labelled with the cell's text. Two consequences are worth knowing before you run a large file. **A number in the cell can collide with an option key.** Step 2 compares your cell against the key, and keys are usually `1`, `2`, `3`. On a field whose options are labelled `2024`, `2025`, `2026`, a cell reading `2024` matches no key, falls through to step 3 and lands correctly. A cell reading `1` matches the key of the first option and is stored as **2024**, whatever you meant by it. If your column holds numbers that are answers rather than positions, map them explicitly in the value map, or use a Number field. **A value map entry pointing at an option that no longer exists is ignored.** If someone deletes or rebuilds the field's options after you set the mapping up, the entry silently stops applying and those values continue through steps 2, 3 and 4, which usually means they create a fresh option. Reopen the column and check the value map if the options have changed since you drafted the mapping. Only case and spacing are treated as the same value. `Chess.`, `chess/go` and a label with a stray non-breaking space are all different, and each becomes its own option. *** ## The value map Under **Match values to options** the panel lists every distinct value the wizard saw in that column, with how many times each appeared, and lets you say where each one goes. This is how `S`, `Small` and `small` become one option instead of three. * On a **new field**, each value starts as its own option. Rename the option in the box beside it, or choose **Merge into** and point the value at another value's option. * On an **existing field**, each value gets a dropdown of the field's current options, pre-selected by label where one matches. Leave it on **Create new option** for values you genuinely want added. The value map belongs to one column. Mapping the same values in a second column is a separate piece of work, and the two do not learn from each other. The wizard reads the first 200 rows of your file and shows at most 100 distinct values per column. When there are more, a line under the table tells you so. Values further down the file that you never saw are still imported, they simply take the four steps above without any decision from you. *** ## Multiple choice columns A Multiple choice cell holds several answers at once, so Orgo needs to know where one ends and the next begins. Under **Values in a cell are separated by** you pick one of three characters: comma, semicolon or pipe. The wizard guesses for you by looking at which character actually splits your column into values that repeat across rows, which is what stops a sentence full of commas from being read as a list. You can override the guess. Under it, **Split preview** shows a few of your sample cells broken into tags, so you can see the effect before you commit. Change the character and the preview rebuilds. Each piece is trimmed and then resolved through the four steps above. Two details follow from that: * **Repeats inside one cell collapse.** `Chess, chess, Chess` stores Chess once. The order of the first appearance is kept. * **A cell of nothing but separators stores nothing.** `,,` and `;` are treated as empty. *** ## Options created during the run Any value that reaches step 4 adds an option to the field, at the moment that row is imported. This happens on fields you created in the wizard and on fields you have had for years, and it is the reason a choice column never fails on an unfamiliar answer. Orgo will not create the same option twice. Values that differ only in case or spacing land on the option created for the first of them, whether they sit in the same batch, thousands of rows apart, or in two imports running at the same time. A file with fifty thousand rows and six spellings of "Small" produces one option, not six. New options behave exactly like ones you typed in Custom Fields settings: they are on the field for the whole organisation, they appear in the dropdown for every member and in the member directory filters, and you can rename or reorder them afterwards. Rename options rather than deleting them. Answers point at the option, not at its text, so renaming updates everyone at once while deleting leaves the answers pointing at something that is gone. *** ## Encrypted fields cannot receive imported values An encrypted custom field appears in the picker with a lock icon at half opacity and the note **"Encrypted fields cannot be filled by an import"**. Clicking it does nothing, and the column stays marked **Needs attention** until you choose a different destination. The wizard never suggests one either: a column whose header matches an encrypted field is suggested as **Skip**. The reason is plain. The import writes values straight into storage for speed, and that path does not encrypt anything on the way in. Allowing it would put readable text in a field whose whole purpose is that the text is not readable. If you have values that need to end up in an encrypted field, either collect them through a form, where the member is signed in and the value is encrypted as it is saved, or use [Identity Validation](/docs/platform/identity-validation) for identity documents, which has its own encrypted storage. *** ## An empty cell changes nothing A blank cell is left out of the row entirely. On a Users or Contacts import that simply means no answer is recorded. On **Modify Users** or **Modify Contacts** it means the value already on the record is left exactly as it was. There is no way to clear a custom field from a spreadsheet. Emptying a column and re-importing leaves every existing answer in place. To remove answers, edit the field on the profiles, or delete the field if you no longer want the question at all. *** ## What stays behind Fields and options created by an import are permanent. Once the field exists it is an ordinary part of your organisation's configuration, listed with the rest, and it stays there afterwards along with any options that were added while rows were being read. The same is true of options added to fields you already had. Practically: do a small trial run of twenty rows before loading fifty thousand. If the trial creates a field or an option you did not want, remove it in Custom Fields settings before running the real file. *** ## Troubleshooting Every value that does not match an existing option becomes one, and only case and spacing are forgiven. `Chess.` and `Chess` are two different answers as far as the import is concerned, and so are `Football/Chess` and `Football, Chess` on a single choice field. Clean the column in the spreadsheet first, or use the value map: it lists every distinct value the wizard found, and you can send each one to the option you actually want before a single row is written. On a new field, use **Merge into** to fold variants together; on an existing field, pick the option from the dropdown instead of leaving it on **Create new option**. Options already created can be renamed or removed in **Settings** → **Users & Profiles** → **Custom Fields**. Prefer renaming: answers point at the option rather than at its text, so a rename fixes every record at once. A Yes / No field accepts exactly three spellings of yes: `true`, `1` and `yes`, in any capitalisation. Everything else is stored as no, with no error, because the field has nowhere else to put it. So `y`, `Y`, `x`, `da`, `ja`, `oui` and a tick character all arrive as no. This is easy to miss because the wizard also recognises `false` and `no` when it is guessing the column's type, so a column of `da` and `nu` can look like a clean Yes / No column and still come in entirely false. Fix it in the spreadsheet: replace your yes values with `yes` or `1` and re-run the import over the same people. A modify import will correct the stored answers. The separator was wrong. If the column is split on commas but your file uses semicolons, the whole cell is treated as a single answer and an option is created with the entire string as its label. Open the column, set **Values in a cell are separated by** to the character your file actually uses, and check **Split preview** underneath: it shows your sample cells broken into tags, so a wrong separator is visible before you start. If the import has already run, delete the wrongly created options in Custom Fields settings, correct the separator and re-run the file as a modify import. That field is encrypted, and an import cannot fill it. The import writes values directly into storage without encrypting them, so the field is locked in the picker rather than quietly storing readable text in it. Map the column to a different field, or to **Skip** and collect the answers another way. See [Encrypted fields cannot receive imported values](#encrypted-fields-cannot-receive-imported-values) above. A locked field leaves the column marked **Needs attention**, which is what is stopping you from starting the import until you choose something else. Choosing **New field** always creates a new field. It does not check whether one of your existing fields already has that name, and it does not check the other columns in the same mapping, so two columns both set to **New field** with the same name produce two fields with the same name. The wizard tries to save you from this: when a column header matches an existing field by name, it suggests **Existing field** and pre-selects it. Overriding that suggestion, or renaming a new field to something that already exists, is what produces the duplicate. Before starting, read the destination line under each column header. It says **Existing field** or **New field**, so a column you expected to land in a field you already have is obvious at a glance. If a duplicate has already been created, move any answers you need and delete the spare in Custom Fields settings. *** ## Related * [Custom Fields](/docs/platform/users/custom-fields) for creating, editing and encrypting fields outside the import * [Profile Fields](/docs/platform/users/profile-fields) for putting a newly created field in front of members * [Data Import](/docs/platform/customization/import) for the wizard as a whole * [Preparing your file](/docs/platform/customization/import/preparing-your-file) for headers, separators and value formats * [Mapping columns](/docs/platform/customization/import/mapping-columns) for the sheet and the settings panel * [Linking records](/docs/platform/customization/import/linking-records) for columns that point at another record * [Import reference](/docs/platform/customization/import/reference) for the fields each import type reads # Data Import Source: https://orgo.space/docs/platform/customization/import/index Load members, contacts, events, payments, badges and companies from CSV files, mapping your own columns onto Orgo fields Import turns spreadsheets 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**. **Uploading no longer starts anything.** Your file is parked as a draft, labelled **Mapping columns**, while you tell Orgo which column goes where. Nothing is written until you press **Start import**. If you are used to the old one-click upload, this is not a failure: the draft is waiting for you, and **Continue mapping** on the step card picks it up again. The Data import page listing numbered import steps, each with a Column mapping badge, an Example CSV link and a Choose file button, with one step showing a completed run and its successful row count *** ## How an import runs Each card on the page is one import type. They are ordered so that earlier runs create the records later ones point at: structure first, then people, then the rows that link them. Cards belonging to a module you have switched off do not appear. Each card also offers an example file, which is the quickest way to see what that type can read. Pick a `.csv` or `.txt` file of up to 50 MB. Orgo reads the top of it, works out the delimiter, and opens the mapping screen on the draft it just created. See [Preparing your file](/docs/platform/customization/import/preparing-your-file). Payments, role assignments, company memberships and badge awards point at records you already have. For those, the wizard runs a sample of your rows through the columns you have chosen and shows you what each one would match, without creating anything. See [Linking to existing records](/docs/platform/customization/import/linking-records). A sheet-style view of your file, one settings panel per column. For every column you choose where its values go, and Orgo proposes a destination from the header you wrote. See [Mapping columns](/docs/platform/customization/import/mapping-columns), and, on member and contact files, [Custom fields](/docs/platform/customization/import/custom-fields). **Start import** becomes available once every required group has a column mapped to it; until then the wizard names the ones still missing. Pressing it creates any custom fields you declared, then runs the file in the background, in batches, so you can close the tab. The step card and the **Import History** table show progress while the run is going, refreshed every three seconds, with counts of successful, failed and skipped rows. Counts move one batch at a time, so a small file sits at 0% and then finishes. Expand a history row to read the per-row messages. The history keeps the 50 most recent imports. Orgo does not email you when an import finishes. Keep the page open, or come back to the history table. *** ## What you can import | Group | Import steps | | - | - | | **Structure** | Local Centers, Units, Roles, Companies, Company Members | | **People** | Users, Contacts, User Roles, Modify Users, Modify Contacts | | **Catalogue** | Products, Product Prices | | **Money** | Product Payments | | **Events** | Events, Event Attendance | | **Badges** | Badge Types, Badges, Badge Assignments | Which cards you see depends on your modules, not on your permissions: Local Centers needs the Local Centers module, Units needs **Enable Organizational Units**, the three product steps need Payments and Fees, Events and Event Attendance need Events, Companies and Company Members need Companies, and the three badge steps need Gamification. Users, Contacts, Roles, User Roles and the two modify steps are always there. The nineteenth type, **List members**, is not on this page. To add people to a manual list from a spreadsheet, open the list itself and use the CSV import inside it. See [Lists and Segments](/docs/platform/users/lists). What each type reads, which columns are required, and what it treats as the same record on a second run: [Import reference](/docs/platform/customization/import/reference). *** ## File formats **CSV and TXT only.** Orgo does not read `.xlsx` or `.xls`. If your data is in Excel, Numbers or Google Sheets, use **Save as** or **Download as** and choose CSV first, one sheet per file. The limit is **50 MB** per file. A larger one is refused before the upload starts, with "File is larger than the 50 MB import limit". Split it and run the parts one after another. Comma, semicolon and tab are all fine: Orgo works out which one your file uses. [Preparing your file](/docs/platform/customization/import/preparing-your-file) covers the rest, including where the header row may sit and how dates and yes/no columns are read. *** ## Who can run an import Every part of the import page, and every import action behind it, requires `ADMIN_TENANT`. Local, HR and financial admins do not see the Settings area at all, so importing is a tenant-admin job even for data that belongs to one chapter. *** ## Creating versus updating Sixteen of the steps only create. A row that matches a record you already have counts as **skipped**, and the existing record is left exactly as it was. A second run of the same file therefore adds very little, as long as its rows carry something to be recognised by: an email, a name, a legacy id. What counts as a match is listed per type in the [reference](/docs/platform/customization/import/reference). The two steps under **Modify existing records**, **Modify Users** and **Modify Contacts**, are the ones that write over what is already there. They match a person first, then update only the columns you filled in: an empty cell leaves the stored value alone, so a blank cannot be used to clear a field. Usernames, passwords, permissions and API tokens are never written by any 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. *** ## If you used the old importer Three habits are worth unlearning. * **Columns are chosen, not guessed.** The old page matched your headers against a fixed list of exact names, so `E-mail address` missed and `email` hit. Now you pick the destination for each column yourself, and Orgo only suggests. * **A legacy id column is no longer required.** Files that carry your old system's identifiers still work and still dedupe on them, but a file that has never had them is fine too: a member is found by email, a role or a chapter by name. * **A column you do not map is dropped.** It is not turned into a text custom field the way an unrecognised header used to be. If you want a column stored, map it, and declare a new custom field for it if there is nowhere obvious to put it. *** ## Related * [Preparing your file](/docs/platform/customization/import/preparing-your-file) - formats, headers, dates, yes/no columns and example files * [Mapping columns](/docs/platform/customization/import/mapping-columns) - the mapping screen, suggestions and what has to be filled in before you can start * [Custom fields](/docs/platform/customization/import/custom-fields) - writing into fields you have, and declaring new ones from a column * [Linking to existing records](/docs/platform/customization/import/linking-records) - how a payment finds its payer, and what the match preview is telling you * [Import reference](/docs/platform/customization/import/reference) - every import type, column by column * [Adding Members](/docs/platform/users/adding-members) - the other ways people get an account * [Where contacts come from](/docs/platform/contacts/sources) - importing contacts, and how they differ from members * [Lists and Segments](/docs/platform/users/lists) - importing people straight into a list * [Custom Fields](/docs/platform/users/custom-fields) - the profile fields an import can fill or create * [Merging Duplicates](/docs/platform/users/merging-duplicates) - cleaning up records an import doubled # Linking Records Source: https://orgo.space/docs/platform/customization/import/linking-records How the import wizard finds the member, product, role or company a spreadsheet row refers to, and how to read the match preview before you start Some files do not describe new things. They describe things that happen to records you already have: a payment made by a member, a role given to a member, a badge awarded to a member. Before Orgo can write such a row it has to find the record the row is talking about, using nothing but the text in your spreadsheet. **Built for** the migration where the payments file names payers by email and the roles file names members by whatever the old system called them. **Replaces** the guesswork of finding out after the fact which rows attached themselves to the wrong person. A payments import showing the match summary above the sheet with a tile per reference reading found, new and unmatched, and unmatched cells marked in the sheet below *** ## Reference columns and their groups In the mapping screen, the columns that point at an existing record are gathered into groups named after the thing they identify: **Payer**, **Product**, **Price tier**, **Member**, **Role**, **Unit**, **Company**, **Badge**. A group usually offers several ways to name the same record, and you map at least one column per required group. A payer can be given by legacy id, by email, or by name; a role by legacy id or by name. The chips in the footer of the mapping screen spell out the choice for you, for example **Payer: Payer email or Payer name**, and turn green once one of the alternatives is mapped. Groups marked optional, such as **Unit** on a role file, can be left unmapped entirely. Where more than one column is offered, the order matters, and the rest of this page is about that order. *** ## The match preview Once a group has at least one column mapped, a strip of tiles appears above the sheet, one tile per group, each with three numbers. | Number | What it counts | | - | - | | **found** | Rows whose reference resolved to exactly one existing record. The import will attach the row to it. | | **new contacts**, **new products**, **new price tiers** | Rows that matched nothing, but carry enough detail for Orgo to create the missing record and use it. The wording names what would be created. | | **unmatched** | Rows that matched nothing and cannot be created either, plus rows whose value matched more than one record. Both fail at import time. | The sheet marks the individual cells too: a row that would create a record is tagged **New**, and a row the chain cannot resolve is tagged **Unmatched**. The tiles describe the mapping as last saved, so they refresh a moment after each change you make and dim while the new answer is on its way. The counts are rows, not people. Five rows naming the same payer show as five under "new contacts" and produce one contact, because the creation step inserts one record per distinct person, not one per row. Read the number as "rows that will not attach to anything you already have", which is an upper bound on what gets created. The preview reads at most 20 rows from the start of your file, however large the file is. "18 found, 2 unmatched" is a verdict on 20 rows and says nothing about rows 21 onwards. A file whose clean rows happen to sit at the top previews perfectly and can still fail thousands of rows further down. Two smaller effects of the same sampling. If an optional group has no value in any of the sampled rows, its tile disappears rather than showing zeros: that means "not part of this import". And rows that leave an optional reference blank are counted in none of the three numbers, so for optional groups the three figures do not have to add up to the number of rows sampled. ### It never writes anything Running the preview reads your data and nothing else. It looks up the values in your own organisation, counts what it found, and stops. No contact, product, price tier or anything else is created while you are still on the mapping screen, and nothing at all is written until you press **Start import**. You can change the mapping and let the numbers settle as many times as you like. Unmatched rows do not block **Start import** either. They are a warning, and it is your call whether to fix the file first. *** ## How each import type finds its records Each group is tried in order, top to bottom, and the first step that finds something wins. The steps near the top are exact identifiers; the steps near the bottom are guesses at a name. ### Payments **Payer** | Order | Column | What Orgo looks for | | - | - | - | | 1 | `user_legacy_id` | A member carrying that id from your old system | | 2 | `payer_email` | A member with that email address, letter case ignored | | 3 | `payer_email` | A contact with that email address | | 4 | `payer_name`, together with `payer_email` and `payer_organisation` when they are mapped | Nothing to find. A new contact is created and the payment is booked against it | If nothing matches and the row has no `payer_name`, the row fails with **Payer not found for the supplied identifier**. Step 4 is the one that surprises people. An email that belongs to no member is not an error: Orgo creates a contact and books the payment to the contact. The money is recorded, but it sits on a contact record rather than on a member profile, and a payment held by a contact can never be a membership fee. See [Contacts and money](/docs/platform/contacts/payments). If those payers are supposed to be members, correct the email column and re-import rather than repairing afterwards. **Product** | Order | Column | What Orgo looks for | | - | - | - | | 1 | `product_legacy_id` | A product carrying that id | | 2 | `product_name`, with `product_type` when mapped | A product of that name, letter case ignored. If there is none, one is created | **Price tier** | Order | Column | What Orgo looks for | | - | - | - | | 1 | `product_price_legacy_id` | A price tier carrying that id | | 2 | `product_name` plus `price_name` plus `amount` and `currency` | A tier of that name and amount on that product. If there is none, one is created | Both groups are optional. Leave the product columns unmapped and the payment is recorded with no product attached, which is how a donation looks. Products are resolved before price tiers, so a tier can attach to a product that the same run created moments earlier. ### Role assignments | Group | Order | Column | Result | | - | - | - | - | | **Member** | 1 | `user_legacy_id` | The member with that id | | | 2 | `email` | The member with that email address | | **Role** | 1 | `role_legacy_id` | The role with that id | | | 2 | `role_name` | The role of that name, letter case ignored | | **Unit** | 1 | `unit_legacy_id` | The unit with that id | | | 2 | `unit_name` | The unit of that name, letter case ignored | Nothing is ever created here. An unknown member or an unknown role fails the row with **not found for the supplied identifier**, and the rest of the file carries on. **Unit** is optional: if the row names no unit, or names one that does not exist, the role is still assigned, without a unit. A unit name that matches two units still fails the row. ### Company memberships | Group | Order | Column | Result | | - | - | - | - | | **Company** | 1 | `company_legacy_id` | The company with that id | | | 2 | `company_name` | The company of that name, letter case ignored | | **Member** | 1 | `user_legacy_id` | The member with that id | | | 2 | `email` | The member with that email address | Nothing is created. The company and the member both have to exist already, so import your companies and your members before this file. A row naming either one wrongly fails on its own. ### Badge awards | Group | Order | Column | Result | | - | - | - | - | | **Member** | 1 | `user_legacy_id` | The member with that id | | | 2 | `email` | The member with that email address | | **Badge** | 1 | `badge_legacy_id` | The badge with that id | | | 2 | `badge_name` | The badge of that name, letter case ignored | Nothing is created. An award naming a badge you have not created yet fails, so import your badge types and badges first. ### List members Adding people to a static list is mapped like the others, with a single **Member** group offering `email`, `user_legacy_id`, `phone` and `name`. It is the one type with no match preview: the run applies its own order rather than the one the mapping declares, so a preview would tell you something other than what happens. The order it uses is a member by email, then a member by legacy id, then a member by phone number, then a contact by email, then a contact by phone number. If nothing matches and the row carries an email or a name, a contact is created and added to the list. A row with only a name links to an existing contact who has no email address and the same name, which keeps a repeated upload from duplicating that person, at the cost of treating two people of the same name as one. *** ## Choosing the columns that match reliably | Reference | Best column | Next best | Do not rely on | | - | - | - | - | | Payer | `user_legacy_id` | `payer_email` | `payer_name` on its own. It never finds anybody, it only creates a contact | | Product | `product_legacy_id` | `product_name` | Duplicate product names, see below | | Price tier | `product_price_legacy_id` | `product_name` plus `price_name` plus `amount` | `price_name` alone. The amount is part of the identity, so 50.00 and 55.00 are different tiers | | Member, on role, company and badge files | `user_legacy_id` | `email` | Anything else. There is no name fallback and no creation, so an unknown member is a failed row | | Role | `role_legacy_id` | `role_name` | Two roles of the same name. Every row naming that role fails | | Unit | `unit_legacy_id` | `unit_name` | Leaving it blank is fine. An ambiguous name is not | | Company | `company_legacy_id` | `company_name` | Duplicate company names, which fail the row | | Badge | `badge_legacy_id` | `badge_name` | Duplicate badge names, which fail the row | **Why an email column beats a name column.** A name is only ever an instruction to create somebody. An email is the one value Orgo looks for among your members first, among your contacts second, and the only value that lets a second import recognise a person the first import created. Names are matched for roles, units, companies, badges and products, where a name is the record's identity, but never for people. So if your file names people, include their email addresses. A large number under "new contacts" on a payer column almost always means the email column is missing or misspelled, not that all those payers are new. Phone numbers are a poor key wherever they are offered. They are compared as written, after trimming spaces at the ends, so `+40 712 345 678` and `+40712345678` are two different people. *** ## Two behaviours to know before you re-import **A person with no email address is created again every time.** Contact creation recognises a person it created earlier by email and by nothing else. Import a payment file whose payers have names but no email addresses, run it again next month, and every one of those payers is created a second time. This is deliberate: matching people by name inside one organisation would quietly merge two people who happen to share a name. The practical rule is that a file without emails is a one-shot file. **The organisation column takes part in identifying a new contact.** A contact is created per distinct combination of name and organisation. Two rows for Ana Pop, one with `payer_organisation` filled in and one with it blank, are two different people to the importer and produce two contacts, even when both rows carry the same email address. Either fill the organisation column consistently for the same person, or leave it unmapped. *** ## Duplicate products and price tiers Where two products share a name, or two price tiers share a name and amount on the same product, Orgo attaches every matching row to the oldest of them and says nothing. There is no warning in the strip and no error in the import log, because a bulk payment import is not allowed to stall on a pre-existing duplicate in your catalogue. This is the opposite of how duplicate roles, units, companies and badges behave, where two records of the same name make the reference ambiguous and fail the row. Tidy up duplicate products and price tiers before importing payments, not after. Once a few thousand payments have attached themselves to the older of two products named "Membership 2026", separating them again is manual work. *** ## Troubleshooting The column you mapped is not the one that identifies the record, or its values do not exist in Orgo. Check three things in order: that legacy id columns hold the ids from the system you are migrating from and not row numbers; that name columns are spelled as the records are spelled in Orgo, accents included; and that the column really is mapped to the group you think, since the tile only reflects the mapping as last saved. Remember also that "unmatched" covers a value that matches two records as well as one that matches none. The import log separates the two afterwards, with a message saying the lookup is ambiguous. The email in the row did not match any member, so the payer chain fell through to its last step and created a contact. Usually the address in the file is an old one, a personal address where the member is registered with a work address, or misspelled. Fix the email column and re-import; correcting it on the contact afterwards does not move the payment. See [Contacts and money](/docs/platform/contacts/payments) for what a contact-held payment can and cannot do. Almost always one of two causes. Either the file names people without email addresses, in which case every run creates them again, or the organisation column is filled for some of a person's rows and blank for others, which splits them in two. Merge the resulting records from the contact list, then add or tidy the email column before the next run. Role assignments create nothing, so the role has to exist first. Either the name in the file does not exist in Orgo, or two roles share that name and the reference is ambiguous. Letter case does not matter; spelling and accents do. Import or rename the roles first, or map `role_legacy_id` instead of the name. The same applies to units, companies and badges. The preview judged the first 20 rows. If your file is sorted so that the well-identified rows come first, the rows further down can behave completely differently. Sort or spot-check the file before importing, and after a large run compare the counts in the import history with what you expected. A file without email addresses, or with an inconsistent organisation column, will also create more records than the row count suggests. *** ## Related * [Data import](/docs/platform/customization/import) what the wizard is and where to start * [Preparing your file](/docs/platform/customization/import/preparing-your-file) formats, headers and column values * [Mapping columns](/docs/platform/customization/import/mapping-columns) the mapping screen and what blocks Start * [Custom fields in an import](/docs/platform/customization/import/custom-fields) mapping onto profile fields and declaring new ones * [Import reference](/docs/platform/customization/import/reference) every import type and the columns it reads * [Contacts](/docs/platform/contacts) what a contact is and how the module is switched on * [The contact record](/docs/platform/contacts/record) what a contact record holds * [Contacts and money](/docs/platform/contacts/payments) what a contact can pay for and where it appears * [Donations](/docs/platform/fees/donations) payments recorded without a product * [Products and prices](/docs/platform/fees/products) products, price tiers and what makes them duplicate * [Companies](/docs/platform/users/companies) corporate membership and company members # Mapping Columns Source: https://orgo.space/docs/platform/customization/import/mapping-columns Tell Orgo what each column in your file means, on a screen that shows your own data while you decide Mapping is where you say what each column in your file means. The screen shows your actual file, not an abstract form, and you work through it one column at a time. Nothing is created or changed while you are in here: no member, contact, payment or badge exists until you press **Start import**. **Built for** the spreadsheet you already have, with the headers it already has. **Replaces** renaming columns in Excel until the import stops complaining. The Map columns screen showing the uploaded file as a sheet, with each column header carrying its destination and a status chip, a progress line reading 6 of 6 columns mapped, and the required field chip beside Discard and Start import *** ## How the screen opens On **Settings → Customization → Import**, pick a step and choose your file. For a step that supports mapping, the action button reads **"Map columns"** rather than **"Start Import"**. Press it and the wizard opens over the whole page. The header shows the title **"Map columns"** with the import type underneath it (**"Users"**, **"Contacts"**, **"Product Payments"**, **"Event Attendance"** and so on). To the right of the title sits the save state: **"Saving…"** while a change is being stored, then **"Draft saved"**. Your choices are saved as you make them. That draft is a mapping, not an import. Close the screen with the **"Close"** X in the header or the Escape key. Clicking the dimmed page behind it does nothing, on purpose. *** ## The sheet Under the toolbar, the screen is your file: the header row across the top, the first 20 rows underneath, numbered down the left. The header row and the numbers stay in place while you scroll, and the sheet scrolls sideways for a wide file. Above the sheet on the left is the progress line, counting mapped columns against the total (**"7 of 12 columns mapped"**), over a thin bar. On the right are the file name and the number of rows Orgo read (**"200 rows sampled"**). The sampled figure is the larger one: Orgo reads up to 200 rows of your file to work out its suggestions and to collect the distinct values in each column, and it draws the first 20 of them for you to look at. ### What a column header shows Each column header is a button, and it stacks three things. 1. **The name from your file**, exactly as you wrote it. Long names are cut short on screen, with the full text on hover. 2. **A summary of where the column is going.** 3. **Its status chips.** The summary line has one wording per state: | Where the column goes | Summary line | | - | - | | A system field with no grouping | **"→ "** and the field, for example **"→ Email"** | | A system field inside a group | **"→ "**, the group, **" · "** and the field, for example **"→ Payer · Payer email"** | | One of your existing profile fields | **"Existing field"**, its type and its name, for example **"Existing field · Single choice · T-shirt size"** | | A new field the import will create | **"New field"** and the type, for example **"New field · Text"**, plus the option count for a choice field, as in **"New field · Multiple choice · 4 options"** | | Left out | **"Skipped"** | | Half-decided | **"Needs attention"** | And one chip per status: | Chip | Meaning | | - | - | | **"System field"** (green) | Going into one of Orgo's own fields for this import type | | **"Existing field"** (blue) | Going into a profile field your organization already has | | **"New field"** (light blue) | Will create a profile field, at the moment you press **Start import** | | **"Skipped"** (grey) | Left out of the import entirely | | **"Needs attention"** (amber) | You picked a kind of destination but not the destination itself, or two columns claim the same system field | A second chip, **"Suggested"**, sits beside the status chip while the column is still on the wizard's own guess. It disappears the moment you change anything about that column, so the chips left showing **"Suggested"** are exactly the decisions you have not reviewed yet. *** ## The column settings panel The column settings panel open beside the sheet, showing how many sample rows have a value, the sample values, the destination choice between a system field, an existing field, a new field and skip, and the field name and type Click a column header and its settings open in a panel beside the sheet. Click the same header again, or the panel's **"Close"** X, to shut it. The panel has a drag handle on its left edge (**"Resize panel"**) if you want it wider, and the arrow keys nudge it once it has focus. A line such as **"18 of 200 sample rows have a value"** tells you how full the column is, followed by up to five of the distinct values it holds and a **"+N"** tag for the rest. A column that is nearly empty, or full of values you did not expect, is worth catching here rather than after the import. **"Destination"** is a block of four buttons: **"System field"**, **"Existing field"**, **"New field"** and **"Skip"**. Import types that do not carry profile fields, such as events or products, offer only **"System field"** and **"Skip"**. A select labelled **"System field"** opens with the placeholder **"Choose a field"**. Types with grouped fields list them under group headings (**"Payer"**, **"Product"**, **"Price tier"**, **"Event"**, **"Attendee"**, **"Member"**, **"Role"**, **"Company"**, **"Badge"** and the rest); people types list theirs flat. A field another column has already taken is greyed out and its name carries the suffix **"(already used)"**. **"Existing custom field"** is a search box with the placeholder **"Search your profile fields"**; it opens the whole list on focus. Each suggestion shows the field name with its type beside it, and once you pick one the help text under the box reads **"Type"** and the type name. An empty search says **"No matching field"**. A field with a lock icon is encrypted and cannot be chosen, see the troubleshooting below. **"Field name"** is pre-filled with the header from your file, and **"Field type"** offers **"Text"**, **"Long text"**, **"Number"**, **"Date"**, **"Yes / No"**, **"Dropdown"**, **"Single choice"** and **"Multiple choice"**. The field is created when you press **Start import**, not before. A single line reads **"This column is left out of the import."** A **"Multiple choice"** column gets **"Values in a cell are separated by"**, three buttons reading **","** **"Comma"**, **";"** **"Semicolon"** and **"|"** **"Pipe"**, with a **"Split preview"** underneath showing how three of your own cells break apart under the choice you made. Every choice column then gets **"Match values to options"**: a table of **"Value in file"** against **"Option label"** for a new field, or **"Option"** for an existing one, where you decide that "M", "Male" and "male" are all one option. That table is covered in full on [Custom Fields in an import](/docs/platform/customization/import/custom-fields). *** ## Why a type was suggested Every column arrives with a guess already made, marked **"Suggested"**. Orgo works it out in this order. First, where the column should go. If the header matches one of the system fields for this import type, it points there. If it matches a profile field your organization already has, it points at that field with the type that field already uses. Otherwise it proposes a new field, and only then does it need to guess a type. The type guess looks at the values in the sampled rows and takes the first rule that fits: 1. **A delimited list.** If a comma, semicolon or pipe appears in at least a third of the filled cells, and the pieces it produces repeat across rows rather than being all different, the column is read as **"Multiple choice"** with that character as the delimiter. The repetition test is what stops a column of free text full of commas from being mistaken for a list. 2. **Yes or no.** Every filled cell is one of true, false, 1, 0, yes or no, in any casing, so the column becomes **"Yes / No"**. 3. **Numbers.** Every filled cell is a number, so the column becomes **"Number"**. 4. **Dates.** Every filled cell is a real date written as `YYYY-MM-DD`, so the column becomes **"Date"**. 5. **A short set of repeating values.** At least 20 filled cells sharing no more than 15 distinct values, so the column becomes **"Single choice"** and the distinct values become its options. 6. **Anything else** becomes **"Text"**. The order matters. A column of `yes; no` is a list before it is a yes or no question, and a column of only `1` and `0` is a yes or no question before it is a number. A suggestion is a starting point, nothing more. The **"Suggested"** chip is there so you can tell at a glance which columns are still running on a guess, and changing anything about the column clears it. *** ## What the sample rows show The 20 rows are not raw text; they are a preview of what the import would store under the mapping as it stands right now. Change a column and its cells redraw. * **A multiple choice column** splits each cell on its delimiter and shows one small tag per piece. The tag reads the option label the piece resolves to, and hovering shows the raw text from your file. * **A single choice column** shows the resolved option label, and underneath it, in smaller muted text, the raw text from your file, but only when the two differ. A cell reading `S` that resolves to an option called `Small` shows "Small" over "S". A cell that already reads "Small" shows one line. * **A skipped column** keeps its raw values on screen but the whole column is dimmed, so it reads as present but inactive. * **An empty cell** shows a faint dash. Empty means empty: the import writes nothing for it, so a blank cell cannot be used to clear a value. Every other column, including system fields, text, numbers and dates, shows its raw values unchanged. *** ## Before Start import can be pressed Two things have to be true, and both are reported in the footer beside the button. **Every required group is satisfied.** Each requirement is one chip. Its label is the group, then the ways of satisfying it: fields that must go together are joined by **" + "**, and the alternatives are joined by **" or "**. A satisfied chip is green with a check mark and reads plainly, for example **"Payer: Payer email or Payer name"**. An unsatisfied chip is grey with an exclamation mark and has the word needed appended, for example **"Payer: Payer email or Payer name needed"**. A simple type shows a single chip: a Users import needs only an email address, so its chip reads **"Required: Email"**. A type that links to other records shows one chip per reference plus a **"Required fields"** chip for the columns on the row itself. Every chip has to be green. **No system field is used twice.** If two columns claim the same one, a red chip appears in the footer reading **"Each system field can be filled by one column only"** followed by the fields in question, and in the panel the select turns red with **"Another column already fills this field"**. Pick a different field for one of them, or skip it. **Start import** also stays disabled while the preview is still loading, while a start is already under way, and while a change cannot be saved. In that last case the header replaces **"Draft saved"** with the reason: **"Mapping is not valid"** when the choice itself is refused, or **"Could not save the mapping"** when the request did not get through. What does not block the button: columns you left skipped, and columns still reading **"Needs attention"** because you opened **"Existing field"** and never picked one. Those are simply not imported. *** ## Unmapped columns are dropped This is the one that surprises people, so it is worth saying flatly: **a column you leave skipped is thrown away.** Its values are not stored anywhere, and no field is created for it. If a column matters, give it a destination. If it does not, skipping it is exactly right and costs nothing. The one place to be careful is a column you assumed would "just come across" because it did on an older import: in this screen, only the columns you point somewhere are read. *** ## Leaving and coming back Closing the screen does not throw anything away. The mapping is saved as you go, and the import sits waiting. Back on **Settings → Customization → Import**, the step you were working on now shows the chip **"Mapping columns"** and two buttons: **"Continue mapping"**, which reopens the screen exactly where you left it, and **"Discard"**, which throws the whole thing away after asking. The confirmation is explicit about what is lost: **"The uploaded file and this mapping will be deleted. Nothing has been imported yet."** There is one draft per step. Uploading a new file for the same step means dealing with the draft first. And a mapping is never reused: each import is mapped from scratch, on its own file. *** ## Troubleshooting Read the footer chips first. Any chip that is still grey names what is missing, and every chip has to be green before the button wakes up. If they are all green, look at the header where **"Draft saved"** normally sits: a message there means your last change could not be stored, and the button stays disabled until it can be. The usual cause is a column set to **"System field"** with no field chosen, or two columns fighting over the same field. You chose a kind of destination but not the destination itself: **"System field"** or **"Existing field"** with nothing picked underneath. The other cause is a clash, where two columns claim the same system field and both are flagged. Open the column and either finish the choice or set it to **"Skip"**. The progress line (**"7 of 12 columns mapped"**) counts only columns with a real destination. Skipped columns and columns still reading **"Needs attention"** are not counted, so a file you have completely decided can sit well under 100% and still be ready to import. Trust the footer chips, not the bar. Messages that come back when you press **Start import** use the internal column names, not the friendly labels on screen: `payer_email` rather than "Payer email", and the normalized version of your own header (lower case, spaces turned into underscores) rather than the header as you typed it. They are also written in English whatever language the rest of the page is in. Match the name to the field by its shape: `payer_email` is **"Payer · Payer email"**, `shirt_size` is your column "Shirt Size". That field is encrypted, and an import cannot write into it. Encrypted fields hold things like identity numbers, and the import writes values by a route that would store them unprotected, so it is refused rather than allowed to leak. Clicking the locked row does nothing at all, which is why the column stays on **"Needs attention"**. Map the column to something else or skip it, and enter those values through the profile instead. *** ## Related * [Data Import](/docs/platform/customization/import) - the whole import process, start to finish * [Preparing Your File](/docs/platform/customization/import/preparing-your-file) - what to fix in the spreadsheet before you upload it * [Custom Fields in an import](/docs/platform/customization/import/custom-fields) - existing fields, new fields, and matching values to options * [Linking Records](/docs/platform/customization/import/linking-records) - how a row finds the person, product or event it belongs to * [Import Reference](/docs/platform/customization/import/reference) - every import type, its fields and its required columns * [Custom Fields](/docs/platform/users/custom-fields) - the profile fields an import can fill or create # Preparing your file Source: https://orgo.space/docs/platform/customization/import/preparing-your-file Get the spreadsheet right before you upload it: CSV format, the 50 MB limit, headers, dates, yes/no columns and choices Most import problems are decided in the spreadsheet, long before Orgo sees it. This page is what to fix while the file is still open in Excel, Numbers or Google Sheets. **Built for** the person holding an export from an old system, a membership register kept in a spreadsheet, or a list somebody else prepared. **Replaces** the guesswork of uploading, reading the errors, and trying again. *** ## Save it as CSV Orgo reads **CSV** and **TXT** files. It does not read Excel workbooks. An `.xlsx` or `.xls` file has to be saved as CSV first, and so does an `.ods` or a Numbers document. | Where the file lives now | How to get a CSV | | - | - | | **Excel** | File, Save As (or Export), and pick **CSV UTF-8 (Comma delimited) (.csv)**. Choose that entry rather than plain "CSV" when both are offered. | | **Numbers** | File, Export To, **CSV**, and set **Text Encoding** to **Unicode (UTF-8)**. | | **Google Sheets** | File, Download, **Comma Separated Values (.csv)**. Google Sheets always writes UTF-8. | | **Another system's export** | Ask for CSV. If the export only offers Excel, open it and save it again as CSV. | Save one sheet per file. A workbook with several tabs becomes a CSV of whichever sheet was active, and the rest is lost silently. Save as **UTF-8** wherever the option exists. Orgo also recognises the older Western European encodings that Excel produces on Windows, but UTF-8 is the only one that carries accented names, Cyrillic and Greek without any guessing. A UTF-8 byte order mark at the start of the file is harmless and is removed for you. *** ## Keep it under 50 MB The limit is **50 MB per file**. The size is checked in your browser before the upload starts, so an oversized file never leaves your computer: you get **"File is larger than the 50 MB import limit"** straight away. A CSV of member records is small, so 50 MB is a lot of rows. If you do go past it, split the file: 1. Open the spreadsheet and split it by row into two or more files, for example rows 1 to 40,000 and rows 40,001 onwards. 2. Copy the header line into every part. Each file has to carry its own headers. 3. Upload the parts one after another, mapping each one as its own import. Splitting is also the faster route for very large files, not only the legal one. A file of a few tens of thousands of rows moves through Orgo noticeably quicker as several parts than as one enormous upload. *** ## How Orgo reads the file **One header line, then one row per record.** No merged cells, no blank spacer rows in the middle, no totals row at the bottom, no notes written above the headers. A spreadsheet meant to be read by a person is rarely a good import file; strip the presentation out of it. **The header line is found for you.** Blank lines above the header are skipped, and when an import starts Orgo looks through the first ten lines for the row that carries the columns that type needs. What you should still do is put the headers on the first line with content in it, because the mapping screen builds the sheet you see from that line. A title such as "Members export 2026" sitting above the headers will be read as the header row there. **The delimiter is detected, not configured.** Orgo counts semicolons, commas and tabs on the header line and uses whichever appears most often. That is why the header line matters more than the rest of the file: a header full of punctuation can outvote the real separator. Values that contain the delimiter are fine as long as your spreadsheet quoted them, which every export listed above does. **One row is one record.** Five rows for the same person are five rows, not one person seen five times, and each of them is processed on its own. *** ## Column headers are yours to name This is the change that matters most if you have imported into Orgo before. **Your headers no longer have to match Orgo's field names.** You are not renaming `Email address` to `email`, or `Date of birth` to `birth_date`, before you upload anything. You upload the file as your old system exported it, and then you say on screen which column goes where. `E-mail`, `Correo`, `Adresa de email` and `Contact email` are all fine, because you point each one at the destination field yourself in the mapping screen. Two things follow from that: * **Do not rename headers to guess at Orgo's vocabulary.** Leave them as they are. Clear, human headers are easier to map than half-remembered technical ones. * **Every column needs a header.** A column with an empty header cell cannot be mapped, so give it a name, even a rough one, or delete the column. Headers that do already match Orgo's names are still worth having: the mapping screen recognises them and pre-selects the destination for you, which leaves less to do by hand. It is a shortcut, not a requirement. Two columns whose headers differ only by capitals, spaces or hyphens count as the same column, so `First Name` and `first-name` collide and only one survives. Give every column a distinct name. *** ## Values that need care Most cells are copied across as text and need no thought. These are the ones that quietly do something other than what the spreadsheet looks like it says. | Column holds | Write it as | What happens otherwise | | - | - | - | | **A date** | `2026-03-14`, always year, month, day with dashes | Anything else is refused: `14/03/2026`, `2026-3-14`, `March 14 2026`, and the plain numbers Excel leaves behind when a date column loses its formatting. A date Orgo cannot read fails the whole row, not just that cell. | | **Yes or no** | `true`, `1` or `yes` for yes, in any capitalisation | Only those three spellings count as yes. Everything else, including `y`, `x`, `da`, `ja`, `oui`, `sim` and a tick character, is stored as **no**, with no warning and no error. | | **A number** | The number as you want it stored | Numbers are stored exactly as written. Nothing is parsed, rounded or reformatted, so `12,50`, `1 250` and `EUR 50` all land as that text. Decide on one way of writing amounts and apply it to the whole column. | | **Nothing (an empty cell)** | Leave it empty only when you mean "no change" | An empty cell writes nothing at all. It cannot clear a value that is already stored, so blanking a column in the spreadsheet and importing again leaves the old values in place. | | **One choice from a list** | The option label as it reads in Orgo | The value is matched against the existing options by label, ignoring capitals and extra spaces, so `chess`, `Chess` and `Chess ` all find the same option. A value that matches nothing creates a new option on the field. | | **Several choices at once** | The labels separated by one consistent character | Multi-choice columns are split on a delimiter you choose in the mapping screen, and each part is then matched like a single choice. Mixing separators inside one column leaves you with options named after the whole cell. | The yes/no rule is the one that catches people out. A column of `da` and `nu`, or `ja` and `nein`, or `Y` and `N`, imports as a column of no's, and the import reports a clean run because nothing went wrong from its point of view. Convert those columns to `yes` and `no`, or to `1` and `0`, in the spreadsheet first. A find-and-replace on the column takes a minute and is the single highest-value thing on this page. Only capitals and spacing are forgiven when a choice is matched. `Chess` and `Chess.` are two different options, and so are `Football` and `Fotbal`. Tidy the spelling in the column before you import, or you will find near-duplicate options on the field afterwards. *** ## Start from an example file Every import type on the **Data Import** page carries an **Example CSV** link on its step card, next to the upload button. The example is a real, working file for that type with a handful of demonstration rows. Use one as a template: 1. Download the example for the type you are importing. 2. Open it and look at the columns. They are the ones that type understands, written the way Orgo writes them. 3. Replace the demonstration rows with your own data, keeping the header line. 4. Save as CSV and upload. Working this way means your headers already match Orgo's names, so the mapping screen has almost nothing left to ask you. It is also the quickest way to see what a type expects when the field list is unfamiliar. Any column of your own that the example does not have can simply be added: you will map it when you upload. *** ## Before you upload * [ ] The file is saved as **CSV or TXT**, not as an Excel workbook, and in UTF-8. * [ ] It is under **50 MB**, or it has been split into parts that each carry the header line. * [ ] The **headers sit on the first line with content**, with nothing above them. * [ ] **Every column has a header**, and no two headers are the same. * [ ] There is **one row per record**: no merged cells, no spacer rows, no totals line. * [ ] Every date column reads **`2026-03-14`**, in that order, for every row including the last ones. * [ ] Every yes/no column uses **`yes`, `1` or `true`**, and nothing else means yes. * [ ] Nothing you wanted to erase was left blank, because a blank cell changes nothing. * [ ] Files about people carry an **email column** wherever you have addresses. * [ ] You scrolled to the **bottom of the file** and checked that the last rows look like the first ones. That last one is worth the thirty seconds. Exports often start clean and turn messy several thousand rows in, where a different date format or a stray note was pasted years ago. *** ## Troubleshooting The limit is 50 MB and it is checked in the browser, so the message appears before anything is uploaded. Split the spreadsheet by row into two or more files, copy the header line into each part, and import the parts one after another. If the file is unexpectedly large for its row count, look for empty columns stretching far to the right, or thousands of empty rows below the data: delete them and export again. Orgo accepts one date format, `2026-03-14`. Everything else, including `14/03/2026` and `14.03.2026`, is refused. In the spreadsheet, select the date column and give it a custom format of `yyyy-mm-dd`, then export again and open the CSV in a text editor to confirm the dates really were written that way. Watch for the case where Excel shows a date but has stored a serial number: the CSV then contains something like `46095`, which is not a date to Orgo. Only `true`, `1` and `yes` are read as yes. Any other word, in any language, is stored as no without an error, so the import looks successful. Fix the column in the spreadsheet with a find-and-replace, `da` to `yes` and `nu` to `no` for example, then import the corrected file. Because a blank cell changes nothing, re-importing the same file with the column corrected will set the values that should be yes. Orgo needs one. Add a line at the top naming each column. The names are yours to choose, since you map them on screen, so plain words are enough. Also check that nothing sits above that line: a report title, a date stamp or an exported note on line one will be treated as the headers by the mapping screen. Delete those rows and save again. The separator is chosen by counting semicolons, commas and tabs on the header line. Two things break it. First, punctuation inside the header names themselves, such as a column called `Name, first`: rename it. Second, a file that mixes separators, usually because it was edited by hand after export. The reliable fix is to open the file in your spreadsheet, check that the columns split correctly there, and export it once more so the whole file uses one separator. In Excel on a computer set to a European locale, prefer the **CSV UTF-8** export, which is consistent about what it writes. *** ## Related * [Data import](/docs/platform/customization/import) - the whole import, from upload to finished records * [Mapping columns](/docs/platform/customization/import/mapping-columns) - the screen where your headers meet Orgo's fields * [Custom fields in an import](/docs/platform/customization/import/custom-fields) - storing columns Orgo has no field for * [Linking records](/docs/platform/customization/import/linking-records) - how a row finds the member, event or product it belongs to * [Import reference](/docs/platform/customization/import/reference) - the fields each import type reads * [Custom Fields](/docs/platform/users/custom-fields) - the profile fields an import can fill or create # Import Type Reference Source: https://orgo.space/docs/platform/customization/import/reference Every import type in one place: the fields you can map, what each type needs, how it decides a record already exists **Built for** the moment you are about to map a file and need the answer for one type, not a tour of the whole wizard. Jump to your type and read the entry. **Replaces** opening the example CSV and guessing what each header does. *** ## How to read an entry Every type below has the same parts. * **Fields.** What you can map. **Field** is the name the wizard shows in its destination list; **Column** is the canonical name Orgo uses internally and in the example file. Your own spreadsheet headers do not have to match either one: you point each column at a field yourself while mapping. * **Required.** What the mapping must cover before **Start import** unlocks. Every group has to be satisfied, and inside a group any one alternative is enough. * **Already exists.** How Orgo decides a row describes a record it already has. **A match is skipped, not updated.** Only [Modify Users](#modify-users) and [Modify Contacts](#modify-contacts) change records that are already there. Re-uploading a corrected sheet through any other type changes nothing for the rows that match. * **Custom fields.** Whether this type can write to custom fields. Only the four people types can; for every other type the field list below is the whole vocabulary, and a column that is not on it can only be skipped. * **Example file.** The **Example CSV** link on that type's card, a small file with the canonical headers. *** ## The types at a glance | Type | Creates | Updates existing records | Custom fields | | - | - | - | - | | [Users](#users) | Members | No | Yes | | [Contacts](#contacts) | Contacts | No | Yes | | [Modify Users](#modify-users) | Nothing, except a contact for a row that matches no member | Yes, members | Yes | | [Modify Contacts](#modify-contacts) | Nothing, except a contact for a row that matches nobody | Yes, contacts | Yes | | [Product Payments](#product-payments) | Payments, plus the payer, product and price tier a payment needs | No | No | | [Products](#products) | Products and fees | No | No | | [Product Prices](#product-prices) | Price tiers | No | No | | [Local Centers](#local-centers) | Chapters | No | No | | [Units](#units) | Units and groups | No | No | | [Roles](#roles) | Roles | No | No | | [User Roles](#user-roles) | Role assignments | No | No | | [Companies](#companies) | Companies | No | No | | [Company Members](#company-members) | Company memberships | No | No | | [List members](#list-members) | List memberships, plus a contact when nobody matches | No | No | | [Events](#events) | Events | No | No | | [Badge Types](#badge-types) | Badge categories | No | No | | [Badges](#badges) | Badges | No | No | | [Badge Assignments](#badge-assignments) | Badge awards | No | No | Order matters when you run several types: each one can name records the earlier ones created, so chapters before members, products before price tiers, price tiers before payments. The import page lists the types in a workable order already. *** ## Users Creates member accounts. | Field | Column | What it means | | - | - | - | | Email | `email` | Email address. Also how Orgo tells whether the person is already a member. | | First name | `first_name` | Given name. | | Last name | `last_name` | Family name. | | Phone number | `phone_number` | Phone number. | | Birth date | `birth_date` | Date of birth. | | Gender | `gender` | Gender. Only the first character is kept. | | Address | `address` | Street address. | | Postal code | `postal_code` | Postcode or ZIP. | | Town of residence | `town_residence` | Town they live in, matched against the town list by name. | | Website | `website` | Personal website. | | Company name | `company_name` | Employer name as free text on the member, not a link to a company record. | | Profession headline | `profession_headline` | Job title or headline text. | | Member ID | `member_id` | Membership card number. | | Full member | `is_full_member` | Yes or no: a full member rather than a trial or associate one. | | Status | `status` | Member status. Only values on the allowed status list are accepted. | | Member type legacy ID | `user_type_legacy_id` | Their membership type, matched by legacy id or by name. | | Chapter legacy ID | `local_center_legacy_id` | Their chapter, by legacy id or by chapter name. | | Date created | `date_created` | The date the record should say the person was created. | | Date joined | `date_joined` | The date they joined. | | Date joined as full member | `date_joined_full_member` | The date they became a full member. | | Newsletter subscribed | `is_newsletter_subscribed` | Yes or no. Left blank, the stored value stays as it is. | | Tags | `tags` | Comma separated tag names. A tag that does not exist yet is created. | | Fee price legacy ID | `fee_tenant_product_price_legacy_id` | Legacy id of the price tier that sets their membership fee. | | Legacy ID | `user_legacy_id` | The person's id in the system you are migrating from. | The wizard shows these as one flat list rather than in groups. **Required:** `email`. **Already exists:** the email address, compared without regard to case. A row whose email already belongs to a member is skipped. A row with a blank or unusable email fails rather than creating a member. Map the legacy id as well and a member carrying that legacy id counts as a match too. **Custom fields:** yes. **Example file:** `import_users.csv`, from the **Example CSV** link on the **Users** card. *** ## Contacts Creates contacts: people you hold details for who do not have a member account. | Field | Column | What it means | | - | - | - | | Email | `email` | Email address. Also how Orgo tells whether this person is already on file. | | Name | `name` | Full name in one field, not split into first and last. | | Phone | `phone` | Phone number. | | Birth date | `birth_date` | Date of birth. | | Gender | `gender` | Gender. | | Address | `address` | Street address. | | Town | `town` | Town, matched by name. | | Country | `country` | Country, matched by two-letter code, three-letter code or name. | | Organisation | `organisation` | The organisation they belong to, as free text. | | Role | `role` | Their position or job title. | | Profession and role | `profession_organisation_role` | Their role inside that organisation. | | Company name | `company_name` | Company name as free text. | | Company identifier | `company_identifier` | Company identifier, for example a Romanian CUI. | | Company address | `company_address` | Company address. | | Company registration number | `company_reg_no` | Company registration number. | | LinkedIn | `linkedin` | LinkedIn profile link. | | Twitter | `twitter` | Twitter profile link. | | Instagram | `instagram` | Instagram profile link. | | Status | `status` | Contact status, matched by name against your profile status list. | | Chapter | `local_center` | Their chapter, by name. | | Chapter legacy ID | `local_center_legacy_id` | Their chapter, by legacy id. | | Newsletter subscribed | `is_newsletter_subscribed` | Yes or no. Left blank, the stored value stays as it is. | | Tags | `tags` | Comma separated tag names. | | Legacy ID | `user_legacy_id` | If the email turns out to belong to a member, this legacy id is stamped onto that member instead of a contact being created. | The wizard shows these as one flat list rather than in groups. **Required:** `email`. **Already exists:** the email address, checked against both members and contacts. An email that already belongs to either is skipped. **Custom fields:** yes. **Example file:** `import_contacts.csv`, from the **Example CSV** link on the **Contacts** card. *** ## Modify Users Updates members who are already in Orgo. One of the two types that change existing records. | Field | Column | What it means | | - | - | - | | Email | `email` | Email address. A match key, and writable: put a new address here to change it. | | Phone number | `phone_number` | Phone number. A match key, and writable. | | Legacy ID | `user_legacy_id` | Their id in your old system. A match key, and writable. | | First name | `first_name` | Given name. | | Last name | `last_name` | Family name. | | Birth date | `birth_date` | Date of birth. | | Gender | `gender` | Gender. | | Address | `address` | Street address. | | Postal code | `postal_code` | Postcode or ZIP. | | Town of residence | `town_residence` | Town they live in, matched by name. | | Website | `website` | Personal website. | | Company name | `company_name` | Employer name as free text. | | Profession headline | `profession_headline` | Job title or headline text. | | Member ID | `member_id` | Membership card number. | | Full member | `is_full_member` | Yes or no. | | Status | `status` | Member status. | | Newsletter subscribed | `is_newsletter_subscribed` | Yes or no. | | Date joined | `date_joined` | The date they joined. | | Date joined as full member | `date_joined_full_member` | The date they became a full member. | | Chapter | `local_center` | Their chapter, by name. | | Chapter legacy ID | `local_center_legacy_id` | Their chapter, by legacy id. Wins if you map both chapter columns. | | Member type legacy ID | `user_type_legacy_id` | Their membership type, by legacy id or name. | **Required:** one group, three alternatives. Map `email`, or `user_legacy_id`, or `phone_number`. **Already exists:** this type only ever works on records that exist. Each row is matched on email first, then legacy id, then phone number. A row that matches no member is tried against your contacts on the same details, and a contact is updated or created from it. **Custom fields:** yes. The wizard offers the full member field list here, but a modify run writes only the fields in the table above. Anything else you map, including `date_created`, `tags` and the fee price legacy id, is accepted and then goes unused. An empty cell writes nothing either, so a blank column cannot clear a value that is already stored. **Example file:** `import_user_modify.csv`, from the **Example CSV** link on the **Modify Users** card. *** ## Modify Contacts Updates contacts who are already in Orgo. The second of the two types that change existing records. | Field | Column | What it means | | - | - | - | | Email | `email` | Email address. A match key, and writable. | | Phone | `phone` | Phone number. A match key, and writable. | | Name | `name` | Full name in one field. | | Birth date | `birth_date` | Date of birth. | | Gender | `gender` | Gender. | | Address | `address` | Street address. | | Town | `town` | Town, matched by name. | | Country | `country` | Country, matched by two-letter code, three-letter code or name. | | Organisation | `organisation` | The organisation they belong to. | | Role | `role` | Their position or job title. | | Profession and role | `profession_organisation_role` | Their role inside that organisation. | | Company name | `company_name` | Company name. | | Company identifier | `company_identifier` | Company identifier, for example a Romanian CUI. | | Company address | `company_address` | Company address. | | Company registration number | `company_reg_no` | Company registration number. | | LinkedIn | `linkedin` | LinkedIn profile link. | | Twitter | `twitter` | Twitter profile link. | | Instagram | `instagram` | Instagram profile link. | | Status | `status` | Contact status. | | Newsletter subscribed | `is_newsletter_subscribed` | Yes or no. | | Chapter | `local_center` | Their chapter, by name. | | Chapter legacy ID | `local_center_legacy_id` | Their chapter, by legacy id. Wins if you map both chapter columns. | **Required:** one group, two alternatives. Map `email`, or `phone`. There is no legacy id alternative here, because contacts carry no legacy id of their own. **Already exists:** each row is matched on email first, then phone. A row that matches nobody creates a contact, as long as it carries an email or a name. **Custom fields:** yes. `tags` and the member legacy id are offered by the mapper but not written by a modify run. An empty cell writes nothing, so a blank column cannot clear a stored value. **Example file:** `import_contact_modify.csv`, from the **Example CSV** link on the **Modify Contacts** card. *** ## Product Payments Creates payment records, and the payer, product and price tier each payment needs. | Group | Field | Column | What it means | | - | - | - | - | | Payer | Payer email | `payer_email` | The payer's email address. | | Payer | Payer name | `payer_name` | The payer's full name, used to create a contact when no member or contact matches. | | Payer | Payer organisation | `payer_organisation` | The payer's organisation, kept as extra detail on a contact created this way. | | Payer | Legacy ID | `user_legacy_id` | The payer, by member legacy id. | | Product | Product name | `product_name` | The product or fee this pays for. Created if it does not exist. | | Product | Product type | `product_type` | The product category, used when the product has to be created. | | Product | Product legacy ID | `product_legacy_id` | The product, by legacy id. | | Price tier | Price tier name | `price_name` | The price tier. Created if it does not exist. | | Price tier | Price tier legacy ID | `product_price_legacy_id` | The price tier, by legacy id. | | Payment | Amount | `amount` | The amount paid. Numbers written the human way are understood. | | Payment | Currency | `currency` | Currency code. Left out, your organisation's currency is used. | | Payment | Status | `status` | Payment status. Only values on the allowed list are accepted. | | Payment | Date created | `date_created` | The date of the payment. | | Payment | Period start | `period_start` | Start of the period the payment covers. | | Payment | Period end | `period_end` | End of that period. | | Payment | Comment | `comment_by_user` | A free text note on the payment. | | Payment | Public | `is_public` | Yes or no: show this payment publicly. | | Payment | Payment legacy ID | `payment_legacy_id` | The invoice or payment reference from your old system. | **Required:** two things. | Group | Map at least | | - | - | | Payer | `user_legacy_id`, or `payer_email`, or `payer_name` | | Payment | `amount` **and** `status`, both | The **Product** and **Price tier** groups are optional: a payment with no product is treated as a donation, so a payments file without product columns validates and imports. **Already exists:** the payment legacy id when you map one. Without it, Orgo builds a fingerprint from the payer, product, price tier, amount, payment date and period, and a second row with the same fingerprint is skipped. That is what stops a re-run of the same file doubling every payment. **Custom fields:** no. **Example file:** `import_product_payments.csv`, from the **Example CSV** link on the **Product Payments** card. *** ## Products Creates products and fees. | Group | Field | Column | What it means | | - | - | - | - | | Product | Name | `name` | Product or fee name. | | Product | Type | `type` | The category, for example a fee rather than a shop item. | | Product | Description | `description` | Description text. | | Product | Product legacy ID | `product_legacy_id` | The product, by legacy id. | | Billing | Subscription | `has_subscription` | Yes or no: it can be paid as a recurring subscription. | | Billing | One-time payment | `has_one_time_payment` | Yes or no: it can be paid once off. | | Billing | Months per period | `month_period` | The billing period, in months. | | Billing | Archived | `is_archived` | Yes or no: archived. | | Chapter | Chapter legacy ID | `local_center_legacy_id` | The chapter that owns the product, by legacy id. | **Required:** `name`. **Already exists:** the product legacy id when you map one, otherwise the name, compared without regard to case. **Custom fields:** no. **Example file:** `import_products.csv`, from the **Example CSV** link on the **Products** card. *** ## Product Prices Creates price tiers under an existing product. | Group | Field | Column | What it means | | - | - | - | - | | Product | Product name | `product_name` | The parent product, by name. | | Product | Product legacy ID | `product_legacy_id` | The parent product, by legacy id. | | Price tier | Name | `name` | Tier name. | | Price tier | Price | `price` | The amount. | | Price tier | Currency | `currency` | Three-letter currency code. | | Price tier | Default tier | `is_default` | Yes or no: the tier offered by default. | | Price tier | Subscription tier | `is_subscription` | Yes or no: recurring. | | Price tier | Lifetime | `is_lifetime` | Yes or no: a lifetime price. | | Price tier | Restricted | `is_restricted` | A restriction marker, stored as text rather than a yes or no. | | Price tier | Price tier legacy ID | `product_price_legacy_id` | This tier, by legacy id. | | Price tier | Previous version legacy ID | `previous_version_old_id` | Legacy id of the tier this one replaces. Linked in a second pass, and only on rows that also carry `product_price_legacy_id`. | | Validity | Valid from | `valid_from` | Start of validity. Left blank, the tier is valid from the moment it is imported. | | Validity | Valid to | `valid_to` | End of validity. | **Required:** one group, two alternatives. | Alternative | Map | | - | - | | A | `product_name` **and** `price` | | B | `product_legacy_id` **and** `price` | **Already exists:** the price tier legacy id when you map one. Without it, the product plus the tier name plus the amount to the cent. The amount is read to two decimals, so `10` and `10.00` are the same tier. **Custom fields:** no. **Example file:** `import_product_prices.csv`, from the **Example CSV** link on the **Product Prices** card. *** ## Local Centers Creates chapters. | Group | Field | Column | What it means | | - | - | - | - | | Chapter | Name | `name` | Chapter name. | | Chapter | Short name | `short_name` | Short name or abbreviation, stored as an alias. | | Chapter | Status | `status` | Active or closed. `FALSE`, `CLOSED` and `INACTIVE` all mean closed. | | Chapter | Is parent | `is_parent` | Yes or no: this chapter has child chapters under it. | | Chapter | Parent chapter | `parent` | The chapter above it, by legacy id or by name. | | Chapter | Date created | `date_created` | Creation date. | | Chapter | Chapter legacy ID | `local_center_legacy_id` | This chapter, by legacy id. | | Location | Town | `town` | Town, matched inside your organisation's country unless the organisation is international. | | Location | Postal address | `postal_address` | Postal address. Also written to the office address. | | Location | Place name | `google_place_name` | Place or venue name. | | Location | Latitude | `google_latitude` | Latitude. | | Location | Longitude | `google_longitude` | Longitude. | | Contact | Contact name | `contact_full_name` | The contact person's name. | | Contact | Contact email | `contact_email` | Contact email address. | | Contact | Contact phone | `contact_phone` | Contact phone number. | | Contact | Website | `website` | Chapter website. | | Contact | Facebook URL | `facebook_url` | Facebook page. | | Bank | IBAN | `iban_eur` | The chapter's EUR IBAN. | **Required:** `name`. **Already exists:** the chapter legacy id when you map one, otherwise the name, compared without regard to case. **Custom fields:** no. **Example file:** `import_local_centers.csv`, from the **Example CSV** link on the **Local Centers** card. *** ## Units Creates units and groups. | Group | Field | Column | What it means | | - | - | - | - | | Unit | Name | `name` | Unit name. | | Unit | Unit legacy ID | `unit_legacy_id` | This unit, by legacy id. | | Hierarchy | Parent unit | `parent_unit` | The unit above it, by name. | | Hierarchy | Parent unit legacy ID | `parent_unit_legacy_id` | The unit above it, by legacy id. Wins if you map both parent columns. | | Hierarchy | Chapter | `local_center` | The chapter that owns the unit, by name. | | Hierarchy | Chapter legacy ID | `local_center_legacy_id` | The chapter that owns the unit, by legacy id. Wins if you map both chapter columns. | **Required:** `name`. **Already exists:** the unit legacy id when you map one, otherwise the name, compared without regard to case. Chapters, groups and role groups are left out of that name check, so a unit can share a name with one of them. **Custom fields:** no. **Example file:** `import_units.csv`, from the **Example CSV** link on the **Units** card. *** ## Roles Creates roles, including the membership types people can hold. | Group | Field | Column | What it means | | - | - | - | - | | Role | Name | `name` | Role name. | | Role | Role legacy ID | `role_legacy_id` | This role, by legacy id. | | Scope | Member type | `is_user_type` | Yes or no: this is a membership type rather than a job. | | Scope | Organisational role | `is_organizational` | Yes or no: a national level role. | | Scope | Chapter role | `is_local_center` | Yes or no: a role held at chapter level. | | Scope | Parent chapter role | `is_local_center_parent` | Yes or no: a role held at parent chapter level. | **Required:** `name`. **Already exists:** the role legacy id when you map one, otherwise the name, compared without regard to case. **Custom fields:** no. **Example file:** `import_roles.csv`, from the **Example CSV** link on the **Roles** card. *** ## User Roles Gives members their roles, optionally inside a unit, for a period of time. | Group | Field | Column | What it means | | - | - | - | - | | Member | Email | `email` | The member, by email. | | Member | Legacy ID | `user_legacy_id` | The member, by legacy id. | | Role | Role name | `role_name` | The role, by name. | | Role | Role legacy ID | `role_legacy_id` | The role, by legacy id. | | Unit | Unit name | `unit_name` | The unit the role is held in, by name. | | Unit | Unit legacy ID | `unit_legacy_id` | The unit, by legacy id. | | Period | Start date | `start_date` | When the role started. | | Period | End date | `end_date` | When it ended. Blank means they still hold it. | | Period | Unit admin | `is_admin` | Yes or no: this role makes them an admin of the unit. | **Required:** three things. | Group | Map at least | | - | - | | Member | `user_legacy_id`, or `email` | | Role | `role_legacy_id`, or `role_name` | | Period | `start_date` | The **Unit** group is offered but never required. **Already exists:** the member, the role, the unit and the start date together. The same person can hold the same role twice as long as the start dates differ. **Custom fields:** no. **Example file:** `import_user_roles.csv`, from the **Example CSV** link on the **User Roles** card. *** ## Companies Creates company records. | Group | Field | Column | What it means | | - | - | - | - | | Company | Name | `name` | Trading name. | | Company | Legal name | `legal_name` | Registered legal name. | | Company | Description | `description` | Description text. | | Company | Status | `status` | Company status. | | Company | Registration number | `registration_number` | Company registration number. | | Company | VAT number | `vat_number` | VAT or tax identifier. | | Company | Country | `country` | Country, matched by two-letter code, three-letter code or name. | | Company | Date created | `date_created` | Creation date. | | Company | Company legacy ID | `company_legacy_id` | This company, by legacy id. | | Contact | Contact name | `contact_full_name` | The contact person's name. | | Contact | Contact email | `contact_email` | Contact email address. | | Contact | Website | `website` | Company website. | | Contact | Address | `address` | Company address. | | Membership | Membership valid until | `valid_fee_date` | The date the company's membership fee is paid up to. | | Membership | Fee price tier | `fee_tenant_product_price_id` | The fee price tier, looked up by legacy id first and then by Orgo's own id. | **Required:** `name`. **Already exists:** the company legacy id when you map one, otherwise the name, compared without regard to case. **Custom fields:** no. **Example file:** `import_companies.csv`, from the **Example CSV** link on the **Companies** card. *** ## Company Members Links members to the companies they belong to. | Group | Field | Column | What it means | | - | - | - | - | | Company | Company name | `company_name` | The company, by name. | | Company | Company legacy ID | `company_legacy_id` | The company, by legacy id. | | Member | Email | `email` | The member, by email. | | Member | Legacy ID | `user_legacy_id` | The member, by legacy id. | | Membership | Role | `role` | Their role inside the company. | | Membership | Date created | `date_created` | When the membership started. | | Membership | Membership legacy ID | `company_user_legacy_id` | This membership row, by legacy id. | **Required:** two things. | Group | Map at least | | - | - | | Company | `company_legacy_id`, or `company_name` | | Member | `user_legacy_id`, or `email` | **Already exists:** the company and the member together, among memberships that have not ended. Somebody already in the company is skipped. **Custom fields:** no. **Example file:** `import_company_users.csv`, from the **Example CSV** link on the **Company Members** card. *** ## List members Adds people to one static list. This type is not on the import page: you start it from the list itself, so the list you are importing into comes from where you started rather than from a column in the file. | Group | Field | Column | What it means | | - | - | - | - | | Member | Email | `email` | Matched against members first, then contacts. | | Member | Legacy ID | `user_legacy_id` | A member, by legacy id. | | Member | Phone | `phone` | Phone number. | | Member | Name | `name` | Full name, used to create a contact when nothing else matches. | **Required:** one group, four alternatives. Map `email`, or `user_legacy_id`, or `phone`, or `name`. **Already exists:** membership of the list itself. Somebody already on the list is counted as already there rather than added twice. A row with no email is also matched against your existing contacts by name before a new contact is created. **Custom fields:** no. This is the one link type with no match preview. What a row resolves to is decided during the run, so a preview would not tell you the truth. **Example file:** `import_user_list_members.csv`, from the **Download example CSV** link in the list's import panel. *** ## Events Creates events. | Group | Field | Column | What it means | | - | - | - | - | | Event | Name | `name` | Event title. | | Event | Begins | `datetime_begin` | Start date and time. | | Event | Ends | `datetime_end` | End date and time. | | Event | Description | `description` | Description text, HTML allowed. Left blank, the event gets an empty description. | | Event | Event type | `event_type` | The event category. A type that does not exist yet is created. | | Event | Event legacy ID | `event_legacy_id` | This event, by legacy id. | | Location | Location | `location_name` | Venue name. | | Location | Timezone | `timezone` | The timezone the times in the file are written in. | | Location | Chapter legacy ID | `local_center_legacy_id` | The chapter that owns the event, by legacy id. | | Location | Unit legacy ID | `unit_legacy_id` | The unit that owns the event, by legacy id. | | Settings | Public | `is_public` | Yes or no: visible publicly. | | Settings | Training | `is_training` | Yes or no: counts as training. | **Required:** `name` **and** `datetime_begin`. **Already exists:** the event legacy id when you map one. Without it, the name plus the start time to the minute, so two events of the same name at different times are two events, and the same name at the same minute is one. **Custom fields:** no. **Example file:** `import_events.csv`, from the **Example CSV** link on the **Events** card. *** ## Badge Types Creates the categories badges are filed under. | Group | Field | Column | What it means | | - | - | - | - | | Badge type | Name | `name` | Badge type name. | | Badge type | Badge type legacy ID | `badge_type_legacy_id` | This badge type, by legacy id. | **Required:** `name`. **Already exists:** the badge type legacy id when you map one, otherwise the name, compared without regard to case. **Custom fields:** no. **Example file:** `import_badge_types.csv`, from the **Example CSV** link on the **Badge Types** card. *** ## Badges Creates badges under a badge type. | Group | Field | Column | What it means | | - | - | - | - | | Badge | Name | `name` | Badge name. | | Badge | Badge legacy ID | `badge_legacy_id` | This badge, by legacy id. | | Badge type | Badge type | `badge_type` | The badge type it belongs to, by name. | | Badge type | Badge type legacy ID | `badge_type_legacy_id` | The badge type, by legacy id. Wins if you map both badge type columns. | **Required:** one group, two alternatives. | Alternative | Map | | - | - | | A | `name` **and** `badge_type` | | B | `name` **and** `badge_type_legacy_id` | **Already exists:** the badge legacy id when you map one, otherwise the name, compared without regard to case. **Custom fields:** no. **Example file:** `import_badges.csv`, from the **Example CSV** link on the **Badges** card. *** ## Badge Assignments Awards badges to members. | Group | Field | Column | What it means | | - | - | - | - | | Member | Email | `email` | The member, by email. | | Member | Legacy ID | `user_legacy_id` | The member, by legacy id. | | Badge | Badge | `badge_name` | The badge, by name. | | Badge | Badge legacy ID | `badge_legacy_id` | The badge, by legacy id. | | Award | Awarded on | `concluded_at` | The date of the award. | | Award | Status | `status` | Completed or pending. Words are accepted as well as 0 and 1, and a word Orgo does not recognise fails the row rather than guessing. | | Award | Points | `points_at_award` | Points scored at the time of the award. | | Award | Member comment | `comment_user` | The member's own comment. | | Award | Reviewer comment | `comment_master` | The assessor's comment. | | Award | Award legacy ID | `badge_user_legacy_id` | This award row, by legacy id. | **Required:** three things. | Group | Map at least | | - | - | | Member | `user_legacy_id`, or `email` | | Badge | `badge_legacy_id`, or `badge_name` | | Award | `concluded_at` | **Already exists:** the badge, the member and the day of the award together, plus the award legacy id when you map one. The same badge can be awarded to the same person more than once, which is why the date is part of the key, and why it is required: a file without it, re-run on another day, would double every award. **Custom fields:** no. **Example file:** `import_badge_users.csv`, from the **Example CSV** link on the **Badge Assignments** card. *** ## Related * [Data Import](/docs/platform/customization/import) - what the wizard is and the steps it runs through * [Preparing your file](/docs/platform/customization/import/preparing-your-file) - formats, headers, dates and the example files * [Mapping columns](/docs/platform/customization/import/mapping-columns) - the mapping screen and what blocks **Start import** * [Custom fields in an import](/docs/platform/customization/import/custom-fields) - mapping onto existing fields and declaring new ones * [Linking records](/docs/platform/customization/import/linking-records) - how a row finds the member, product or event it names * [Custom Fields](/docs/platform/users/custom-fields) - the fields an import can write to * [Lists & Segments](/docs/platform/users/lists) - where a List members import starts * [Merging Duplicates](/docs/platform/users/merging-duplicates) - cleaning up records an import doubled # 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: English, Romanian, German, Bulgarian, Lithuanian, Spanish, French, Italian, Dutch, Ukrainian and Portuguese. Any other organization language (Czech, Greek, Estonian, Slovak) 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, Czech, members see a Czech 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 English, Romanian, German, Bulgarian, Lithuanian, Spanish, French, Italian, Dutch, Ukrainian and Portuguese, chosen from the organization language, with English as the fallback. Czech 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 Czech organization's invoices do arrive in Czech. 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 the [Emails page](/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 and family invitations 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 See every automatic email, change its wording in place, preview it and send yourself a test Every automatic email ships with a written-for-you version in your organisation's language. When that wording does not sound like you, change it: click a sentence in the email and type your own. The design stays Orgo's, so it keeps up with later improvements; only your words are saved. **Built for** organisations whose voice matters. **Replaces** apologising for the robot that emailed your members. Everything lives on one page: **Settings** → **Notifications & Email Campaign** → **Emails** (`/tenants/modules/emails/templates`). Admins (ADMIN\_TENANT) and communication managers (COMMUNICATION\_TENANT) can open it and edit wording; communication managers reach the same page from the main menu at `/email-templates`. Only admins can switch emails on or off, see [System emails](/docs/platform/emails/system-emails). Emails page with the section list under Emails in the left module menu, a search box and the All, Editable, Can be turned off and Off filters, and the Users section as a card listing each email with an Edit text button and an on or off switch *** ## Finding an email The page lists every email your organisation sends, one card per section: **Users**, **Referrals**, **Adhesion**, **Membership & Fees**, **Identity**, **eDocuments**, **Events**, **Donations**, **Subscriptions**, **Admin alerts**, **Sign-in & security** and **Activity notifications**. * The sections also appear under **Emails** in the left menu. Clicking one scrolls the page to it. * **Search emails** matches names and descriptions. * The filters narrow the list to **Editable** emails, those that **Can be turned off**, or those that are **Off**. Each filter shows how many emails it holds. Only sections that apply to you appear: **Referrals** and **Adhesion** show when those features are switched on, and **Membership & Fees**, **Identity**, **eDocuments**, **Events**, **Donations** and **Subscriptions** disappear when the matching feature is off. The referral emails also follow your registration setting: with manual approval on you see the versions that mention approval, without it the ones that do not. Emails Orgo sends to your organisation about its own Orgo subscription, and internal messages such as "your report is ready", are not listed: they are not yours to change. *** ## Previewing an email Click any row to open a preview of the email as your members receive it, with your wording, your logo and colour, and your own account's details filled in. This works for every email on the page, including the ones you cannot edit or switch off. The subject line sits above the email. Sign-in codes show a sample code. **Activity notifications** (new discussions, comments, mentions, votes and the discussion summary) show sample content in your organisation's language. *** ## Changing the wording Click **Edit text** on the row, or **Edit text** in the preview. The email opens exactly as it is sent, with every text you can change outlined. A heading or a button label is plain text: **Enter** keeps your change, **Escape** puts the previous wording back. A paragraph can also take **bold**, *italic* and links, from the buttons above the email. Click where the value should go, then pick it from **Insert Placeholder**. The menu lists only what this email can fill in. The **Subject** field sits above the email. Leave it alone and members keep getting the default subject in your language. **Preview** shows the email with your changes and your account's details. **Back to Editor** returns to editing. **Send Test Email** sends the email with your unsaved changes to your own address, with `[TEST]` in front of the subject. It saves nothing. **Save** makes your wording the one members receive from that moment on. Inline editor for the Welcome email: the Subject field, the Insert Placeholder and Use default buttons, and the email itself with each editable text outlined, with Send Test Email, Preview and Save in the header To put one text back to the default, clear it and save. Every text you leave untouched keeps the default wording, so a later improvement to that sentence still reaches your members. *** ## Placeholders A placeholder is written `{{name}}` and is replaced with real data when the email is sent. Most emails can use these: | 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 emails add their own: event emails carry the event's name, date and place, contract reminders the document and its expiry date, renewal reminders the expiry date and the product. The **Insert Placeholder** menu is the authoritative list for the email you have open. **Save** refuses a placeholder the email cannot fill and names it, so a typo such as `{{firstname}}` cannot reach your members as literal text. Pick a replacement from **Insert Placeholder**. *** ## Going back to the original **Use default** in the editor toolbar removes your wording and your subject for this email, after you confirm. It cannot be undone: the email goes back to the built-in version exactly as it was before you touched it. *** ## Language The built-in wording exists in English, Romanian, German, Bulgarian, Lithuanian, Spanish, French, Italian, Dutch, Ukrainian and Portuguese. Orgo uses your organisation's default language; any other language falls back to English. Your wording is saved for the language you wrote it in. If you later change the organisation's default language, members get the built-in wording in the new language until you edit the email again. The invoice email 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). *** ## Emails customised in the old editor An email you customised before the inline editor arrived was saved as a whole document. Members still receive that saved version, without the current design, and the editor says so in a notice above the email. Saving the email in the editor replaces it with the current design and your texts. *** ## What you cannot change * **Sign-in & security** emails (login, multi-factor, verification, password and email-change codes and confirmations, and the event app code) can be previewed but not edited. They carry live one-time codes, so their wording is fixed. * **Activity notifications** can be previewed but not edited. Each member chooses which ones they get, see [Notifications](/docs/platform/notifications). * A few admin alerts, such as **Reactivation request**, **Group transfer request**, **Resignation request** and **Referral received**, can be switched off but not edited. Some emails have no row at all and always send in their built-in wording, among them invoices, family invitations, waitlist messages, task notifications and event-app networking messages. *** ## Troubleshooting Check that you pressed **Save** rather than only previewing, 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 this email, often because of a typo or a placeholder copied from another email. Delete it and pick a replacement from **Insert Placeholder**. It was customised in the old editor. Open it in the editor and save: it moves to the current design and keeps your texts. 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). Clear that text in the editor and save. To reset the whole email, use **Use default**. *** ## Related * [System emails](/docs/platform/emails/system-emails) - what each email is for, when it sends, and switching it off * [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; communication managers (COMMUNICATION\_TENANT) can also open the **Emails** page and change wording. The delivery log and the lists sit in the Administration area instead. *** ## The three surfaces | Surface | Where | What it is for | | - | - | - | | **Emails** | Settings → Notifications & Email Campaign → Emails | See every automatic email, preview it, change its wording, and switch it on or off | | **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. Email is available in English, Romanian, German, Bulgarian, Lithuanian, Spanish, French, Italian, Dutch, Ukrainian and Portuguese: if your default language is anything else, emails fall back to English. Wording you change yourself is saved for the language you wrote it in, and every recipient gets that version. If you change the organisation's default language later, the built-in wording in the new language applies until you edit the email again. 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 that email is switched off on the **Emails** page, nothing is sent and nothing is logged as sent. Sign-in and security emails, the newsletter signup confirmation and workflow emails ignore this check and always send. The built-in email in your organisation's language, with any texts and subject you changed in place of the defaults. 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 and family invitations are never written to the log. Otherwise the email was either switched off on the **Emails** page 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, falling back to English for a language email does not cover. A member's own interface language does not change it. Invoice emails are the exception and cover all 14 languages. Find it on the **Emails** page and turn off the switch on its row. Every email has its own switch; **Turn all off** on a section is only a shortcut. *** ## Related * [System emails](/docs/platform/emails/system-emails) - the catalogue of automatic emails, what triggers each, and which can be switched off * [Email templates](/docs/platform/emails/email-templates) - previewing an email, changing its wording, 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 on the **Emails** page: **Settings** → **Notifications & Email Campaign** → **Emails** (`/tenants/modules/emails/templates`). Switching an email on or off needs ADMIN\_TENANT; communication managers (COMMUNICATION\_TENANT) see whether each email is on but cannot change it. Changes save as you flip them. The old **Emails Config** address now opens this page filtered to the emails that **Can be turned off**. Emails page filtered to Can be turned off, with section cards for Users and Membership and Fees, each email row with its switch, an off count on the section and the Turn all on or Turn all off button *** ## How the switches work Every email that can be turned off has its own switch on its row. Each section card shows how many of its emails are off, and **Turn all off** or **Turn all on** switches the whole section in one go. You can leave the renewal reminders 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. Organisations that used the old category switches keep what they chose: an email whose category was off shows as off on its row until you switch it on. Some emails always send and show **Always sent** instead of a switch: the **Sign-in & security** emails (a member locked out of their account is not a preference) and the newsletter signup confirmation (without it nobody can finish subscribing). The emails Orgo sends you about your own Orgo subscription are not listed and always send. *** ## Members and accounts | Email | Sent when | Can be turned off | | - | - | - | | **Account confirmation** | Someone registers and must confirm their address | Yes | | **Welcome** | A member's account becomes active | Yes | | **User invitation** | An admin invites someone to join | Yes | | **Company invitation** | Someone is invited to join a company profile | Yes | | **Account created by admin** | An admin creates the account rather than the member registering | Yes | | **Adult eligibility** | A child member comes of age and can sign in on their own | Yes | | **Waitlist eligibility** | A child becomes old enough to register from the waitlist, sent to the parents | Yes | | **New member notification** | A new member registers, sent to admins | Yes | | **Reactivation request** | A former member asks to come back, sent to admins | Yes | | **Newsletter registration** | Someone subscribes to the newsletter and must confirm their address | No, always sends | | **Account deactivated** | An account is deactivated, sent to admins | No, always sends | | **Family invitation** | A member invites a family member to link accounts | No, always sends | *** ## Sign-in and security None of these can be switched off or edited. They are listed under **Sign-in & security** on the Emails page so you can preview them, and the platform refuses to save custom wording for them. | 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. Each of the fourteen (seven here, seven for companies) can be turned off on its own, under **Membership & Fees**. | 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 | Can be turned off | | - | - | - | | **Renewal Confirmed** | A recurring membership charge succeeds | Yes | | **Renewal Failed** | A recurring membership charge fails | Yes | | **Fee Payment Approval** | An admin approves a recorded fee payment | Yes | | **Invoice** | An invoice is emailed, with the PDF attached | No, 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 | Can be turned off | | - | - | - | | **Event invitation** | A member is invited to an event | Yes | | **Free event registration** | Someone registers for a free event | Yes | | **Paid event registration** | A ticket purchase completes | Yes | | **Guest tickets** | A buyer's tickets are issued for other people | Yes | | **Attendance confirmed** | A ticket is confirmed for an attendee | Yes | | **24-hour reminder** | A published event starts tomorrow, sent once to everyone who registered at least a day before | Yes | | **1-hour reminder** | An event with the one-hour reminder enabled starts in about an hour, checked every 10 minutes | Yes | | **Attendance reminder** | An event ended 24 hours ago and attendance still needs recording | Yes | | **Networking invitation, accepted, declined, cancelled** | A meeting request in the event app changes state | No, always sends | *** ## Applications, identity and documents | Email | Sent when | Can be turned off | | - | - | - | | **Adhesion pending review** | An application is submitted, sent to admins and HR | Yes | | **Adhesion approved** | An application is approved | Yes | | **Adhesion rejected** | An application is rejected | Yes | | **Adhesion reverted to draft** | An admin sends an application back for changes | Yes | | **Adhesion form validated** | An admin validates the signed form | Yes | | **Identity validation requested** | A member uploads identity documents | Yes | | **Identity rejected** | A submission is rejected, with the reason | Yes | | **Identity payment reminders (3)** | Hourly job, for members who owe an identity validation payment | Yes | | **New identity for review** | Sent to finance when a document needs checking | Yes | | **Contract expiry: 30 days, 7 days, today, 7 days overdue** | Daily job at 08:00 UTC against each document's validity end date | Yes | | **Contract signed, pending** | One party has signed and others have not | Yes | | **Contract signed, complete** | Everyone has signed, sent to the signer, with a separate version for admins | Yes, each version on its own | *** ## Subscriptions and payments | Email | Sent when | Can be turned off | | - | - | - | | **Subscription created** | A recurring payment is set up | Yes | | **Subscription payment received** | A recurring charge succeeds | Yes | | **Subscription cancelled** | A recurring payment is cancelled | Yes | | **Identity expiring** | Daily job at 07:00 UTC, for subscriptions whose identity document is about to expire | Yes | | **Subscription cancelled, identity expired** | Daily job at 08:00 UTC: three days before the identity document expires, the subscription is set to end and the member is told | No, always sends | | **Checkout reminder** | Daily job at 08:00 UTC, for an abandoned checkout | Yes | | **Donation thank you** | A donation payment completes | Yes | | **Form submission confirmation** | Someone submits a form that has confirmation enabled | Yes | | **Donation refunded** and **recurring donation stopped** | A donation is returned, or a recurring one stopped, because it would pass the annual limit per donor | Yes | *** ## Community, local centres and everything else | Email | Sent when | Can be turned off | | - | - | - | | **Local centre request, approved, declined** | A member asks to join a local centre and an admin decides | Yes | | **Resignation request** and **approved** | A member asks to resign and an admin decides | Yes | | **Referral received** | Someone signs up through a referral link | Yes | | **Referral complete** | A referral is finished, one version for the referrer and one for admins, differing by whether your organisation approves registrations manually | Yes | | **Post held for moderation** | A discussion post is held, sent to moderators | No, always sends | | **Connection request** and **accepted** | Members connect in the event app | No, always sends | | **Vote open** and **vote closed** | A vote opens or closes. Members receive them through their vote notification preference; non-member attendees of an event vote receive the opening one with a personal voting link | No, each member chooses | | **Waitlist confirmation, approved, rejected, position update, new entry** | The registration waitlist changes | No, always sends | | **Task assigned, status changed, comment added, due soon, overdue** | Task activity | No, always sends | *** ## Digests Three summary emails run on a schedule instead of reacting to one event. | Digest | Runs | Contains | | - | - | - | | **Daily discussion summary** | 06:00 UTC | Sent to active members whose discussion preference is Daily who have unread discussions from the last 25 hours. It lists up to the 10 newest, grouped by group, with a count of the rest | | **Weekly discussion summary** | Wednesdays 09:00 UTC | The same, over the last 7 days, for members set to Weekly | | **Daily task digest** | 06:00 UTC | Open tasks assigned to the member | The discussion summary lists discussions only. Events, mentions, comments and votes reach a member as their own emails, if their preferences ask for them. Sending the summary marks the discussions it covers as seen in the app, and nothing else. Members choose Instant, Daily or Weekly in their own notification preferences, or switch discussion email off entirely. Discussion and other activity emails follow each member's notification preference, so they have no switch on the Emails page. You can preview each one under **Activity notifications**. To change what new members start with, set the defaults in **Notification Preferences**. See [Notifications](/docs/platform/notifications). *** ## Related * [Emails](/docs/platform/emails) - sender identity, language and delivery * [Email templates](/docs/platform/emails/email-templates) - previewing an email and rewriting its wording * [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. Running events for a specific kind of organization? [Scouting and youth organizations](/docs/platform/templates/scouting#camps-and-events) covers camps end to end, and [Political parties](/docs/platform/templates/political-party#internal-elections) covers internal elections. See all [Setup Templates](/docs/platform/templates). *** ## 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** | `COMMUNICATION_TENANT` | Opens the [Emails page](/docs/platform/emails/email-templates) at the event emails | | **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 One rule, and both halves of it must be true: * the event is **published**, and * its audience is set to **Public**. Ticketing does not change this. A members-only event with ticketing enabled has no public page, because members buy their tickets on the event page inside the app. Anything that fails either half refuses the request: 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 and Fees section of the Emails page, listing the renewal reminders with their send timing from 1 Month Reminder through 30 Days After Reminder, each with Edit text and its switch The **1 Day Reminder** appears on the Emails page 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 reminders (seven individual, seven company) are listed under **Membership & Fees** at **Settings** → **Emails & Notifications** → **Emails**. **Edit text** changes the wording, and each reminder has its own switch, so you can silence one rung and keep the rest. **Turn all off** stops the whole section. *** ## 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 the reminder is switched on under **Membership & Fees** at **Settings** → **Emails & Notifications** → **Emails**. 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** | | **Group transfer request**, **Group transfer approved** and **Group transfer declined** switched on | **Settings** → **Modules** → **Emails & Notifications** → **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 that the group transfer emails are switched on at **Settings** → **Modules** → **Emails & Notifications** → **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. *** ## Not sure where to start? If you already know what kind of organization you're running, skip the feature-by-feature tour below and go straight to a [Setup Template](/docs/platform/templates) — a playbook that names the exact modules to turn on, in order, for your kind of organization. Formal membership applications, identity checks, chapters, internal elections. Members that are companies or institutions: company membership, seats, invoicing. Age-based sections, parents and consent, safeguarding, progression, camps. One-off and recurring giving, campaign pages, donor recognition and receipts. [See all Setup Templates →](/docs/platform/templates) *** ## 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): preview any automatic email and change its wording in place * [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. * **Build and move your public website**: write pages and news, organize menus, apply a template, or bring an existing site across from WordPress or Squarespace. See [Building your website by asking](#building-your-website-by-asking) below. Under the hood, the assistant has access to the full Orgo REST API (780+ operations across members, events, payments, newsletters, votes, the website builder, 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 the one you sign in with, not the one in the address — the same address serves every organization. Administrators find it inside Orgo too, under **Website** → **Build by asking**, ready to copy. An older address of the form `https://.mcp.orgo.space/mcp` still works and existing connectors using one keep working. There is no longer any reason to prefer it: it reaches the same server and the same sign-in. ### If you belong to several organizations The sign-in page lists every organization your email is a member of and asks you to pick one. That choice is fixed for the life of the connection: the connector is bound to the organization you picked, and the assistant can neither see nor reach the others through it. To work in a second organization, add the connector a second time under a different name and pick that organization when you sign in. 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 (488 paths, 787 operations) | | Auth helpers | `whoami`, login with OTP verification, token refresh | | Website builder | `website_guide` — the authoring and migration workflow, plus the full section vocabulary, read from your own organization | | Documentation resources | Resources under the `orgo://` scheme: concepts, recipes, webhooks, and the website guide and schema | | Transports | stdio (local), HTTP with OAuth (hosted), SSE streaming | *** ## Building your website by asking Your organization's public website is the one part of Orgo an assistant does not reach through the ordinary endpoint list. Pages and news articles are documents, not rows, and they are made of a fixed vocabulary of sections that cannot be guessed. So the connection carries its own instructions: for anything touching the website, the assistant reads `website_guide` first, which returns the workflow and the vocabulary **from your organization**, generated by the same code that validates a save. There is nothing to install and nothing to teach it. Things people ask: * *"Set up my website from the template that fits a cultural organisation, then show me the homepage."* * *"Add a Volunteering page with a hero, three ways to help and a contact form, and put it in the header menu."* * *"Our address changed: redirect /contact-us to /contact permanently."* * *"Publish everything that has changed since last week."* ### Moving an existing site in Ask the assistant to move your current site across — WordPress, Squarespace, Wix, WildApricot, Hivebrite and NationBuilder are all covered — and it will fetch the pages itself, decide what each part of them *is*, and express that in Orgo's vocabulary. It is a mapping, not a clone: a copy would inherit the old site's layout accidents and its bad behaviour on phones, which is usually why you are moving. Two things stop and ask you, every time: 1. **Before anything is written.** The assistant runs the import as a dry run and shows you what would land — the pages, the section counts, what it could not map. Nothing has changed at this point. 2. **Before anything is public.** Publishing is a separate, deliberate call. Everything up to it is reversible from a snapshot, which Orgo takes before every write. Pictures and downloadable documents (PDF, Word, Excel, PowerPoint, OpenDocument, CSV) come across by address: the assistant asks Orgo to fetch each one, and a downloads page becomes a `files` section. Archives and anything that is not a document are listed for you instead. What does not come across: your old newsletter provider, which maps to Orgo's own list; and a shop, which has no equivalent. The assistant tells you what it found rather than quietly flattening it. Redirects matter more than they look. A migration without them throws away every inbound link and search ranking the old addresses had earned. Ask for them explicitly if the assistant has not proposed them. *** ## Troubleshooting Your AI tool could not reach the address you entered, so it never got as far as the Orgo login. Check the address for typos — it ends in `/mcp` — then remove the connector and add it again. In Claude Code the address has to be added with `--transport http`; without it the URL is treated as a command to run and the connection never starts. Sign-in opens in a browser window that pop-up blockers sometimes hide. Look for a blocked pop-up notice in the address bar, allow it, and retry. In Claude Code, run `/mcp` and pick the Orgo server to start the sign-in by hand. The assistant works inside the organization you chose when you signed in, and that choice cannot be changed afterwards. Remove the connector, add it again, and pick the right organization from the list on the sign-in page. It has exactly your permissions. Anything your own account cannot see or change in Orgo, the assistant cannot either. *** ## 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 * [Website Builder](/docs/platform/organisation/website-builder) - the site the assistant is authoring, and how to edit it by hand * [Public website](/docs/platform/organisation/public-website) - the public pages your organization gets before you build any of your own # 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 and the **Emails** page, where every automatic email is previewed, reworded and switched on or off. The page header reads "Notifications & Email Campaign". | Email Campaigner, Notification Preferences, Contact forms, Emails | | **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 | | 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: it renders in the organization default only, in English, Romanian, German, Bulgarian, Lithuanian, Spanish, French, Italian, Dutch, Ukrainian or Portuguese, 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 * [Website Builder](/docs/platform/organisation/website-builder) - Write a site of your own: your pages, your news, your menus, your domain * [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 # Website Builder Source: https://orgo.space/docs/platform/organisation/website-builder Build your organization's public website out of ready-made sections, then publish it to your own domain — or ask an AI assistant to build it for you The website builder is where your organization's own website is written: pages and news articles made of ready-made sections, a header and footer menu, your colours, your domain. It is not a page of settings for the [small public site](/docs/platform/organisation/public-website) every organization already gets — it is a site you author, with as many pages as you want to write. What it replaces is a separate website you would otherwise host somewhere else, keep in sync by hand, and re-key every event, chapter and document into. Here the events section pulls your real events, the chapters section your real chapters, and the downloads section the files you have already shared from Drive. **Settings → Organization → Website** Requires **ADMIN\_TENANT** and the website module. Without the module the menu entry is not there and every call behind it is refused, so an address typed by hand gets you nowhere either. *** ## The five areas | Area | What you do there | | - | - | | **Pages** | Write and order the pages of the site. This is also where news is switched on. | | **Articles** | Write news articles. The tab appears once news is on. | | **Header & Footer** | The two menus: what is in them and in what order. | | **Settings** | Your domain, custom code, and redirects. | | **Design** | Colours and link styles, and the starter templates. | *** ## Pages are made of sections A page is an ordered list of sections, each one a shape that already knows how to behave on a phone. You choose the shape and fill it in; you do not lay anything out. | Section | For | | - | - | | `hero` | The opening statement: a headline, a line under it, up to three buttons, optionally a background image or a short silent video | | `text` | A run of prose — an about page, a policy, a long explanation | | `imageText` | One image beside one block of text; repeat with alternating sides for a sequence | | `image` | A picture that *is* the content, not an illustration of nearby text | | `cards` | A row of linked cards with pictures — programmes, news teasers, "explore these" | | `features` | Icon cards: a glyph, a short title, two lines. For "what we do" where there are no photographs | | `stats` | A band of numbers with labels, for when the figures are the argument | | `cta` | One loud panel asking for a single action. Once per page — a page that asks three times asks for nothing | | `banner` | A full-bleed photograph with a heading and a button, mid-page | | `gallery` | A grid of photographs, optionally opening into a lightbox | | `video` | One embedded video or podcast episode | | `quote` / `testimonials` | One pulled quote, or several short endorsements with faces | | `people` | A roster: photograph, name, role, a line of biography | | `logos` | A wall of partner, funder or member logos | | `faq` | Questions with expandable answers | | `columns` | Two or three columns of parallel text | | `divider` | A rule or a gap between two sections | | `form` | One of your own forms, filled in and sent without leaving the page | | `files` | Documents to download, taken from Drive | | `events` | Your upcoming public events, pulled live | | `articles` | Your published news, newest first, optionally one category | | `chapters` | The map and list of your local chapters | | `donate` | The donation panel, wired to your payment setup | | `newsletter` | The sign-up form for your own newsletter list | The last six are live: you write the heading, the platform supplies the content, and it stays correct without anyone revisiting the page. ### Sections that need something to exist first The section stores the form's identifier and fetches its questions when the page renders, so adding a question updates every page carrying it and closing the form closes it everywhere at once. Never re-type a form's questions into another section. Two conditions, both refused on save with a message naming the block: the form must be **published or closed** — a draft is not embeddable — and it must be answerable by somebody with no Orgo account. A members-only form on a public page would render questions a visitor can fill in and cannot send, so it is refused rather than embedded. Each row of the section is one document, from one of two places: * **Uploaded to the website.** Press **Upload** next to the file search and choose a PDF, Word, Excel, PowerPoint, OpenDocument, RTF, EPUB, text or CSV file, up to 25 MB. It is checked, stored on the website and listed in the search from then on. It stays public until it is deleted — there is no share to revoke. A document still listed on a page cannot be deleted until it is taken off that page. * **Shared from [Drive](/docs/platform/files).** Search for a file you have already shared publicly. The permissions and the revocation stay in Drive: revoking the share later takes the download off the site. Prefer this for documents the organisation keeps and updates in Drive. Archives, web pages, images and programs are refused on upload. Every entry is listed as a file, never as a picture — a photograph a visitor is meant to *look* at belongs in `gallery` or `image`. Without a donation product the section hides itself from visitors rather than showing an empty panel. See [Donation Pages & Widgets](/docs/platform/fees/donation-pages). Both pull from the platform. The events section needs the events module; the chapters section shows your active local centers, so it is empty until you have some. *** ## Starting from a template Six starter templates under **Design → Templates**, each a complete small site — pages, sections, menus and a matching palette — that you then edit: | Template | For | | - | - | | Civic | Parties, movements and campaign groups | | Cultural | A theatre, festival, choir or heritage organisation | | Educational | Youth programmes, training and scouting | | Environmental | Conservation, climate and local green action | | Professional | Professional bodies and chambers | | Social | Community support and direct services | A template is a starting point, not an import. If you already have a website somewhere else, do not rebuild it by hand from a template — [move it across](#moving-an-existing-website-in) instead. *** ## Design **Design → Theme** sets six colours — accent, page background, alternate surface, body text, header background, footer background — and how links behave on hover. Everything else follows from them, so the site stays coherent without anyone picking a colour per page. *** ## Your address Every organization's site starts on an Orgo address of the form `your-org.orgo.cloud`, live the moment you publish. To use a domain you own, enter it under **Settings → Domain**. Orgo shows you the DNS record to add and then reports what it sees: | Status | What it means | | - | - | | Live | Visitors reach the site here over a secure connection | | Setting up the certificate | The DNS record is in place; this usually takes a few minutes | | Not reaching Orgo yet | Check the record with whoever manages the domain name | The domain your website uses is separate from the address your members sign in at. See [Custom Domain](/docs/platform/custom-domain). ### Custom code **Settings → Custom code** adds markup inside `` and before `` — an analytics tag, a verification meta tag, a chat widget. Up to 8,000 characters each. Custom code runs on the **published site only** — never in the builder and never in the preview. That is a safety boundary, not an omission: code you paste cannot reach the screen where you are signed in as an administrator. ### Redirects **Settings → Redirects** maps an old address to a new one. They matter most when you move a site in: without them, every link anyone ever shared to the old site, and every search ranking those addresses earned, stops working on the day you go live. *** ## Publishing Nothing you write is visible to anybody until you publish. Two separate things have to be true: Pages are drafts until you say otherwise. You can publish one page or the whole site. One switch decides whether visitors reach the site at all. Until it is on, a published page is still only visible to you. Publishing queues a build: the site is rendered to static files and served from a CDN, which is why a published page loads faster than the builder that made it. Changes you save afterwards do not reach visitors until you publish again — the builder tells you which areas have unpublished changes. Orgo takes a snapshot of the whole site before every write, so a change you regret can be put back. *** ## Building your website by asking You can connect an AI assistant to your organization and describe what you want instead of clicking it together: > *"Add a Volunteering page with a hero, three ways to help and a contact form, and put it in the header menu."* The **Connect MCP** button at the top of the builder gives you the address and the steps for Claude, Claude Code, ChatGPT and other assistants. The assistant works with your permissions and never publishes anything by itself. See [Orgo MCP](/docs/platform/mcp). ### Moving an existing website in Ask the assistant to move your current site across — WordPress, Squarespace, Wix, WildApricot, Hivebrite and NationBuilder are all covered. It reads the old site, decides what each part of it *is*, and expresses that in the sections above. It is a mapping rather than a copy: a clone would inherit the old site's layout accidents and its bad behaviour on phones, which is usually why you are moving in the first place. It stops and asks you twice — once before anything is written, with a preview of what would land, and once before anything becomes public. Pictures and downloadable documents — statutes, reports, forms as PDF or Office files — come across with the pages, and a downloads page becomes a `files` section. Your old newsletter provider and any shop do not come across; the assistant tells you what it found rather than quietly flattening it. *** ## Troubleshooting Publishing a page and putting the site live are two separate steps. Check the live switch, then check that the page itself is published rather than a draft. Saving is not publishing. The builder marks the areas holding unpublished changes; publish again to send them. The `files` section can only list documents that are publicly shared in Drive. Share it there, then add it here. If a download has stopped working, check whether the share was revoked. A draft form cannot be embedded, and neither can a members-only one: on a public page it would show questions a visitor can fill in and cannot send. Publish the form and set it to accept answers from people without an Orgo account. It needs the website module and **ADMIN\_TENANT**. Both are checked on the server, so the missing menu entry is the symptom rather than the cause. *** ## Related * [Public website](/docs/platform/organisation/public-website) - the small fixed site every organization gets, before you build one of your own * [Custom Domain](/docs/platform/custom-domain) - the address your members sign in at * [Branding](/docs/platform/organisation/branding) - the logo the site's header and footer use * [Orgo MCP](/docs/platform/mcp) - connect an assistant and build the site by asking * [Files](/docs/platform/files) - Drive, and the shares the downloads section reads * [Forms](/docs/platform/forms) - the forms a page can embed * [Donation Pages & Widgets](/docs/platform/fees/donation-pages) - what the donate section needs * [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, available in English, Romanian, German, Bulgarian, Lithuanian, Spanish, French, Italian, Dutch, Ukrainian and Portuguese * [ ] `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** | Settings → Notifications & Email Campaign → Emails | Every automatic email with a preview, its wording to change in place, and an on or off switch per email. See [System emails](/docs/platform/emails/system-emails) and [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 is available in English, Romanian, German, Bulgarian, Lithuanian, Spanish, French, Italian, Dutch, Ukrainian and Portuguese. 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** lists every automatic email by section (Users, Membership & Fees, Adhesion and the rest), each with its own switch. Click an email to preview it. 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 page filtered to Can be turned off, with section cards for Users and Membership and Fees, each email row with its switch, an off count on the section and the Turn all on or Turn all off button **Done when** every email is on deliberately or off deliberately, rather than on because nobody looked. On the same page, **Edit text** opens the email as it is sent: click a sentence and type your own, change the subject, insert placeholders. Your wording is saved for the organization's language and every recipient gets it. 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 that email's switch on the **Emails** page 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, falling back to English for a language email does not cover, and wording you change yourself 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 switches on the **Emails** page 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 email on the **Emails** page reviewed and switched on or off deliberately * [ ] Emails that did not sound like you rewritten with **Edit text** on the **Emails** page * [ ] **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** email | **Settings → Modules → Emails & Notifications → Emails** | `ADMIN_TENANT` or `COMMUNICATION_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 → Emails**, find **Donation Thank You** under **Donations** and click **Edit text**. 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 wording goes to every donor as written, whatever language they read the platform in. It is saved for your organisation's default language, which is also the language of the built-in version. **Done when:** the email reads in your own voice. 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 those two emails under **Subscriptions** on **Settings → Modules → Emails & Notifications → Emails** silences the only cancel link a donor who is not a member ever receives. Leave them 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 has its own switch under **Donations** on **Settings → Modules → Emails & Notifications → Emails**. An email 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 | **Group transfer request**, **approved** and **declined** | **Settings → Modules → Emails & Notifications → 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** → **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. They are listed under **Adhesion** at **Settings** → **Emails & Notifications** → **Emails**, each with its own switch and **Turn all off** for the five together, and each can be reworded with **Edit text** (see [Email templates](/docs/platform/emails/email-templates)). Your wording 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 the email is switched on under **Adhesion** on the **Emails** page. 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** → **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 has its own switch, **Referral received - Admin Notification**, under **Referrals** at **Settings** → **Emails & Notifications** → **Emails**, next to 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 request** and **Resignation approved** | Settings → Emails & Notifications → Emails | The two resignation emails (request to admins, approval to the member), each with its own switch. On by default; off keeps the workflow but stops that email | *** ## 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 | Each has its own switch on the **Emails** page. 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)