Roles, members and user groups

Invite your team, pick a base role for each person, build custom roles per module, group people and check what someone can do.

Embed
Preview of the card
<a href="https://hermeticor.com/guides/roles"><img src="https://hermeticor.com/guides/_api/public/orgs/5fcd8b3c-a27c-4688-972f-de710125592f/spaces/9a3da731-ded5-4536-b84f-8c9a61420ff4/pages/cbaa9aa2-8b17-44c9-987c-9a527ba652d1/social-card.svg?v=3e7ae33eec8b" alt="Roles, members and user groups" width="600" height="315"></a>

Each member of a workspace has a base role. A custom role starts from a base role and adds or removes scopes. A user group gives one custom role to many people.

What you need first

  • To invite people or change their base role: an owner or admin signed in to the web app.

  • For custom roles and groups through the API: a key with members:write (members:read to look only).

1. Invite people

Invites and base-role changes are made in the web app, under Settings → Members. With an API key those calls answer 403 and say a signed-in user is needed.

The base roles:

Role

Can do

owner, admin

Everything

marketer

Build and send campaigns, journeys, templates, forms and newsletters; read analytics and settings

sales

Prospects, sequences, contacts and sends; read segments, templates and analytics

analyst

Read everything and build reports and dashboards

viewer

Read only, without connections, integrations or settings

List members with GET /v1/members.

2. See the permission grid

curl -s "$BASE/v1/roles/matrix" -H "Authorization: Bearer $HERMETICA_API_KEY"

You get every base and custom role, with read and write per module.

3. Create a custom role

curl -s -X POST "$BASE/v1/roles" \
  -H "Authorization: Bearer $HERMETICA_API_KEY" -H "Content-Type: application/json" \
  -d '{"name":"GTM Operator","baseRole":"marketer","grant":["campaigns:approve"],"deny":["connections:read"]}'
# 201, with the role's effective scopes
  • baseRole cannot be owner.

  • You can only grant scopes you hold yourself. Anything else answers 403 "Cannot grant scope you lack".

  • A second role with the same name answers 409.

Tune it one module at a time:

curl -s -X PUT "$BASE/v1/roles/<roleId>/matrix" \
  -H "Authorization: Bearer $HERMETICA_API_KEY" -H "Content-Type: application/json" \
  -d '{"matrix":{"segments":{"read":true,"write":true}}}'

4. Give it to a person

curl -s -X PUT "$BASE/v1/members/<userId>/custom-role" \
  -H "Authorization: Bearer $HERMETICA_API_KEY" -H "Content-Type: application/json" \
  -d '{"roleId":"<roleId>"}'

Send {"roleId":null} to go back to the base role. Owners cannot take a custom role (412).

5. Or give it to a group

curl -s -X POST "$BASE/v1/user-groups" \
  -H "Authorization: Bearer $HERMETICA_API_KEY" -H "Content-Type: application/json" \
  -d '{"name":"GTM team","customRoleId":"<roleId>","userIds":["<userId>"]}'

Limit what the group sees with PUT /v1/user-groups/<groupId>/access. A role that a group still uses cannot be deleted (412 "Role is still used by a user group"); move the group first.

6. Check what someone can do

curl -s "$BASE/v1/members/by-email/maya@example.com/permissions" -H "Authorization: Bearer $HERMETICA_API_KEY"

This shows the effective scopes after base role, custom role and group.

See who changed what

Every role and member change is in the audit log:

curl -s "$BASE/v1/audit?targetType=custom_role&limit=50" -H "Authorization: Bearer $HERMETICA_API_KEY"

It needs audit:read. Filter with action (for example role.created) and from (an ISO time such as 2026-11-01T00:00:00Z), and continue with &cursor=<nextCursor>. GET /v1/audit/export?format=csv (or ndjson) exports it.

Next: Billing and plans.

Updated