Enterprise APIs and Governance
|
This content was generated with the assistance of AI and should be verified against the official Webflow documentation before being relied on in production. This sub-section’s Webflow bibliography lists the reference material consulted while preparing these pages. |
This page describes the Webflow Enterprise API surface and the governance features around it as they were on 2026-10-28,
the date on which its facts were checked against the Data API reference on developers.webflow.com (authentication,
scopes, rate limits, workspace tokens and every endpoint in the Enterprise reference section). The pinned developer
packages are webflow-api 3.3.4 for JavaScript and TypeScript and webflow 2.0.0 for Python. Every endpoint in
the sections below requires an Enterprise workspace; plans are named by tier only, never by price, and a plan
change by Webflow can move an endpoint between tiers, so the reference page of an endpoint is the authority for its
current requirement. The examples on this page are written to be run by an organisation that has an Enterprise workspace and are shown with
placeholder identifiers and tokens only; the Developer workspace is the free place to rehearse the plan-neutral parts of
the Data API.
The running example is Fernbrook Gardens, a fictitious botanical garden. For most of this sub-section it is a small team with one site. Imagine now that it has grown into a federation: the garden itself, a sister arboretum and a seed-exchange charity, each with its own Webflow site, a central web team, volunteers who edit content, and a trustee board that asks, once a year, who had access to what. That is the situation in which the Enterprise APIs matter.
What "Enterprise" adds for developers
Most of the Data API is plan-neutral: Collections, items, pages, assets, forms, webhooks and the site publish endpoint work for any site that a token can reach (see Data API: Authentication and Scopes and Data API: SDKs, Limits and Errors). Enterprise adds four kinds of capability, each with its own section of the reference:
-
Workspace-level administration: list the Workspaces a token can see, create, rename and delete Sites, read a site’s hosting plan.
-
People and access: list, invite, re-role and remove Workspace members, and grant or revoke access to a single Site, including custom Site roles.
-
Site configuration: manage 301 redirects, the
robots.txtrules and the files served under/.well-known/. -
Observability and audit: read the Workspace audit log (who logged in, who was added or removed, which role changed) and the Site Activity log (what changed on a Site, by whom or by which agent).
A fifth, smaller piece is the workspace token, a token type that exists only for Enterprise Workspaces and that is the normal credential for the audit log.
Credentials and scopes
The Enterprise endpoints use the same bearer-token scheme as the rest of the Data API, with a few extra scopes and one extra token type. The authoritative lists are the Scopes reference and the Workspace Token page.
Workspace tokens
A workspace token is an API token that grants access to Workspace-level resources, such as the audit log. It is
meant for Workspace administrators. Site data is reached with a site token instead; a workspace token has no site
scope and therefore cannot call a Site endpoint such as Get Site Information.
The rules documented for workspace tokens are:
-
They exist only for Enterprise Workspaces, and only Workspace administrators can create them.
-
A Workspace can have up to five of them.
-
A token expires after 365 consecutive days without use; any API call resets the countdown.
-
A token cannot be regenerated. If its value is lost, create a new token and update every integration that used the old one.
-
The only workspace-token scope in the documentation is
workspace_activity:read, which grants the audit log endpoint. The documentation also listsworkspace:read(for List Workspaces) among the scopes supported by workspace tokens.
Creating a token is a Dashboard task. In the Workspace, open Apps & integrations, choose Manage, scroll to Workspace API access, and use Generate API token. Name it, set the permission of each scope (for example no access or read-only), generate it and copy the value once into a secrets manager.
Fernbrook’s security practice follows the guidance of the same page: one token per use case (the SIEM forwarder has its own token, separate from the quarterly access-review script), descriptive names, the minimum scope, periodic rotation, and immediate revocation when an administrator leaves or changes role.
Source: Data API: Workspace Token
The scopes that matter
The Scopes reference lists the following scopes for the endpoints on this page. The "Supported by" column is from the reference; a scope that a token type does not support cannot be granted to it.
| Scope | Level | Covers and supported by |
|---|---|---|
|
Workspace |
List Workspaces. Workspace API tokens and Data Client apps registered with workspace-level access. New site tokens cannot have this scope. |
|
Workspace |
The Workspace audit log. Workspace API tokens and Data Client apps registered with workspace-level access. |
|
Site |
Create Site. Data Client apps and site tokens. |
|
Workspace |
List, invite, re-role and remove Workspace members (named in the endpoint pages). |
|
Site |
List and change the members of one Site (named in the endpoint pages). |
|
Site |
The Site Activity log. Data Client apps and site tokens. |
|
Site |
Site Configuration endpoints; |
|
Site |
Sites endpoints. |
|
Site |
The page-branching endpoints. |
|
Site |
Site plan endpoints. |
There is no scope named "enterprise"; the plan check happens on the workspace, and a call from a token whose workspace
is not Enterprise fails with an error rather than with a missing scope. A call that lacks a scope fails with a 403
whose code is missing_scopes, so the two causes are distinguishable in logs.
Source: Data API: Scopes
Rate limits and retries
Rate limits are per API key and are published per plan tier: 60 requests per minute for Starter and Basic, 120 for CMS,
Ecommerce and Business, and custom limits for Enterprise. Every response carries X-RateLimit-Limit and
X-RateLimit-Remaining; a response with status 429 carries Retry-After, typically 60 seconds. The official SDKs retry
429s automatically with exponential backoff; code that calls the REST endpoints directly must honour Retry-After.
Because Enterprise limits are negotiated, an audit-log forwarder should read X-RateLimit-Remaining rather than
hard-code a number. The Site publish endpoint has its own limit of one successful publish per minute.
Source: Data API: Rate Limits
Listing Workspaces and finding the identifier
Most Workspace endpoints take a workspace_id in the path. GET /v2/workspaces lists the active Workspaces a token
can reach, with each id, name and slug; archived, deleted and draft Workspaces are excluded and the list is not
paginated. It needs workspace:read, and it works with Workspace API tokens and with Data Client apps. The audit log
endpoint accepts either the ID or the slug.
curl --request GET \
--url https://api.webflow.com/v2/workspaces \
--header 'accept: application/json' \
--header "authorization: Bearer $WEBFLOW_WORKSPACE_TOKEN"
Source: Data API: List Workspaces
Site lifecycle: create, update, delete and plan
Four endpoints manage Sites from outside the Dashboard. They let a central team provision a site for each new programme from a template, rename and file it, and retire it.
| Operation | Request | Scope | Notes |
|---|---|---|---|
Create Site |
|
|
Body: |
Update Site |
|
|
Body fields |
Delete Site |
|
|
Returns 204 with no body. |
Get Site Plan |
|
|
Returns the hosting plan’s |
The response of Create Site includes dataCollectionEnabled and dataCollectionType (always, optOut or
disabled), which mirror the site’s privacy settings, so a provisioning script can verify that a new site starts with
the setting the organisation’s policy requires and fix it before anything is published.
Fernbrook’s provisioning script creates the sister arboretum’s site from the garden’s template, so that the design system described in Building a Design System starts in place:
// provision-site.ts (run by an Enterprise administrator's automation)
const workspaceId = process.env.WEBFLOW_WORKSPACE_ID!;
const token = process.env.WEBFLOW_API_TOKEN!;
const response = await fetch(
`https://api.webflow.com/v2/workspaces/${workspaceId}/sites`,
{
method: "POST",
headers: {
authorization: `Bearer ${token}`,
"content-type": "application/json",
accept: "application/json",
},
body: JSON.stringify({
name: "Fernbrook Arboretum",
templateName: "fernbrook-base-template",
}),
},
);
if (!response.ok) {
throw new Error(`Create Site failed: ${response.status} ${await response.text()}`);
}
const site = await response.json();
console.log(site.id, site.shortName, site.timeZone);
Source: Data API: Create Site
Deleting a Site is a destructive and immediate operation. Treat it like a database drop: restrict sites:write to a
dedicated token, require a second human approval in the pipeline that calls it, and take a backup first (see
Backups and Recovery).
Source: Data API: Delete Site
Site configuration endpoints
The Site configuration endpoints are the API form of settings that a site owner normally edits in Site settings. They matter at Enterprise scale because a federation of sites needs the same baseline everywhere, and a script can apply it and detect drift.
301 redirects
Redirects send a retired path to its replacement (see Redirects and Site Migration for the Dashboard side). The API manages the 301 rules of one site:
| Operation | Request | Scope |
|---|---|---|
List |
|
|
Create |
|
|
Update |
|
|
Delete |
Delete 301 redirects endpoint |
|
A rule has an id, a fromUrl (the source path) and a toUrl (the destination path). The list response returns the
rules under redirects with a pagination object of limit, offset and total. A create request carries one rule
at a time; there is no documented bulk create, so a migration of hundreds of old addresses is a loop that respects the
rate limit.
Fernbrook retired the old site’s /gardens section in favour of the Zones collection. The migration script
reads the old paths from a CSV file and creates one rule for each:
// create-redirects.ts
import { readFileSync } from "node:fs";
const siteId = process.env.WEBFLOW_SITE_ID!;
const token = process.env.WEBFLOW_API_TOKEN!;
const pairs = readFileSync("old-to-new.csv", "utf8")
.trim()
.split("\n")
.slice(1) // skip the header row
.map((line) => line.split(","));
for (const [fromUrl, toUrl] of pairs) {
const response = await fetch(`https://api.webflow.com/v2/sites/${siteId}/redirects`, {
method: "POST",
headers: { authorization: `Bearer ${token}`, "content-type": "application/json" },
body: JSON.stringify({ fromUrl, toUrl }),
});
if (response.status === 429) {
const wait = Number(response.headers.get("retry-after") ?? "60");
await new Promise((resolve) => setTimeout(resolve, wait * 1000));
pairs.push([fromUrl, toUrl]); // retry later
continue;
}
if (!response.ok) {
console.error(`Failed ${fromUrl}: ${response.status}`);
}
}
Source: Data API: Create a 301 redirect
The remaining operations are documented on their own pages: Get 301 redirects, Update 301 redirect and Delete 301 redirects. Redirect paths are site-relative; remember that a redirect that points at a path which is itself redirected creates a chain that search engines may follow only partly.
robots.txt
The robots.txt endpoints read and write the structured rules that Webflow renders into /robots.txt. Each rule names a
userAgent and lists allows and disallows; a separate sitemap field holds the sitemap URL.
| Operation | Request | Scope |
|---|---|---|
Get |
|
|
Replace |
|
|
Update |
|
|
Delete |
|
|
The Replace page documents PUT as replacing the stored configuration with the body, which is the safe choice for a
baseline that must be identical on every site. Fernbrook keeps one baseline for its federation: crawlers may read
everything except the volunteers area, and the sitemap points to the site’s own domain.
{
"rules": [
{
"userAgent": "*",
"allows": ["/"],
"disallows": ["/volunteers"]
},
{
"userAgent": "GPTBot",
"disallows": ["/volunteers", "/staff-only"]
}
],
"sitemap": "https://www.fernbrook.example/sitemap.xml"
}
Source: Data API: Replace robots.txt
curl --request PUT \
--url "https://api.webflow.com/v2/sites/$WEBFLOW_SITE_ID/robots_txt" \
--header "authorization: Bearer $WEBFLOW_API_TOKEN" \
--header 'content-type: application/json' \
--data @robots-baseline.json
Source: Data API: Update robots.txt
A robots.txt file is advice to well-behaved crawlers, not access control. The volunteers area is protected by
password protection (see Password Protection and Site Search),
and listing a path under disallows also tells everyone who reads the file that the path exists. The Dashboard side of
the same setting is described in the Help Center article
Set robots.txt rules.
Well-known files
The well-known endpoint publishes small files under /.well-known/ on the site’s domain. Typical uses are
security.txt for vulnerability reports, apple-app-site-association and assetlinks.json for app links, and
domain-verification files requested by third-party services.
| Operation | Request | Scope |
|---|---|---|
Set a file |
|
|
Delete files |
|
|
The body of the set operation has fileName, fileData and an optional contentType of application/json
(the default) or text/plain. The documented limits are that each file must be under 100 KB and that a site holds
fewer than 30 well-known files. File names may end in .txt or .json, or have no extension. Because some upload
tools cannot send an extensionless name, the special .noext marker is stripped when the file is saved:
apple-app-site-association.noext.txt is served as apple-app-site-association. A successful set returns 201 and a
successful delete returns 204; the delete body names the files in a fileNames list.
// set-security-txt.ts
const siteId = process.env.WEBFLOW_SITE_ID!;
const token = process.env.WEBFLOW_API_TOKEN!;
const securityTxt = [
"Contact: mailto:security@fernbrook.example",
"Expires: 2027-10-28T00:00:00Z",
"Preferred-Languages: en, es, de",
].join("\n");
const response = await fetch(`https://api.webflow.com/v2/sites/${siteId}/well_known`, {
method: "PUT",
headers: { authorization: `Bearer ${token}`, "content-type": "application/json" },
body: JSON.stringify({
fileName: "security.txt",
fileData: securityTxt,
contentType: "text/plain",
}),
});
console.log(response.status); // 201 on success
Source: Data API: Set a well-known file
The delete operation is documented at Data API: Delete a well-known file. Publish the site to make a change visible; the Data API publish endpoint is covered in Data API: Sites, Pages and Components.
People and access
The access endpoints are the API form of the Workspace and Site member screens. Used well, they replace a quarterly spreadsheet of "who can do what" with a script that reads the truth.
Workspace members
| Operation | Request | Scope |
|---|---|---|
List members and invites |
|
|
Invite a member |
|
|
Update a member’s role |
Update Workspace Member Role endpoint |
|
Remove a member |
Remove Workspace Member endpoint |
|
Bulk update roles |
|
|
Bulk remove members |
Bulk Remove Workspace Members endpoint |
|
The list endpoint returns both members and invites (pending, declined and expired) and filters by email and by
roles; its default page size is 50 with a maximum of 100, and paging uses the nextCursor of the previous response.
The limit is applied to the two lists separately. A member has a workspace role (owner, admin, member,
guest, reviewer or client) and, for Workspaces on Workspace seats, a default Site role.
An invite is one of three shapes: a default Site role invite (the person gets one Site role across the Workspace’s
sites), a Site access invite (a list of sites, all with the same Site role) and a collaborator client invite (one
site only). Role pairings follow the Dashboard’s role picker: an admin workspace role pairs with the site_manager
default role, a member pairs with site_manager, designer, marketer, content_editor or custom, and a
reviewer pairs with reviewer. The error codes include insufficient_seats, user_limit_reached and
member_already_has_access, which a script should treat as expected, recoverable outcomes.
// invite-editor.ts
const workspaceId = process.env.WEBFLOW_WORKSPACE_ID!;
const token = process.env.WEBFLOW_API_TOKEN!;
const response = await fetch(
`https://api.webflow.com/v2/workspaces/${workspaceId}/members`,
{
method: "POST",
headers: { authorization: `Bearer ${token}`, "content-type": "application/json" },
body: JSON.stringify({
email: "new.volunteer@example.org",
workspaceRole: "member",
defaultSiteRole: "content_editor",
}),
},
);
const result = await response.json();
console.log(response.status, result.status); // "invited" or "active"
The bulk role endpoint takes a role, a defaultSiteRole and lists of memberIds and inviteIds. It returns 200 as
soon as the batch has been applied, even if every item failed, so read summary (updated and failed) and the
per-item results; results are de-duplicated, so match them to the input by id, not by position. One failure code,
workspace_member_managed_by_scim, shows that members whose lifecycle is controlled by SCIM cannot be changed by hand
or by this API.
Site access
Site access narrows or widens one member’s rights on one Site.
| Operation | Request | Scope |
|---|---|---|
List Site members |
|
|
Grant access |
|
|
Change a Site role |
Update Site Member Role, by member ID or by email |
|
Revoke access |
Revoke Site Access, by member ID or by email |
|
The grant endpoint creates new access and never modifies an existing grant: if the member already has access it fails
with a 409 whose code is member_already_has_access, and the way to change a role is the update endpoint. The body has
a required siteRole (site_manager, designer, marketer, content_editor, reviewer or custom), either an
email or a memberId, and a siteRoleId that is required when the role is custom and rejected otherwise. In
responses a Site role can also be branch_designer, limited_designer or viewer.
curl --request POST \
--url "https://api.webflow.com/v2/sites/$WEBFLOW_SITE_ID/members" \
--header "authorization: Bearer $WEBFLOW_API_TOKEN" \
--header 'content-type: application/json' \
--data '{"email": "journal.editor@example.org", "siteRole": "content_editor"}'
Source: Data API: Grant Site Access
The list endpoint pages with limit (default 50, maximum 100), email and cursor, and is the building block of an
access review:
Data API: List Site Members.
Audit trails
Webflow keeps two different logs, aimed at two different questions. Do not confuse them.
| Log | Question it answers | Endpoint and scope |
|---|---|---|
Workspace audit log |
Who signed in, who was added, removed or re-roled, which custom role changed, which Workspace setting was toggled? |
|
Site Activity log |
What changed on this Site: CMS items, pages, publishes, branches; by which person, agent or system? |
|
The Site Activity log is also a Dashboard panel and exists in lighter form outside Enterprise; the panel and its history are described in Collaboration, Comments and the Activity Log. The API is the Enterprise part.
Workspace audit log
The request takes a limit (at most 100), an offset, a sortOrder (asc or desc), a from and a to
(ISO 8601 timestamps) and an eventType filter. The response has an items array and a pagination object with
limit, offset and total. Every event has an eventType, an eventSubType, a payload and an actor that is
either a person (with an email) or a token (with a name), so an action taken by an API token is attributable to that
token.
eventType |
eventSubType values |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
The payload depends on the type. For user_access it records the sign-in method (dashboard, sso, api or
google), a coarse location and the ipAddress. Membership and invitation payloads carry the targetUser, the
userType (member, guest, reviewer or client), the new roleName and the previousRoleName, and a method
whose values include sso and scim as well as dashboard, admin, invite, access_request and api. That
method is how a reviewer tells a person added by a SCIM sync from one added by a Workspace admin in the Dashboard.
A trimmed example of what a membership event looks like, with placeholder values:
{
"eventType": "workspace_membership",
"eventSubType": "user_role_updated",
"actor": { "type": "person", "id": "user_placeholder_1", "email": "admin@example.org" },
"payload": {
"targetUser": { "id": "user_placeholder_2", "email": "volunteer@example.org" },
"method": "dashboard",
"userType": "member",
"roleName": "Designer",
"previousRoleName": "Content editor"
}
}
The documented SDK call uses webflow.workspaces.auditLogs.getWorkspaceAuditLogs in JavaScript and
client.workspaces.audit_logs.get_workspace_audit_logs in Python:
import { WebflowClient } from "webflow-api";
const webflow = new WebflowClient({ accessToken: process.env.WEBFLOW_WORKSPACE_TOKEN! });
const logs = await webflow.workspaces.auditLogs.getWorkspaceAuditLogs("fernbrook-workspace", {
from: new Date("2026-10-01T00:00:00Z"),
to: new Date("2026-10-28T00:00:00Z"),
limit: 100,
});
for (const entry of logs.items ?? []) {
console.log(entry.eventType, entry.eventSubType);
}
import datetime
import os
from webflow.client import Webflow
client = Webflow(access_token=os.environ["WEBFLOW_WORKSPACE_TOKEN"])
audit_logs = client.workspaces.audit_logs.get_workspace_audit_logs(
workspace_id_or_slug="fernbrook-workspace",
from_=datetime.datetime(2026, 10, 1, tzinfo=datetime.timezone.utc),
to=datetime.datetime(2026, 10, 28, tzinfo=datetime.timezone.utc),
)
print(audit_logs)
Site Activity log
The Site Activity endpoint takes only limit (maximum 100) and offset. Each entry carries an id, createdOn and
lastUpdated, an event (for example cms_item, site_published, page_created or branch_merged), a
resourceOperation (CREATED, MODIFIED, PUBLISHED, UNPUBLISHED, DELETED and reordering and group variants),
the acting user (an id and a displayName), resourceId, resourceName, newValue, previousValue and an
event-specific payload.
Two fields were added with the AI and MCP attribution described in
MCP Server and AI Agents. source names the originating system:
WEBFLOW_AI, WEBFLOW_MCP, DESIGNER or SYSTEM. actorType is user, agent, workflow or rule, with
actorId and actorName. Both are null for events recorded before attribution existed. Governance teams use them to
answer "did a person or an agent publish this change?", which is one of the strongest reasons for the Fernbrook trustees
to read this log. The documentation does not state a retention period, so a SIEM that must keep history for years
should copy entries out as they are produced instead of relying on the API as the archive.
curl --request GET \
--url "https://api.webflow.com/v2/sites/$WEBFLOW_SITE_ID/activity_logs?limit=100&offset=0" \
--header 'accept: application/json' \
--header "authorization: Bearer $WEBFLOW_API_TOKEN"
Source: Data API: Get Site Activity Logs
Feeding audit logs to a SIEM
The audit endpoints are pull endpoints, so a forwarder polls on a schedule and ships each new event to the log store. Page-branch events are the exception for Site changes, because the branch-created, branch-merged and branch-deleted webhooks exist (see Webhooks).
A robust forwarder follows a few rules:
-
Checkpoint by time, de-duplicate by content. Use the
fromfilter with the newest timestamp already shipped, re-read a small overlap, and drop events whose key (type, subtype, actor, target and timestamp) has already been stored. The audit events have no single documented identifier, so a derived key is required. -
Page with
offsetuntil it reachestotal. Sort ascending so a crash in the middle leaves a continuous prefix. -
Respect the limits. On a 429, wait for
Retry-Afterand keep the checkpoint where it was. -
Protect the token. The forwarder holds a read-only
workspace_activity:readtoken in a secret store. Revoke and replace it on a schedule. -
Alert on the interesting subset. Role changes to
Admin,custom_roleevents,workspace_settingevents, sign-ins from unexpected places, and Site Activity entries withactorTypeofagentthat publish a site.
// forward-audit-logs.ts
import { WebflowClient } from "webflow-api";
const webflow = new WebflowClient({ accessToken: process.env.WEBFLOW_WORKSPACE_TOKEN! });
const workspace = process.env.WEBFLOW_WORKSPACE_SLUG!;
async function* pull(from: Date) {
let offset = 0;
while (true) {
const page = await webflow.workspaces.auditLogs.getWorkspaceAuditLogs(workspace, {
from,
limit: 100,
offset,
});
const items = page.items ?? [];
yield* items;
offset += items.length;
if (items.length === 0 || offset >= (page.pagination?.total ?? 0)) return;
}
}
const checkpoint = new Date(process.env.LAST_CHECKPOINT ?? "2026-10-01T00:00:00Z");
for await (const event of pull(checkpoint)) {
await fetch(process.env.SIEM_INGEST_URL!, {
method: "POST",
headers: { "content-type": "application/json", authorization: `Bearer ${process.env.SIEM_TOKEN}` },
body: JSON.stringify(event),
});
}
The full pipeline belongs in version control and in the CI conventions of Testing, CI and DevOps; a contract test that replays a recorded page of audit events through the forwarder catches API drift before a gap appears in the evidence.
Identity, SSO and SCIM
Enterprise Workspaces can sign members in through the organisation’s identity provider and can have their member lifecycle provisioned by SCIM. Both are configured by Workspace administrators in the Dashboard together with Webflow, not through the Data API, and both leave traces in the API that are useful to know.
-
Single sign-on. The sign-in
methodof auser_accessevent isssowhen a member authenticated through the identity provider, so the audit log can show how many sign-ins bypass it, for exampledashboardorgooglesign-ins that an organisation intends to retire. -
SCIM provisioning. Membership and invitation events carry
scimas amethodwhen the identity provider created or changed them, and a member managed by SCIM cannot be re-roled by the bulk role endpoint (the failure code isworkspace_member_managed_by_scim). The identity provider is therefore the source of truth for who is in the Workspace, and the API is for reading and for the cases the provider does not cover. -
Offboarding. When a person leaves the organisation, disabling them in the identity provider is what ends their Webflow access. The audit log’s
user_removedevents with methodscimare the evidence that it did.
The configuration screens, supported identity providers and licensing terms are described by Webflow for Enterprise customers and can change between releases, so follow the current Webflow documentation for them rather than the Data API reference.
Custom roles
The built-in roles cover the common cases (see Plans, Workspaces, Seats and Roles for the table and the seat model). An Enterprise Workspace can additionally define custom roles, up to 20, starting from the permissions of a built-in role and adjusting them. The API surface for them is small and worth knowing precisely:
-
A custom Site role is referenced by
siteRole: "custom"plus asiteRoleIdin the grant, update, invite and bulk endpoints; the ID is required withcustomand rejected with any other role. -
In responses the member’s
roles.siteiscustomandroles.siteRoleIdholds the role’s ID. -
Creating, changing and deleting a role are written to the Workspace audit log as
custom_roleevents withrole_created,role_updatedandrole_deleted, together with the role name and its previous name. -
Granular access changes on a Site (restricting a role to certain resources) appear as
site_membershipevents withuser_granular_access_updatedand agranularAccessobject holding the resource’sid,name,typeand arestrictedflag.
The Fernbrook web team defines a Journal contributor custom role that can edit Journal items and upload assets but
cannot publish, and grants it with siteRole: "custom". The audit log answers the trustees' question of who created the
role and when.
{
"email": "journal.volunteer@example.org",
"siteRole": "custom",
"siteRoleId": "role_id_placeholder"
}
Source: Data API: Grant Site Access
Team plan and the Enterprise gap
The Team plan (a Site plan tier introduced in 2026 and described in Plans, Workspaces, Seats and Roles) moves several collaboration features that used to be Enterprise-only down a tier: page branching, single-page publishing, the publishing workflow and the Site Activity log in the Dashboard. The Enterprise reference sections described here are documented as requiring an Enterprise workspace. The practical consequences for a developer are:
-
A Team site can use the Data API as any paid site does, including webhooks, CMS and publish endpoints, but the Enterprise endpoints for creating or deleting Sites, managing redirects,
robots.txtor well-known files, managing members and reading the audit logs are not part of it. Those tasks are done in the Dashboard. -
Page branching is usable from the Designer on a Team site, and the branch-created, branch-merged and branch-deleted webhook payloads describe branches (
siteId,branchId,pageId,parentPageId,pageName,createdByandcreatedOn). The branch-management scopes (branches:read,branches:create,branches:update,branches:delete,branches:merge,branches:publish) are listed in the Scopes reference. See Page Branching, Releases and Approvals. -
The Developer workspace plan, which is free and limited to three workspace users and 1,000 visitors a month, includes Custom Code, the Site Activity Log and Page Branching, and does not allow publishing to production, code export or site transfer. It is therefore a good place to rehearse the Site Activity calls.
A governance checklist for a federation of sites
A short operating model for an organisation such as Fernbrook Gardens, in the order a new Enterprise Workspace usually needs it:
-
Identity first. Connect the identity provider for sign-in and provisioning so that joiners and leavers follow HR records, and keep a small number of break-glass administrator accounts whose use alerts the web team.
-
Roles second. Prefer built-in roles; add custom roles only where a real separation of duties exists, such as editors who cannot publish. Review them through
site_membershipandcustom_roleevents. -
Tokens third. Create one workspace token for each integration with the minimum scope, store the values in a secrets manager, rotate them, and revoke them when an owner leaves. Remember the five-token limit when planning.
-
Baselines as code. Keep the robots rules, the security file and the redirect list of each site in version control and apply them with the endpoints above on every release. A nightly job lists the live values and reports drift.
-
Evidence continuously. Forward both logs to the SIEM and retain them according to the organisation’s policy, because the API does not state a retention period.
-
Review quarterly. A script lists members and invites with the list endpoints, flags people with no sign-in in 90 days from the audit log and sends the report to site owners to confirm or revoke.
-
Restrict destructive calls. Site deletion and bulk member removal belong in a pipeline with a second approver and a fresh backup.
Pitfalls and corrections
-
Plan errors are not scope errors. An Enterprise-only call from a non-Enterprise workspace fails with a plan-related error even when the token has every scope; check the Workspace plan before debugging the token.
-
Site tokens cannot do Workspace administration. The Workspace audit log needs a Workspace token or a Data Client app registered with workspace-level access; a site token returns an authorisation error. New site tokens cannot have the
workspace:readscope. -
Documentation inconsistencies. A few endpoint pages show example fields that differ slightly from their schema (for example the Site Plan response names its information link
pricingInfoin the schema andpricingDetailsin the example). Read the field defensively and prefer the schema. -
Bulk endpoints return 200 on partial failure. Always inspect
summaryandresults. -
Publish after changing configuration. Publish the site after changing redirects,
robots.txtor well-known files, and fetch the live file to confirm the result. -
Older material. Older books and tutorials describe these tasks in the Dashboard only. The reference now documents each of them as an endpoint with its scope. See Where Older Books and Tutorials Are Outdated.
Where to go next
-
Data API: Authentication and Scopes for site tokens, OAuth and the general scope model.
-
Data API: SDKs, Limits and Errors for the SDK clients, retries and the error model.
-
Plans, Workspaces, Seats and Roles for the tiers, seats and built-in roles.
-
Collaboration, Comments and the Activity Log for the Dashboard view of site activity.
-
MCP Server and AI Agents for agent attribution in the logs.
-
Testing, CI and DevOps for running the forwarder and baseline jobs in CI.