Automate OrbitPage without sharing a dashboard session.
Create scoped tokens and manage the OrbitPage dashboard end to end from scripts, n8n, backends or CI.
Last reviewed August 4, 2026Manage your OrbitPage workspace with scoped personal tokens: edit pages, publish, and use media, domains, analytics, AI, Shop, newsletters and billing.
Three credential boundaries cover three different jobs.
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. |
Versioned resources cover the dashboard; the link endpoints show the safe-update loop.
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:* |
Every supported dashboard operation, grouped by the surface it controls.
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 one token for one automation and one environment.
Open Dashboard > Account > 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 and capture its revision before every change.
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.Use PATCH for the smallest change to an existing 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. |
Use PUT only when the collection itself must change.
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());Use the native n8n node or the same contract from an HTTP client, generated client, backend or CI runner.
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.
Native n8n 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.
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.
Treat automation credentials as short, observable lifecycles.
A workspace supports up to ten active personal tokens per user. The Account 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.
Branch on the HTTP status and machine-readable code.
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.
A safe integration is narrow, secret and revision-aware.
Least privilege
Use read-only unless the job must publish. Token capabilities can never exceed the owner's current workspace role.
Server-side only
Call the API from a trusted script, backend or CI runner. A browser bundle, mobile client or public repository cannot keep a bearer secret.
No blind writes
GET immediately before a write and use If-Match. If a 409 returns revision_conflict, read again and reapply the intent; for any other code, resolve the documented business condition.
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.
The personal-token Automation REST API is a managed SaaS capability.
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.
Use this guide, the OpenAPI contract and personal tokens created in Account.
Use the bundled dashboard on the same trusted origin. The repository documentation explains the internal boundary for contributors and maintainers.