Skip to content

Groups

This document will help you create groups and organisations, manager their members and accept or reject invites.

AI-assisted, human-approvednovem uses AI to review and keep our documentation up to date.

Overview

Groups control how resources are shared among users. A group belongs to an individual user or an organisation. This reference covers membership, roles, invitations, and group profiles.

The examples use fictional users and the fictional organisation acme.

Groups

Groups can either belong to a user and be a user group or an organisation and be an org group.

A user group consists of an @ followed by a username, then a ~ and a group name. An organisation group consists of a + followed by an organisation name, then a ~ and a group name.

Usernames, organisation names, and group names cannot contain spaces.

User groups are created by PUTing a group name under the /admin/groups/ folder and organisations by PUTing an organisation name under the /admin/orgs/ folder.

To add a user to a group you simply PUT the username in the /admin/groups/<group_name>/roles/<ROLE>/ folder where <ROLE> is one of founders, admins, superusers or members.

The user creating a group or organisation is automatically given the founder role.

The groups of which you are a member are listed under /admin/groups, keyed by their group slug (not the display name). Org groups you can see are also surfaced under /orgs/<org>/groups.

User Groups

User groups are the unit of sharing for individuals. Create one by PUTting a group name under your /admin/groups/ folder; you become its founder automatically.

PUT /v1/admin/groups/analysts

A user group is referenced elsewhere, for example when sharing a visual, as @username~groupname (e.g. @alice~analysts).

Inviting users

Add a member by PUTting their username into one of the group's role folders. The roles, from most to least privileged, are founders, admins, superusers and members.

PUT /v1/admin/groups/analysts/roles/members/bob

The invited user receives an invitation they must accept before the membership becomes active; until then they show in the role listing with an I- prefix (the same pending marker used for social connections).

Accepting or declining an invite

Pending invites are listed under the invited user's /admin/invites/ folder, keyed by the group reference (@alice~analysts). Each invite holds a single accept endpoint; POST yes to it to accept, or no to decline:

GET  /v1/admin/invites                            -- list pending invites
POST /v1/admin/invites/@alice~analysts/accept     -- body: yes (or no to decline)
curl -X POST -H "Authorization: Bearer $NOVEM_TOKEN" \
  -H "Content-Type: text/plain" \
  --data "yes" \
  https://api.novem.io/v1/admin/invites/@alice~analysts/accept

Note: Text bodies must be sent as text/plain. curl's --data flag defaults to application/x-www-form-urlencoded, which the API rejects — always pass -H "Content-Type: text/plain" alongside it.

Promoting users

Changing a member's role is the same PUT, into a different role folder — to promote bob from member to admin:

PUT /v1/admin/groups/analysts/roles/admins/bob

Removing users

DELETE the user from the role folder to revoke their membership. The role folder must be the one the user actually holds — deleting bob from roles/members/ when he is an admin removes nothing and answers 404.

DELETE /v1/admin/groups/analysts/roles/members/bob

Leaving a group or organisation

An accepted member may delete their own role, including after a subscription downgrade. The last accepted founder must arrange a replacement before leaving. The webapp provides a confirmed leave action in the group or organisation header.

Leaving an organisation removes your organisation role only. Your memberships in its groups remain, so you can still see the organisation and access content through those groups. Leave each group separately to remove those memberships. Content may remain reachable through other shares or public access.

Who may promote and remove whom

Role management needs superuser or above, and reaches your own rank and below. A superuser may add and remove members and other superusers; an admin may do the same to admins; a founder to founders. Nobody can promote someone above their own rank, and nobody can remove or demote someone above it — so an admin cannot appoint a founder, and a superuser cannot remove an admin.

Two further restrictions apply:

  • A group always keeps a founder. The last remaining founder can neither be removed nor demoted, including by themselves. Appoint another founder first.
  • A user group's founder is fixed. It is set when the group is created and cannot be granted, changed or removed afterwards. Organisation and org-group founders have no such restriction.

Revoking an invite you sent

An invite is pending until the invitee accepts it, and whoever sent it can always withdraw it in that window — even if you have since been demoted, and even if someone more senior has raised the role the invite carries. Use the role folder the invite currently names:

DELETE /v1/admin/groups/analysts/roles/admins/bob

Once bob accepts, removing the membership follows the rank rules above. You can withdraw your own pending invitations while you remain in the group. Before leaving, withdraw them or ask a remaining admin to manage them.

Organisations

Organisations are shared parents for groups that belong to a company or team rather than a single user. Create one by PUTting an organisation name under /admin/orgs/; as with groups, the creator becomes the founder.

PUT /v1/admin/orgs/acme

Note: Two constraints apply, both enforced by the API: only organisation accounts can create organisations (a regular account gets a 403), and each account can create exactly one.

Organisation-level roles (membership of the organisation itself) are managed under /admin/orgs/<org>/roles/<role>/<user> using the same four role folders.

Organisation Groups

An organisation's groups live under the org and are referenced as +orgname~groupname, e.g. +acme~research. They are created and have their members managed exactly like user groups, one level deeper under the org:

# create the research group under the acme org
PUT /v1/admin/orgs/acme/groups/research

# add a member
PUT /v1/admin/orgs/acme/groups/research/roles/members/bob

Organisation admins see every group

An organisation admin or founder has oversight of every group under the organisation. All of the org's groups appear in their views — the /v1/orgs/:org/groups listing, the organisation's groups in GraphQL, and the dashboard — each with its profile and full member roster, even for groups the admin has not joined. A superuser is an in-group moderator role and carries no org-wide oversight; like a regular organisation member, they see only the groups they belong to.

Oversight is read-only on its own. To administer a group — invite or remove members, edit its profile or options — an org admin must hold a role in the group itself, and may claim one directly, without waiting for an invite, by PUTting their own username into a role folder:

# an org admin claims the admin role on a group under their org
PUT /v1/admin/orgs/acme/groups/research/roles/admins/alice

The role takes effect immediately, with no invitation to accept, because the admin is exercising the organisation's own authority. This is the intended way to take over a group whose previous administrator has left. Until a role is claimed the group's role sub-resource returns nothing, since the admin holds no role in it yet.

Inbound e-mail address

An org group can have its own inbound e-mail address. Mail sent to it triggers a run of every job shared with the group; it is not delivered to the group's members. The address is computed and read-only; it takes the form <group>@<org>.<org-mail-domain>, for example research@acme.<org-mail-domain> (the domain suffix is configured per environment).

Each trigger must have exactly one unambiguous From address and authenticate that sender with aligned DKIM or envelope SPF. A message that fails this check is retained as inbound mail for diagnosis but starts no job and receives no reply. When a run is admitted, its result is sent to the From address and copied to each To or Cc recipient who holds a verified novem e-mail address and may run the job themselves. A failed run is reported to the sender alone. Other recipients and Reply-To get nothing, and a Bcc recipient is not visible to novem, so it gets no copy either.

The address exists only when both of these hold:

  • the parent organisation has its mail subdomain enabled, and
  • the group accepts inbound mail.

Read it from the group's email sub-resource. When the group is not mail-enabled the value is empty:

GET /v1/orgs/acme/groups/research/email     -- plain text, "" if not mail-enabled

Any member of the group (member, superuser, admin or founder) can read it. The same value is returned as the email field on the group's info object and as the email field on Group in GraphQL; both are null when the group is not mail-enabled.

Group & organisation pages

A group or org has a profile, the page people see at its public URL. It works like your own profile: a profile folder with text fields and imagery, all written with POST (or PUT/DELETE for imagery) by a founder or admin.

VerbPathDescription
GET.../profileThe profile folder
POST / GET / DELETE.../profile/nameDisplay name
POST / GET / DELETE.../profile/descriptionDescription, rendered as markdown
POST / GET / DELETE.../profile/picture/imageAvatar
POST / GET / DELETE.../profile/picture/bannerBanner
POST / GET / DELETE.../profile/picture/maskAvatar crop (x,y,r)

.../ is /admin/groups/:group for a user group or /admin/orgs/:org/groups/:group for an org group; orgs themselves expose the same profile tree at /admin/orgs/:org.

Organisation workflow activity

GET /v1/orgs/:org/profile/stats/activity returns a daily workflow-run series for the authenticated caller's readable shares within an organisation. Despite living under the read-oriented /orgs tree, this is member activity, not public organisation analytics.

The caller must hold an accepted member, superuser, admin or founder role either directly on the named organisation or on one of its child org groups. A pending role does not qualify; an unknown organisation or a caller without that relevance receives 404. The activity itself is narrower than that relevance check: it includes only distinct jobs carrying a readable ({r}) share to a child org group under the named organisation in which the caller is an accepted member. A job shared through more than one qualifying group is counted once.

There is no parent-organisation content inheritance. A direct organisation member or administrator who belongs to none of its child groups can reach the endpoint but receives a zero-filled series. Public-only jobs, jobs shared directly with the caller, jobs shared through user groups or another organisation, owned-but-unshared jobs, jobs reachable only through a pending group membership and shares without read permission are not included.

Only top-level runs are counted; nested child runs are excluded. The response is a dense chronological series ending on the current UTC day and capped at the most recent 371 UTC calendar days. Days without matching runs are present with zero counts.

The default response is a plain-text table with flat columns. Send Accept: application/json to receive the same data as an array:

curl -H "Authorization: Bearer $NOVEM_TOKEN" \
  -H "Accept: application/json" \
  https://api.novem.io/v1/orgs/acme/profile/stats/activity
[
  {
    "day": "2026-08-17",
    "views": 0,
    "vdes_created": 0,
    "mails_sent": 0,
    "social": 0,
    "jobs": {
      "total": 3,
      "trigger": {
        "api": 1,
        "schedule": 1,
        "email": 1
      },
      "status": {
        "success": 2,
        "failed": 1
      }
    }
  }
]

jobs.total is the total number of included top-level runs for the day; jobs.trigger and jobs.status provide the corresponding trigger and outcome breakdowns. The views, vdes_created, mails_sent and social fields are currently always zero. They are retained so this endpoint has the same ActivityDay response shape as profile activity.

Visibility options

The profile/options folder holds boolean toggles (yes/no, default no), again founder/admin only:

OptionEffect
publicWhether people outside the group/org can find it and see its profile
show_profileShow the profile page (stored, not yet enforced)
show_descriptionShow the description on it (stored, not yet enforced)
show_membersShow the member list (stored, not yet enforced)
is_openLet users join without an invite (stored, not yet enforced)

Only public changes what anyone can see or do today. The other four are stored and returned by the GraphQL groups query, but nothing acts on them yet: setting show_members to no does not hide the member list, and setting is_open to yes does not let anyone join without an invite.

In the webapp, the Visibility switch on an organisation's, org group's or user group's Admin tab sets public. It is shown to the founders and admins who may write it, which for an org group includes the parent organisation's founders and admins. Going public shows the profile to everyone: name, summary, description, picture, banner and the creator's username. For an org group it also shows the parent organisation's name, even when the organisation itself is private, and the group's workflow email address if it receives workflow email. It does not publish the content shared with the group, and the member list stays visible only to people in it.

Organisations also have two nullable identity colours. These are small dashboard accents, separate from the organisation's full visualisation theme:

VerbPathDescription
GET / POST / DELETE/admin/orgs/:org/profile/options/primary_colorPrimary identity colour, used for organisation identity and aggregate activity
GET / POST / DELETE/admin/orgs/:org/profile/options/secondary_colorOptional secondary accent

POST takes a plain-text CSS hex colour in strict #RRGGBB form: a leading # followed by exactly six hexadecimal digits. A trailing editor line ending is removed; other surrounding whitespace is invalid. Hexadecimal letters may be upper- or lowercase and are preserved. Malformed values return 400 without replacing the stored colour. The management leaves are available on premium and enterprise plans; reading or writing them requires an accepted organisation founder or admin role.

DELETE idempotently resets the selected colour to null and returns an empty plain-text response. A GET on an unset colour returns an empty value; the organisation GraphQL fields and user_info.primary_org overview fields return null. When the primary colour is null, dashboard surfaces use the standard Novem colour. A null secondary colour means that no organisation-specific secondary accent is configured.

Note: for organisations and org groups the show_* options require a premium subscription. User-group options are available on all plans.

Groups and orgs also carry comment threads at .../threads/*, on the same paid-to-write, free-to-read terms as the rest of the platform.

Org themes (the branding applied to a whole organisation's content) are documented separately under org themes.

Browsing groups & orgs

The management endpoints above live under /admin. The read-oriented views are public (subject to the visibility options):

PathDescription
/v1/orgsOrganisations visible to you
/v1/orgs/:orgAn organisation — description and groups
/v1/orgs/:org/groupsThe org's groups — all of them for an org admin, otherwise those you belong to
/v1/orgs/:org/groups/:groupA group — name, description, profile, role (your role in it, empty until you hold one) and shared content
/v1/orgs/:org/profile/stats/activityDaily top-level runs for jobs shared readably through your child org groups
/v1/users/:user/groupsA user's groups visible to you
/v1/o/:orgThe org FQNP alias — card, banner, img, and the org's visuals under p / g / m / d / v