---
title: "Add a website editor by email"
method: POST
path: "/websites/{websiteId}/editors"
tags: ["Website editors"]
---

# Add a website editor by email

`POST /websites/{websiteId}/editors`

## Request

- Base URL: `https://api.cactal.ai/v1`
- URL: `https://api.cactal.ai/v1/websites/{websiteId}/editors`
- Auth: HTTP bearer

Gives an email address `full` or `content` editor access to this single website. When the email already belongs to an account, the grant is created immediately (`granted`) — or nothing changes if that account already inherits access through its organization role (`already_inherited`). Otherwise a `pending` invitation is created and emailed; it expires after 48 hours unless you set `expiresAt`. Re-adding an email with a pending invitation refreshes that invitation instead of creating a duplicate. Change an existing editor’s role with `websites.editors.setRole`.

## Path parameters

- `websiteId` string, required

## Request body

- object
  - `email` string, email, required
  - `role` 'full' | 'content', required
  - `expiresAt` union
    - unknown
    - string, date-time
  - `callbackUrl` string, uri

## Response `200`

The immediate grant, the already-covered principal, or the pending invitation.

- union
  - object
    - `status` 'granted', required: The email belongs to an existing account; the editor grant was created immediately.
    - `grant` object, required
      - `websiteId` string, required: Id of the website the grant applies to.
      - `principalId` string, required: Id of the principal holding the grant.
      - `role` 'full' | 'content', required: `full` allows full website editing; `content` allows content editing only.
      - `createdAt` string, date-time, required: When the grant was created.
  - object
    - `status` 'already_inherited', required: The account already inherits website access through its organization role; nothing changed.
    - `principalId` string, required: Id of the principal that already has access.
  - object
    - `status` 'pending', required: No account exists for the email; a pending invitation was created and emailed.
    - `invitation` object, required
      - `id` string, required: Unique invitation id.
      - `email` string, required: Invited email address, normalized to lowercase.
      - `role` 'full' | 'content', required: Editor role granted when the invitation is accepted.
      - `status` 'pending' | 'accepted' | 'canceled', required: Lifecycle status of the invitation.
      - `expiresAt` string, date-time, required: When the invitation can no longer be accepted.
      - `createdAt` string, date-time, required: When the invitation was created.

## Other responses

- `400`: Validation failed. The response `message` names the first invalid field.
- `401`: Missing, invalid, expired, or revoked API key.
- `403`: The authenticated principal lacks the required capability.
- `404`: The resource does not exist or is outside the principal’s access scope.
- `429`: Rate limit exceeded. Retry after the number of seconds in the `Retry-After` header.

---

[API](https://skmtc.dev/cactal/apis/cactal-api.md) · [All operations](https://skmtc.dev/cactal/apis/cactal-api/llms.txt) · [OpenAPI document](https://skmtc.dev/cactal/apis/cactal-api/revisions/9cd0fb5eacdd?raw)
