Cactal Website editors API

Grant, list, and revoke website-scoped editor access, and invite collaborators to a single website by email.

Operations 5

GET /websites/{websiteId}/editor-invitations List website editor invitations #
GET /websites/{websiteId}/editors List website editors #
POST /websites/{websiteId}/editors Add a website editor by email #
DELETE /websites/{websiteId}/editors Remove a website editor or cancel an invitation #
PUT /websites/{websiteId}/editors/{principalId} Set a website editor’s role #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/cactal-ai:cactal-ai-website-editors-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

cactal-ai-website-editors-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: Cactal Ai Website editors API
  version: 1.0.0
  description: 'Operations tagged Website editors across 2 of this provider''s published API definitions: openapi.json, cactal-ai-openapi.json. Each path carries the servers of the definition it was published in.'
servers:
- url: https://api.cactal.ai/v1
security:
- apiKey: []
tags:
- name: Website editors
  description: Grant, list, and revoke website-scoped editor access, and invite collaborators to a single website by email.
paths:
  /websites/{websiteId}/editor-invitations:
    get:
      operationId: websites.editorInvitations.list
      summary: List website editor invitations
      description: Lists website editor invitations newest first with cursor pagination (default 20 per page, maximum 100). The default `status=pending` returns open invitations; use `accepted`, `canceled`, or `all` to inspect invitation history. Cancel a pending invitation with `websites.editors.remove` and its `invitationId`.
      tags:
      - Website editors
      parameters:
      - name: websiteId
        in: path
        required: true
        schema:
          type: string
          minLength: 1
      - name: status
        in: query
        required: false
        schema:
          default: pending
          type: string
          enum:
          - pending
          - accepted
          - canceled
          - all
      - name: cursor
        in: query
        required: false
        schema:
          type: string
      - name: limit
        in: query
        required: false
        schema:
          default: 20
          type: integer
          minimum: 1
          maximum: 100
      responses:
        '200':
          description: A page of website editor invitations.
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          type: string
                          description: Unique invitation id.
                        email:
                          type: string
                          description: Invited email address, normalized to lowercase.
                        role:
                          type: string
                          enum:
                          - full
                          - content
                          description: Editor role granted when the invitation is accepted.
                        status:
                          type: string
                          enum:
                          - pending
                          - accepted
                          - canceled
                          description: Lifecycle status of the invitation.
                        expiresAt:
                          description: When the invitation can no longer be accepted.
                          type: string
                          format: date-time
                        createdAt:
                          description: When the invitation was created.
                          type: string
                          format: date-time
                      required:
                      - id
                      - email
                      - role
                      - status
                      - expiresAt
                      - createdAt
                      additionalProperties: false
                  nextCursor:
                    description: Opaque cursor for the next page. Pass it as the `cursor` parameter on the next request. `null` when this is the last page.
                    type:
                    - string
                    - 'null'
                required:
                - items
                - nextCursor
                additionalProperties: false
        '400':
          description: Validation failed. The response `message` names the first invalid field.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ServiceError'
        '401':
          description: Missing, invalid, expired, or revoked API key.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ServiceError'
        '403':
          description: The authenticated principal lacks the required capability.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ServiceError'
        '404':
          description: The resource does not exist or is outside the principal’s access scope.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ServiceError'
        '429':
          description: Rate limit exceeded. Retry after the number of seconds in the `Retry-After` header.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ServiceError'
      x-cactal-required-capability: websites.editors.list
      x-cactal-read-only: true
      x-cactal-destructive: false
      x-cactal-idempotent: true
    servers:
    - url: https://api.cactal.ai/v1
  /websites/{websiteId}/editors:
    get:
      operationId: websites.editors.list
      summary: List website editors
      description: Returns the website’s direct user-account editor grants, newest first as a paginated set. API keys, organization members who inherit access, and email invitations are separate resources. List invitations with `websites.editorInvitations.list`, add editors with `websites.editors.add`, and revoke a grant with `websites.editors.remove`. Page size defaults to 20 (maximum 100).
      tags:
      - Website editors
      parameters:
      - name: websiteId
        in: path
        required: true
        schema:
          type: string
          minLength: 1
      - name: cursor
        in: query
        required: false
        schema:
          type: string
      - name: limit
        in: query
        required: false
        schema:
          default: 20
          type: integer
          minimum: 1
          maximum: 100
      responses:
        '200':
          description: One page of the website’s direct editor grants.
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      type: object
                      properties:
                        principalId:
                          type: string
                          description: Id of the principal holding the grant.
                        role:
                          type: string
                          enum:
                          - full
                          - content
                          description: '`full` allows full website editing; `content` allows content editing only.'
                        createdAt:
                          description: When the grant was created.
                          type: string
                          format: date-time
                        name:
                          type: string
                          description: Account display name.
                        email:
                          type: string
                          description: Account email address.
                      required:
                      - principalId
                      - role
                      - createdAt
                      - name
                      - email
                      additionalProperties: false
                  nextCursor:
                    description: Opaque cursor for the next page. Pass it as the `cursor` parameter on the next request. `null` when this is the last page.
                    type:
                    - string
                    - 'null'
                required:
                - items
                - nextCursor
                additionalProperties: false
        '400':
          description: Validation failed. The response `message` names the first invalid field.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ServiceError'
        '401':
          description: Missing, invalid, expired, or revoked API key.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ServiceError'
        '403':
          description: The authenticated principal lacks the required capability.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ServiceError'
        '404':
          description: The resource does not exist or is outside the principal’s access scope.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ServiceError'
        '429':
          description: Rate limit exceeded. Retry after the number of seconds in the `Retry-After` header.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ServiceError'
      x-cactal-required-capability: websites.editors.list
      x-cactal-read-only: true
      x-cactal-destructive: false
      x-cactal-idempotent: true
    post:
      operationId: websites.editors.add
      summary: Add a website editor by email
      description: 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`.
      tags:
      - Website editors
      parameters:
      - name: websiteId
        in: path
        required: true
        schema:
          type: string
          minLength: 1
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                email:
                  type: string
                  format: email
                  pattern: ^(?:[A-Za-z0-9_'+\-]+\.)*[A-Za-z0-9_'+\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\-]*\.)+[A-Za-z]{2,}$
                role:
                  type: string
                  enum:
                  - full
                  - content
                expiresAt:
                  anyOf:
                  - {}
                  - type: string
                    format: date-time
                    pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:\.\d+)?(?:Z))$
                callbackUrl:
                  type: string
                  format: uri
              required:
              - email
              - role
      responses:
        '200':
          description: The immediate grant, the already-covered principal, or the pending invitation.
          content:
            application/json:
              schema:
                oneOf:
                - type: object
                  properties:
                    status:
                      type: string
                      const: granted
                      description: The email belongs to an existing account; the editor grant was created immediately.
                    grant:
                      type: object
                      properties:
                        websiteId:
                          type: string
                          description: Id of the website the grant applies to.
                        principalId:
                          type: string
                          description: Id of the principal holding the grant.
                        role:
                          type: string
                          enum:
                          - full
                          - content
                          description: '`full` allows full website editing; `content` allows content editing only.'
                        createdAt:
                          description: When the grant was created.
                          type: string
                          format: date-time
                      required:
                      - websiteId
                      - principalId
                      - role
                      - createdAt
                      additionalProperties: false
                  required:
                  - status
                  - grant
                  additionalProperties: false
                - type: object
                  properties:
                    status:
                      type: string
                      const: already_inherited
                      description: The account already inherits website access through its organization role; nothing changed.
                    principalId:
                      type: string
                      description: Id of the principal that already has access.
                  required:
                  - status
                  - principalId
                  additionalProperties: false
                - type: object
                  properties:
                    status:
                      type: string
                      const: pending
                      description: No account exists for the email; a pending invitation was created and emailed.
                    invitation:
                      type: object
                      properties:
                        id:
                          type: string
                          description: Unique invitation id.
                        email:
                          type: string
                          description: Invited email address, normalized to lowercase.
                        role:
                          type: string
                          enum:
                          - full
                          - content
                          description: Editor role granted when the invitation is accepted.
                        status:
                          type: string
                          enum:
                          - pending
                          - accepted
                          - canceled
                          description: Lifecycle status of the invitation.
                        expiresAt:
                          description: When the invitation can no longer be accepted.
                          type: string
                          format: date-time
                        createdAt:
                          description: When the invitation was created.
                          type: string
                          format: date-time
                      required:
                      - id
                      - email
                      - role
                      - status
                      - expiresAt
                      - createdAt
                      additionalProperties: false
                  required:
                  - status
                  - invitation
                  additionalProperties: false
        '400':
          description: Validation failed. The response `message` names the first invalid field.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ServiceError'
        '401':
          description: Missing, invalid, expired, or revoked API key.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ServiceError'
        '403':
          description: The authenticated principal lacks the required capability.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ServiceError'
        '404':
          description: The resource does not exist or is outside the principal’s access scope.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ServiceError'
        '429':
          description: Rate limit exceeded. Retry after the number of seconds in the `Retry-After` header.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ServiceError'
      x-cactal-required-capability: websites.editors.add
      x-cactal-read-only: false
      x-cactal-destructive: false
      x-cactal-idempotent: false
    delete:
      operationId: websites.editors.remove
      summary: Remove a website editor or cancel an invitation
      description: Revokes a website-scoped editor grant when called with `principalId`, or cancels a pending invitation (so its emailed link stops working) when called with `invitationId` — provide exactly one. Returns 404 when the principal has no direct grant or the invitation does not exist; canceling an invitation that was already accepted or canceled returns 409. Access inherited from an organization role is unaffected. Grants are listed by `websites.editors.list`; invitations are listed by `websites.editorInvitations.list`.
      tags:
      - Website editors
      parameters:
      - name: websiteId
        in: path
        required: true
        schema:
          type: string
          minLength: 1
      requestBody:
        required: false
        content:
          application/json:
            schema:
              type: object
              properties:
                principalId:
                  description: Principal whose direct editor grant should be revoked. Provide either this or `invitationId`.
                  type: string
                  minLength: 1
                invitationId:
                  description: Pending invitation to cancel so its emailed link stops working. Provide either this or `principalId`.
                  type: string
                  minLength: 1
      responses:
        '200':
          description: The removed editor grant or the canceled invitation.
          content:
            application/json:
              schema:
                oneOf:
                - type: object
                  properties:
                    status:
                      type: string
                      const: removed
                      description: The principal’s direct editor grant was revoked.
                    grant:
                      type: object
                      properties:
                        websiteId:
                          type: string
                          description: Id of the website the grant applies to.
                        principalId:
                          type: string
                          description: Id of the principal holding the grant.
                        role:
                          type: string
                          enum:
                          - full
                          - content
                          description: '`full` allows full website editing; `content` allows content editing only.'
                        createdAt:
                          description: When the grant was created.
                          type: string
                          format: date-time
                      required:
                      - websiteId
                      - principalId
                      - role
                      - createdAt
                      additionalProperties: false
                  required:
                  - status
                  - grant
                  additionalProperties: false
                - type: object
                  properties:
                    status:
                      type: string
                      const: canceled
                      description: The pending invitation was canceled; its emailed link no longer works.
                    invitation:
                      type: object
                      properties:
                        id:
                          type: string
                          description: Unique invitation id.
                        email:
                          type: string
                          description: Invited email address, normalized to lowercase.
                        role:
                          type: string
                          enum:
                          - full
                          - content
                          description: Editor role granted when the invitation is accepted.
                        status:
                          type: string
                          enum:
                          - pending
                          - accepted
                          - canceled
                          description: Lifecycle status of the invitation.
                        expiresAt:
                          description: When the invitation can no longer be accepted.
                          type: string
                          format: date-time
                        createdAt:
                          description: When the invitation was created.
                          type: string
                          format: date-time
                      required:
                      - id
                      - email
                      - role
                      - status
                      - expiresAt
                      - createdAt
                      additionalProperties: false
                  required:
                  - status
                  - invitation
                  additionalProperties: false
        '400':
          description: Validation failed. The response `message` names the first invalid field.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ServiceError'
        '401':
          description: Missing, invalid, expired, or revoked API key.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ServiceError'
        '403':
          description: The authenticated principal lacks the required capability.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ServiceError'
        '404':
          description: The resource does not exist or is outside the principal’s access scope.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ServiceError'
        '409':
          description: The request conflicts with the current state of the resource.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ServiceError'
        '429':
          description: Rate limit exceeded. Retry after the number of seconds in the `Retry-After` header.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ServiceError'
      x-cactal-required-capability: websites.editors.remove
      x-cactal-read-only: false
      x-cactal-destructive: true
      x-cactal-idempotent: false
    servers:
    - url: https://api.cactal.ai/v1
  /websites/{websiteId}/editors/{principalId}:
    put:
      operationId: websites.editors.setRole
      summary: Set a website editor’s role
      description: Sets the principal’s editor role on this single website, replacing any existing grant for that principal. `role` is `full` (full website editing) or `content` (content editing only). Principals who already inherit access through their organization role are rejected with a validation error. Use `websites.editors.add` to add someone by email instead of principal id.
      tags:
      - Website editors
      parameters:
      - name: websiteId
        in: path
        required: true
        schema:
          type: string
          minLength: 1
      - name: principalId
        in: path
        required: true
        schema:
          type: string
          minLength: 1
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                role:
                  type: string
                  enum:
                  - full
                  - content
              required:
              - role
      responses:
        '200':
          description: The saved editor grant.
          content:
            application/json:
              schema:
                type: object
                properties:
                  websiteId:
                    type: string
                    description: Id of the website the grant applies to.
                  principalId:
                    type: string
                    description: Id of the principal holding the grant.
                  role:
                    type: string
                    enum:
                    - full
                    - content
                    description: '`full` allows full website editing; `content` allows content editing only.'
                  createdAt:
                    description: When the grant was created.
                    type: string
                    format: date-time
                required:
                - websiteId
                - principalId
                - role
                - createdAt
                additionalProperties: false
        '400':
          description: Validation failed. The response `message` names the first invalid field.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ServiceError'
        '401':
          description: Missing, invalid, expired, or revoked API key.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ServiceError'
        '403':
          description: The authenticated principal lacks the required capability.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ServiceError'
        '404':
          description: The resource does not exist or is outside the principal’s access scope.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ServiceError'
        '429':
          description: Rate limit exceeded. Retry after the number of seconds in the `Retry-After` header.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ServiceError'
      x-cactal-required-capability: websites.editors.setRole
      x-cactal-read-only: false
      x-cactal-destructive: true
      x-cactal-idempotent: false
    servers:
    - url: https://api.cactal.ai/v1
components:
  schemas:
    ServiceError:
      type: object
      required:
      - kind
      - message
      description: Canonical error body returned by every non-2xx response. Extra fields carry error-specific details.
      properties:
        kind:
          type: string
          enum:
          - validation
          - unauthorized
          - forbidden
          - not_found
          - conflict
          - rate_limited
          - internal
          description: Stable, machine-readable error category.
        message:
          type: string
          description: Human-readable explanation of the failure.
        suggestion:
          type: string
          description: What to do next when the failure has a known fix; may name the exact operation to call.
        validValues:
          type: array
          items:
            type: string
          description: The acceptable values for the failing field, when the set is closed.
      additionalProperties: true
  securitySchemes:
    apiKey:
      type: http
      scheme: bearer
      description: Cactal API key. Create one in the dashboard or via `POST /apiKeys`. The plaintext key is shown once at creation.
x-refined-from:
- openapi.json
- cactal-ai-openapi.json