Automation REST API
Create scoped tokens and manage the OrbitPage dashboard end to end from scripts, n8n, backends or CI.
Choose the right API
This page documents the versioned REST boundary. An OrbitPage token is not an OpenAI provider key and never authenticates private dashboard endpoints.
| Surface | Credential | Purpose and support |
|---|---|---|
| Automation REST API | op_pat_... | Supported external API for scripts, n8n, server backends and CI. It manages the token-bound workspace through /api/v1. |
| OrbitPage AI | op_pat_... + ai:read/ai:write | The public plan/commit flow prepares and applies validated AI proposals. Any OpenAI provider credential remains a separate server-side concern and is never an OrbitPage bearer token. |
| Dashboard APIs | Firebase session on SaaS; admin session on OSS | Private browser-to-app routes. They are not a stable external integration contract and must not receive personal API tokens. |
REST API overview
Every request is bound to the workspace selected when the token was created. A token cannot choose another tenant in the URL or request body, and current workspace permissions are checked again on every call.
The contract uses standard HTTPS JSON operations—GET, POST, PUT, PATCH and DELETE—and supports curl, n8n's HTTP Request node and generated OpenAPI clients.
GET/api/v1/linksRead every page block
Returns the ordered collection, workspace identity and the current revision.
Scope:links:readPATCH/api/v1/links/{linkId}Change one existing block
Merges editable fields, validates the whole page and publishes the new revision.
Scope:links:writePUT/api/v1/linksReplace the full collection
Use this to add, remove or reorder blocks after reading and preserving the current collection.
Scope:links:write| Dashboard surface | API paths | Scopes |
|---|---|---|
| Workspace and complete draft | /workspace · /draft | workspace:read |
| Profile, theme and subpages | /profile · /theme · /pages | profile:* · theme:* · pages:* |
| General, privacy and menu settings | /settings/* | settings:* |
| Publication, versions and backup | /publication · /versions · /backup | publication:* · backup:* |
| Media and custom domains | /media/* · /domains/* | media:* · domains:* |
| Analytics and reviewed AI changes | /analytics · /ai/* | analytics:read · ai:* |
| Shop and newsletter | /shop/* · /newsletter/* | shop:* · newsletter:* |
| Team and billing | /team/* · /billing/* | team:* · billing:* |
Complete endpoint reference
Paths below are relative to https://orbitpage.com/api/v1. Method, path and scope are the stable integration contract; request schemas, formats, enum values and response models live in the linked OpenAPI 3.1 document. Unknown routes return 404 and unsupported methods are never silently converted.
01Workspace, content and appearanceInspect the token-bound workspace and manage its complete draft, profile, blocks, theme and subpages.11 operations
| Method and path | Operation | Required scope | Input and controls |
|---|---|---|---|
GET/workspace | Read workspace, plan, access, usage and revision | workspace:read | — |
GET/draft | Read the complete editable page draft | workspace:read | — |
GET/links | List page blocks and the current revision | links:read | — |
PUT/links | Replace the complete ordered block collection | links:write | LinksReplaceRequest · If-Match |
PATCH/links/{linkId} | Update editable fields on one block | links:write | LinkPatch · If-Match |
GET/profile | Read profile identity and metadata | profile:read | — |
PATCH/profile | Update profile fields | profile:write | JSON · If-Match · ?publish=1 |
GET/theme | Read the active draft theme | theme:read | — |
PUT/theme | Replace the draft theme | theme:write | JSON · If-Match · ?publish=1 |
GET/pages | List configured subpages | pages:read | — |
PUT/pages | Replace configured subpages | pages:write | array | { pages } · If-Match · ?publish=1 |
02Settings and publicationControl menus, privacy, managed public files, sitemap generation and the explicit draft-to-public lifecycle.9 operations
| Method and path | Operation | Required scope | Input and controls |
|---|---|---|---|
GET/settings | Read menu, privacy, text-file and sitemap settings | settings:read | — |
PUT/settings/menu | Update menu settings | settings:write | JSON · If-Match · ?publish=1 |
PUT/settings/privacy | Update consent and privacy settings | settings:write | JSON · If-Match · ?publish=1 |
POST/settings/text-files | Create a managed public text file | settings:write | TextFileCreateRequest · If-Match |
PUT/settings/text-files/{key} | Update a managed public text file | settings:write | TextFileUpdateRequest · If-Match |
DELETE/settings/text-files/{key} | Delete a managed public text file | settings:write | If-Match |
POST/settings/sitemap | Regenerate the managed sitemap | settings:write | If-Match |
GET/publication | Read draft and publication status | publication:read | — |
POST/publication | Publish the latest validated draft | publication:write | — |
03Versions, backups and mediaRestore revisioned content, export or import workspace data, and run the reserve-upload-finalize media lifecycle.9 operations
| Method and path | Operation | Required scope | Input and controls |
|---|---|---|---|
GET/versions | List restorable published page versions | backup:read | — |
POST/versions/{revision}/restore | Restore and immediately publish a historical version | backup:write | If-Match |
GET/backup | Export a managed workspace backup | backup:read | ?sections=profile,links,… |
POST/backup/restore | Validate, restore and immediately publish a managed backup | backup:write | BackupRestoreRequest · If-Match |
GET/media | List workspace media metadata and usage | media:read | — |
POST/media/cleanup | Preview or delete unreferenced media | media:write | MediaCleanupRequest |
POST/media/uploads/reserve | Reserve a direct media upload | media:write | MediaUploadReserveRequest |
POST/media/uploads/finalize | Finalize and register an uploaded object | media:write | UploadTokenRequest |
DELETE/media/uploads | Abort a reserved media upload | media:write | UploadTokenRequest |
04Domains, analytics and AIManage DNS activation, read plan-bounded performance reports and apply AI changes only after a validated preview.8 operations
| Method and path | Operation | Required scope | Input and controls |
|---|---|---|---|
GET/domains | Read domain status and DNS requirements | domains:read | — |
POST/domains | Connect a custom domain | domains:write | DomainConnectRequest |
POST/domains/refresh | Refresh verification and activation | domains:write | — |
DELETE/domains | Disconnect the custom domain | domains:write | — |
GET/analytics | Read the dashboard analytics report | analytics:read | ?days=7|30|90 |
GET/ai/allowance | Read AI allowance and current usage | ai:read | — |
POST/ai/plan | Generate a validated AI change preview | ai:write | AiPlanRequest |
POST/ai/commit | Commit a previously validated AI preview | ai:write | AiCommitRequest |
05ShopConnect commerce, manage products and appearance, upload protected files, then publish or unpublish the synchronized Shop block.10 operations
| Method and path | Operation | Required scope | Input and controls |
|---|---|---|---|
GET/shop | Read products, orders, customers and Shop state; may initialize private Shop data and refresh Stripe status | shop:read | ?refresh=0|1 |
POST/shop/connect | Create or continue Stripe Connect onboarding | shop:write | — |
POST/shop/products | Create or update a Shop product | shop:write | ShopProductRequest |
DELETE/shop/products/{productId} | Delete a Shop product | shop:write | — |
PUT/shop/appearance | Replace entire Shop appearance | shop:write | ShopAppearanceRequest |
POST/shop/publish | Publish Shop and its synchronized page block | shop:write | — |
POST/shop/unpublish | Unpublish Shop | shop:write | — |
POST/shop/uploads/reserve | Reserve a product-file upload | shop:write | ShopFileUploadReserveRequest |
POST/shop/uploads/finalize | Finalize a product-file upload | shop:write | ShopUploadTokenRequest |
DELETE/shop/uploads | Abort a reserved product-file upload | shop:write | ShopUploadTokenRequest |
06NewsletterConfigure encrypted SMTP delivery, manage consented subscribers and control the complete campaign lifecycle.9 operations
| Method and path | Operation | Required scope | Input and controls |
|---|---|---|---|
GET/newsletter | Read subscribers, campaigns and SMTP state | newsletter:read | — |
PUT/newsletter/settings | Update encrypted SMTP settings | newsletter:write | NewsletterSmtpRequest |
POST/newsletter/settings/test | Send a configuration test | newsletter:write | EmailRecipientRequest |
POST/newsletter/subscribers | Add or update a consented subscriber | newsletter:write | NewsletterSubscriberRequest |
DELETE/newsletter/subscribers/{subscriberId} | Remove a subscriber | newsletter:write | — |
POST/newsletter/campaigns | Create or update a campaign | newsletter:write | NewsletterCampaignRequest |
DELETE/newsletter/campaigns/{campaignId} | Delete a campaign | newsletter:write | — |
POST/newsletter/campaigns/{campaignId}/send | Queue or schedule a campaign | newsletter:write | NewsletterSendRequest |
DELETE/newsletter/campaigns/{campaignId}/send | Cancel a queued campaign | newsletter:write | — |
07Team and billingManage collaborators and invitations, inspect subscriptions and open authenticated Stripe checkout or portal sessions.9 operations
| Method and path | Operation | Required scope | Input and controls |
|---|---|---|---|
GET/team | List members and pending invitations | team:read | — |
POST/team/invitations | Create a workspace invitation link without sending email | team:write | TeamInvitationRequest |
PATCH/team/members/{memberUid} | Update a member role | team:write | TeamRoleRequest |
DELETE/team/members/{memberUid} | Remove a workspace member | team:write | — |
DELETE/team/invitations/{invitationId} | Revoke a pending invitation | team:write | — |
GET/billing | Read plan and subscription state | billing:read | — |
POST/billing/checkout | Create a Stripe plan checkout | billing:write | BillingCheckoutRequest |
POST/billing/portal | Create a Stripe billing-portal session | billing:write | BillingPortalRequest |
POST/billing/promotion-code | Redeem a promotion code and reconcile plan entitlements | billing:write | PromotionCodeRedeemRequest |
Create and use a token
Open Dashboard > Team > Personal API tokens. Give the token a name that identifies its owner and purpose, choose full workspace, read-only workspace, links-only or individual resource scopes, then select an expiry of 30, 90 or 365 days—or no expiry when a documented rotation process already exists.
Confirm your identity
Token creation is a sensitive account action and requires a recent Google or password authentication.
Choose the smallest scope
Read and write scopes are separate for each resource—for example theme:read, theme:write, shop:read and shop:write. A write scope automatically includes its matching read scope.
Copy the secret once
OrbitPage stores a SHA-256 hash, not the recoverable secret. If it is lost, revoke it and create another token.
Store it outside the code
Use an environment variable or a CI secret store. Never put the token in a URL, repository, screenshot, browser bundle or build log.
export ORBITPAGE_TOKEN='op_pat_...'
curl --silent --show-error --include \
--header "Authorization: Bearer $ORBITPAGE_TOKEN" \
https://orbitpage.com/api/v1/links$env:ORBITPAGE_TOKEN = 'op_pat_...'
$headers = @{ Authorization = "Bearer $env:ORBITPAGE_TOKEN" }
Invoke-RestMethod -Uri 'https://orbitpage.com/api/v1/links' -Headers $headersRead the collection
The response body contains the ordered blocks in data and the current numeric revision. The same revision appears in X-OrbitPage-Revision and as a weak ETag. Save either value for If-Match; do not guess or cache it across unrelated runs.
HTTP/2 200
etag: W/"42"
x-orbitpage-revision: 42
content-type: application/json; charset=utf-8
{
"object": "list",
"data": [
{
"id": "portfolio-main",
"type": "link",
"title": "Selected work",
"description": "Recent projects and case studies",
"url": "https://example.com/work",
"isActive": true,
"status": "live",
"availability": "available",
"clickCount": 18,
"position": 0
}
],
"revision": 42,
"workspace": {
"tenantId": "tenant_...",
"pageId": "page_...",
"username": "your-page"
}
}dataThe complete ordered block collection. Array order is the visual page order.revisionThe optimistic-concurrency version used by every write.workspaceThe tenant, page and username permanently bound to this token.ETagThe safest value to pass directly as the next If-Match header.Update one block
URL-encode the ID returned by GET and send only the fields that should change. OrbitPage merges the patch into the existing block, protects identity and analytics fields, validates the complete page against its schema and plan, then publishes immediately.
curl --request PATCH \
--url https://orbitpage.com/api/v1/links/portfolio-main \
--header "Authorization: Bearer $ORBITPAGE_TOKEN" \
--header 'Content-Type: application/json' \
--header 'If-Match: W/"42"' \
--data '{
"title": "Book a consultation",
"url": "https://example.com/book",
"isActive": true
}'| Field group | Examples | Behavior |
|---|---|---|
| Content | title, description, url, content, textItems | Editable when valid for the existing block type. |
| Visibility and timing | isActive, status, availability, startDate, endDate, timezone | Validated together with scheduling and plan rules. |
| Appearance and media | icon, coverImage, backgroundColor, alignment, size | Accepted only when values match the page schema. |
| Protected | id, type, clickCount, ctaClicks, systemKey | Ignored or rejected. System-managed blocks cannot be patched. |
Replace the collection
PUT replaces the complete ordered collection. It is the operation for adding a block, removing a block or changing page order. It is not a shortcut for updating one title: omitting a block removes it from the page.
const token = process.env.ORBITPAGE_TOKEN;
if (!token) throw new Error("ORBITPAGE_TOKEN is missing");
const endpoint = "https://orbitpage.com/api/v1/links";
const authorization = { Authorization: `Bearer ${token}` };
const read = await fetch(endpoint, { headers: authorization });
if (!read.ok) throw new Error(`GET failed: ${read.status} ${await read.text()}`);
const current = await read.json();
const revision = read.headers.get("etag") ?? String(current.revision);
// Preserve the full collection and change only the intended block.
const links = current.data.map((block) =>
block.id === "portfolio-main"
? { ...block, title: "Work and case studies" }
: block
);
const write = await fetch(endpoint, {
method: "PUT",
headers: {
...authorization,
"Content-Type": "application/json",
"If-Match": revision
},
body: JSON.stringify({ links })
});
if (!write.ok) throw new Error(`PUT failed: ${write.status} ${await write.text()}`);
console.log(await write.json());n8n and end-to-end workflows
OrbitPage does not require an SDK: any HTTPS client that can send JSON, Bearer authentication and standard GET, POST, PUT, PATCH and DELETE requests is compatible. The patterns below cover the stateful parts that an integration must handle explicitly.
Verified n8n community node
Install n8n-nodes-orbitpage and create an OrbitPage API credential with the personal token and Base URL. The connection test performs a safe workspace read; guided actions then handle paths, scopes, item linking and revision-aware writes without placing the secret in workflow JSON.
Draft and publication
Profile, theme, pages and supported settings writes require If-Match and update the draft by default. Add ?publish=1 for an eligible immediate publication, or review several deferred changes and call POST /publication once. Link PATCH and PUT publish immediately.
Direct media upload
Reserve first, upload bytes to the returned storage URL, then finalize. Send the OrbitPage bearer token only to orbitpage.com; use only the method and temporary headers returned for the storage request.
Reviewed AI commit
Plan returns a validated preview without mutating the page. Store and review its previewToken, then commit exactly that proposal. Set publish in the commit body only when the automation is authorized to make the result public.
OrbitPage is approved by n8n as a Verified Community Node; it remains community-maintained and is not preinstalled. Once it appears in the verified catalog, an instance owner or admin can search for OrbitPage in the + nodes panel, select More from the community and choose Install, including on n8n Cloud. If it is not listed yet, Cloud users must wait for catalog publication; self-hosted users can install n8n-nodes-orbitpage through Settings → Community Nodes.
Installation, downloads and example workflows
Install community node: n8n-nodes-orbitpage
Credential: OrbitPage API
OrbitPage API Token: op_pat_...
OrbitPage Base URL: https://orbitpage.com
Connection test: GET /api/v1/workspace
First safe workflow step:
Node: OrbitPage
Resource: Workspace & Draft
Operation: Get Workspace Overview
First revision-controlled write:
Resource: Theme
Operation: Replace Entire Theme Draft
Revision Check: Use Latest Automatically (Recommended)# 1. Reserve an upload and receive uploadUrl, slot and uploadToken
POST /api/v1/media/uploads/reserve
{ "filename": "cover.jpg", "contentType": "image/jpeg", "sizeBytes": 245760 }
# 2. Upload the bytes directly using the returned URL, method and headers
# Do not forward the OrbitPage Authorization header to the storage URL.
# 3. Register the uploaded object in the workspace
POST /api/v1/media/uploads/finalize
{ "slot": "<slot>", "uploadToken": "<uploadToken>" }# 1. Generate a validated preview without changing the page
POST /api/v1/ai/plan
{ "message": "Make the primary CTA clearer" }
# 2. Review the returned operations and previewToken
# 3. Apply the exact reviewed preview; publishing remains explicit
POST /api/v1/ai/commit
{ "previewToken": "<previewToken>", "publish": false }Use Base URL https://orbitpage.com, without /api/v1. A successful save reads /api/v1/workspace and confirms the token, workspace binding and workspace:read scope without changing data.
A 401 requires a valid replacement token, a 403 requires the missing scope, and repeated redirects require checking the Base URL or reverse proxy. Share status and JSON code with support, never the secret.
CI, rotation and revocation
A workspace supports up to ten active personal tokens per user. The Team token list shows each token's prefix, scopes, creation and expiry dates, and recent use. Last-used timestamps are intentionally written at most once every five minutes.
name: Update OrbitPage
on: workflow_dispatch
jobs:
update:
runs-on: ubuntu-latest
env:
ORBITPAGE_TOKEN: ${{ secrets.ORBITPAGE_TOKEN }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
- run: node scripts/update-orbitpage.mjs- Name tokens by system and environment—for example, “GitHub Actions · production”.
- Rotate by creating the replacement, updating the secret store, testing one read, then revoking the old token.
- Revoke immediately after suspected disclosure, ownership change or workflow retirement. Revocation takes effect on the next request.
- Do not build a long-lived shared token. Separate credentials make logs, rotation and incident response understandable.
Errors and retries
Errors use JSON with error and code. Do not parse the human sentence to control a workflow. Most 4xx responses require changing the request or credential; only revision conflicts and rate limits belong in an automatic retry path.
INVALID_JSON · LINKS_REQUIRED · LINK_PATCH_INVALIDFix the request body or the fields rejected by the page schema.PERSONAL_TOKEN_*Replace a missing, invalid, expired or revoked token. Do not retry with the same secret.PERSONAL_TOKEN_SCOPE_DENIED · SYSTEM_LINK_PROTECTEDUse the required scope or stop: the current identity is not allowed to perform this operation.LINK_NOT_FOUNDRefresh the collection; the block ID may have been removed or replaced.revision_conflictGET again, reapply the intended change to the new state and retry with the new revision.REQUEST_TOO_LARGEKeep the JSON body at or below 768 KiB.UNSUPPORTED_CONTENT_ENCODINGSend an uncompressed JSON request body.revision_requiredAdd If-Match using the revision or ETag returned by the latest GET.RATE_LIMITEDWait for Retry-After, then retry with exponential backoff and jitter.Current guardrails allow 120 requests per minute and 5,000 requests per day per token. Limits may become stricter during abuse protection; always honor Retry-After.
Validate outcomes
Check response status, revision and returned data. For important changes, open the public page after publication and alert on failure without logging the token.
SaaS and open source
The open-source repository contains an Express API used by its bundled dashboard, but that internal admin-session API is not the same versioned automation contract. Do not send an op_pat token to a self-hosted server and do not send a self-hosted admin JWT to orbitpage.com/api/v1.
Read the open-source API boundary