Cactal Website editors API
Grant, list, and revoke website-scoped editor access, and invite collaborators to a single website by email.
Grant, list, and revoke website-scoped editor access, and invite collaborators to a single website by email.
Every API here is available over the APIs.io API and to AI agents over MCP.
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
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.curl "https://apis.io/api/v1/apis/cactal-ai:cactal-ai-website-editors-api"
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.
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: 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