---
title: "Roles and access"
description: "The four workspace roles, what each is for, and where access is decided in the product."
updated: "2026-08-29"
verifiedAgainst:
  - packages/shared/src/index.ts
  - firestore.rules
  - packages/shared/src/free-grant.ts
  - apps/web/lib/server/acquisition-runtime-control.ts
  - apps/web/lib/server/workspace-invitation-service.ts
  - apps/web/lib/server/workspace-invitation-contract.ts
  - apps/web/lib/server/workspace-invitation-resend-mailer.ts
  - apps/web/lib/server/acquisition-benefit-exclusion.ts
---

Membership of a workspace carries one of four roles.

| Role     | Intended for                                          |
| -------- | ----------------------------------------------------- |
| `owner`  | The person who owns the account and its billing       |
| `admin`  | Someone trusted with settings and spending            |
| `editor` | Someone who works on content                          |
| `viewer` | Someone who needs to see the work without changing it |

## What the roles separate

The important boundary is spending. Actions that cost money or change what the
workspace is billed are restricted to the owner and admin roles. Editorial work
is available to editors.

<Callout variant="warning" title="Roles are held at workspace level">
  A role applies across every Project in the workspace. There is no per Project role today, so an
  editor added for one Project can work on all of them.
</Callout>

## Adding people

Owners and admins invite people from **Settings → Workspace → Team members**.
Choose the person's workspace role before sending. The email link lasts seven
days, works once, and must be accepted while signed in with the address that
received it. Pending invitations can be resent, renewed with a new secure link,
have their role changed, or be revoked from the same screen.

Seats are unlimited on every paid plan. Inviting a teammate does not change
billing, but their role applies to every current and future Project in the
workspace. Owners cannot be removed or demoted from team settings, and a member
cannot change their own role there.

<Callout variant="note" title="Sending an invitation needs a workspace subscription">
  Seats are uncapped, but sending is gated on the workspace holding a
  subscription in an allowed status. A workspace whose only Project is on the
  Free grant has no subscription document at all, so the invite is refused with
  "A paid subscription is required to send team invitations." Putting any Project
  in the workspace on a paid plan is what opens it. A workspace on the trial can
  invite, because checkout writes a real trialing subscription.
</Callout>

## What an invitation can refuse

Sending is checked in a fixed order, and each refusal names its own cause rather
than failing generically.

<PropertyList>
  <Property name="Your own email is not verified">
    You cannot invite anyone until your address is verified. Verify it and send
    again.
  </Property>
  <Property name="The workspace has no paid subscription">
    The gate described above. Put a Project on a paid plan.
  </Property>
  <Property name="Your sign in is stale">
    If the address on your account changed since you signed in, sign in again
    before sending.
  </Property>
  <Property name="The account is disabled">
    A disabled account cannot send invitations at all. Contact support.
  </Property>
</PropertyList>

There are also daily caps, which exist to stop a mailbox being used as a delivery
channel: 100 invitations per workspace per day, 100 per sender per day, and 5 to
any single recipient per day across all of Blogged. Resending the same invitation
has a 60 second cooldown, which is separate from the caps and clears on its own.

Invitations are sent from `invites.blogged.dev`, a dedicated sending domain that
is not the one billing email comes from. If a teammate cannot find the message,
that is the domain to search for and to allow.

<Callout variant="danger" title="Accepting an invitation first costs the new member their own Free grant">
  If someone's very first action in Blogged is accepting your invitation, their
  account is permanently recorded as having arrived through one, and it is issued
  no signup benefit of its own. Not then, and not if they later create their own
  workspace.

  This is not reversible, so it is worth saying to anyone you invite who might
  also want their own Blogged account: sign up separately first, then accept. An
  account that already holds a grant keeps it, so the order is the only thing that
  matters. See [the Free grant](/billing/free-grant).
</Callout>

If you need a boundary the current roles do not express, say so at
[hello@blogged.dev](mailto:hello@blogged.dev) rather than working around it with
a second workspace, which would split your billing and your content.

See the [roles reference](/reference/roles) for the table in one place.
