Reading time: 12 min read

Three important APIs to master SitecoreAI

A practical, Postman-first tour of every API you'll touch on SitecoreAI — with credentials, scopes, endpoints, and the gotchas that trip up everyone.

Portrait photo of Sohrab Saboori, article author

A deep dive into the three important APIs of SitecoreAI

There are really three APIs that matter on SitecoreAI. Each one tied to a distinct stage of the content lifecycle, and each one unlocked by a different credential type. Master those three and you can drive every programmatic interaction with the platform: reading content, editing it, running workflow, publishing, clearing cache, rotating keys.

This guide walks through each API: what it does, which credential unlocks it, where to create that credential, and the exact Postman request to fire. Everything here is drawn from real hands-on work wiring up a production workflow app, including the specific gotchas that waste the most time.

By the end you'll have three credentials, a working Postman collection, and a mental model that makes the whole platform click.

The mental model — three content lifecycle stages, 3 + 1 APIs

Every piece of content on SitecoreAI moves through three stages:

  1. Author — created and edited in the Content Management (CM) instance
  2. Publish — promoted from CM to the Experience Edge delivery layer
  3. Deliver — served to your website, app, or search index

Each stage has its own API:

StageAPIWhat it does
AuthorAuthoring & Management GraphQL APICreate/edit items, run workflow
PublishEdge Administration REST APIManage cache, webhooks, settings
DeliverEdge Delivery GraphQL APIRead published content

Plus a fourth sibling of the Edge Admin API that most people miss:

ExtraAPIWhat it does
Token managementEdge Token REST APICreate / revoke the sc_apikey keys used by Delivery

So the real count is 3 primary APIs + 1 reference API, and they're managed by 3 types of credentials.

The "two APIs or one?" trap

Sitecore's own docs say "Sitecore Authoring and Management GraphQL API" — singular. Read the first line of the official reference:

The Sitecore Authoring and Management API provides a single endpoint and schema that allows you to manage your Sitecore content using GraphQL.

One endpoint. One schema. One credential scope.

What trips people up is that older blog posts and credential labels imply they're separate. They're not. The names describe two categories of operations inside the same API:

  • Authoring operationscreateItem, updateItem, deleteItem, moveItem
  • Management operationsexecuteWorkflowCommand, workflow state queries

Same URL. Same Bearer token. Different GraphQL mutations. That's the whole story.

Where credentials come from: the portal

All OAuth credentials are created on the Credentials page of your SitecoreAI project:

https://portal.sitecorecloud.io → Your project → Credentials

The Organization vs Environment tab

TabScopeUse for
OrganizationWorks across every environment in the orgCI/CD pipelines, Sitecore CLI, cross-env tooling
EnvironmentScoped to one environmentApp runtime credentials (safer)

Rule of thumb: app runtime → Environment tab. CI/CD → Organization tab. Environment-scoped creds have a smaller blast radius if they leak.

The three credential types

When you click Create credentials, you pick a type. The type is the scope preset. You don't get a separate scope picker in the UI.

TypeGrantsUse for
Automationxmcloud.cm:admin + xmclouddeploy.*Authoring & Management GraphQL API
Edge administrationedge.* (cache, settings, webhooks, tokens)Edge Admin REST API + Edge Token REST API
External editing hostCLI/editing host scopesSitecore CLI, external editing host deploys

For typical app development, you need one Automation credential and one Edge administration credential. That's it.

Verifying what a credential can do

The credential list in the portal does not show scopes. The only reliable way to see what a credential actually unlocks is to request an OAuth token and decode it:

  1. Request an access token via Postman (shown below)
  2. Copy the access_token string
  3. Paste into https://jwt.io
  4. Look at the scope claim

Example decoded scopes from an Automation credential:

xmclouddeploy.organizations:manage
xmclouddeploy.projects:manage
xmclouddeploy.environments:manage
xmclouddeploy.deployments:manage
xmcloud.cm:admin        ← this one unlocks Authoring & Management

Example from an Edge administration credential:

edge.caches:clear
edge.settings:read / update
edge.webhooks:create / read / update / delete
edge.tokens:create / read / update / delete
edge.content:publish
edge.content:clearall

Another useful claim: tenant_id — it tells you which Sitecore environment the token is bound to. More on this in the gotchas section.

Postman setup

Create a Postman environment with these variables before starting:

# Your environment's instance slug — from Environment host name on the Details tab
# e.g. fishtankcon7604-navigatoracc468-dev2cbf
SITECORE_INSTANCE=
# --- Edge Delivery (read) ---
SITECORE_EDGE_DELIVERY_ENDPOINT=https://xmc-{INSTANCE}.sitecorecloud.io/sitecore/api/graph/edge
SITECORE_API_KEY=           # sc_apikey — Edge delivery key
# --- Authoring & Management (one API) ---
SITECORE_MANAGEMENT_ENDPOINT=https://xmc-{INSTANCE}.sitecorecloud.io/sitecore/api/authoring/graphql/v1
SITECORE_MANAGEMENT_CLIENT_ID=      # from Automation credential
SITECORE_MANAGEMENT_CLIENT_SECRET=  # from Automation credential
SITECORE_MANAGEMENT_AUDIENCE=https://api.sitecorecloud.io
# --- Edge Administration + Token ---
EDGE_ADMIN_ENDPOINT=https://edge.sitecorecloud.io/api/admin/v1
EDGE_TOKEN_ENDPOINT=https://edge.sitecorecloud.io/api/apikey/v1
EDGE_ADMIN_CLIENT_ID=               # from Edge administration credential
EDGE_ADMIN_CLIENT_SECRET=           # from Edge administration credential
EDGE_ADMIN_AUDIENCE=https://api.sitecorecloud.io
# --- Test data ---
TEST_ITEM_ID={YOUR-TEST-ITEM-GUID}  # format: {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}
WORKFLOW_COMMAND_ID=                # from GetWorkflow response (see below)

Important: Once variables are filled, activate the environment using the dropdown in the top-right of Postman. If you leave it on "No environment," your {{variables}} won't resolve and every request will fail in confusing ways.

API 1: Edge delivery

Role: Read published content from the delivery layer. This is what your website calls.

Endpoint: https://xmc-{instance}.sitecorecloud.io/sitecore/api/graph/edge

Protocol: GraphQL

Auth: sc_apikey header (no OAuth, a single long-lived string)

Where to get the key:

  • Option 1: Call the Edge Token REST API (see below) — POST /api/apikey/v1/tokens
  • Option 2: Create an API Key item in CM at /sitecore/system/Settings/Services/API Keys

Example Postman request

POST {{SITECORE_EDGE_DELIVERY_ENDPOINT}}
Content-Type: application/json
sc_apikey: {{SITECORE_API_KEY}}
{
  "query": "query GetItems($path: String!, $lang: String!) { item(path: $path, language: $lang) { id name path children(first: 10) { results { id name path } } } }",
  "variables": {
    "path": "/sitecore/content",
    "lang": "en"
  }
}

Operations available

  • item(path, language) — fetch a single item
  • item.children, item.ancestors — navigate the tree
  • search(...) — full-text search across published content
  • site(name) — site-specific queries

Notes

  • Edge Delivery only returns content that has been published to Edge. Drafts are invisible here.
  • Responses are CDN-cached globally — very fast.
  • No write operations — this API is read-only.
  • You do not need an OAuth token to call this. The sc_apikey is sufficient.

API 2: Authoring & Management

Role: Everything on the CM side — content CRUD, workflow, templates, versions. One API covers it all.

Endpoint: https://xmc-{instance}.sitecorecloud.io/sitecore/api/authoring/graphql/v1

Protocol: GraphQL

Auth: OAuth Bearer (Automation credential, scope xmcloud.cm:admin)

Step 1: Get the OAuth token

POST https://auth.sitecorecloud.io/oauth/token
Content-Type: application/json
{
  "client_id": "{{SITECORE_MANAGEMENT_CLIENT_ID}}",
  "client_secret": "{{SITECORE_MANAGEMENT_CLIENT_SECRET}}",
  "audience": "https://api.sitecorecloud.io",
  "grant_type": "client_credentials"
}

Response contains access_token, save it to {{management_access_token}}.

Postman Tests tab script to auto-save:

if (pm.response.code === 200) {
  const body = pm.response.json();
  pm.environment.set('management_access_token', body.access_token);
  console.log('✅ Token saved. Expires in', body.expires_in, 'seconds');
}

Step 2: Update an item (authoring operation)

⚠ Important: The straightforward-looking mutation with $fields: [ItemFieldInput!]! as a variable will fail with:

"The specified value type of field `fields` does not match the field type."

on SitecoreAI. The fix is to inline the fields array inside the mutation and parameterize only the value:

POST {{SITECORE_MANAGEMENT_ENDPOINT}}
Content-Type: application/json
Authorization: Bearer {{management_access_token}}
{
  "query": "mutation UpdateItem($itemId: ID!, $value: String!) { updateItem(input: { itemId: $itemId, fields: [{ name: "__Display Name", value: $value }] }) { item { itemId name } } }",
  "operationName": "UpdateItem",
  "variables": {
    "itemId": "{{TEST_ITEM_ID}}",
    "value": "Updated from Postman"
  }
}

Field naming notes:

  • Sitecore system fields start with __ (double underscore): __Display Name, __Icon, __Workflow
  • Custom fields use their exact internal name: Title, approvalItemStatus
  • The display label you see in Content Editor is not always the internal name. Always use the internal name in GraphQL

Step 3: Advance a workflow (management operation)

POST {{SITECORE_MANAGEMENT_ENDPOINT}}
Content-Type: application/json
Authorization: Bearer {{management_access_token}}
{
  "query": "mutation ExecuteWorkflowCommand($item: ItemQueryInput!, $commandId: String!) { executeWorkflowCommand(input: { item: $item, commandId: $commandId }) { successful message } }",
  "operationName": "ExecuteWorkflowCommand",
  "variables": {
    "item": { "itemId": "{{TEST_ITEM_ID}}" },
    "commandId": "{{WORKFLOW_COMMAND_ID}}"
  }
}

Critical observation: this request uses the same endpoint URL and the same Bearer token as the updateItem above. The only difference is the mutation. This is the concrete proof that "Authoring API" and "Management API" are one API.

To find a commandId

First query the item's current workflow state:

query GetWorkflow($itemId: ID!) {
  item(where: { itemId: $itemId }) {
    itemId
    name
    workflow {
      workflow { workflowId name }
      workflowState {
        stateId
        displayName
        finalState
      }
    }
  }
}

The available commands for the current state are returned in the schema. Copy the relevant commandId GUID into your WORKFLOW_COMMAND_ID env var.

What else this API can do

Content CRUD is only one corner of the surface. Other operations available:

CategoryOperations
Content CRUDcreateItem, updateItem, deleteItem, moveItem, renameItem, copyItem, duplicateItem
TemplatescreateItemTemplate, updateItemTemplate, deleteItemTemplate
VersionsaddItemVersion, deleteItemVersion
WorkflowexecuteWorkflowCommand, workflow state queries
Query & searchitem(where: …), item.children, item.ancestors, search(…), itemTemplate(…)

Rule of thumb: anything you can do in the Content Editor UI, you can automate through this one endpoint.

Full schema explorer: https://edge-platform.sitecorecloud.io/api/graphql/ide

Authoring & Management queries vs Edge Delivery queries

Both APIs have item() and search() queries, but they're not the same:

 Authoring & ManagementEdge Delivery
Data sourceCM database (drafts + published)Edge index (published only)
SpeedDirect CM hit — slowerCDN-cached — fast
Use caseAdmin tooling, dashboards, automationWebsite, mobile app
AuthOAuth Bearersc_apikey

If your website calls search(), use Edge Delivery. If your admin dashboard needs to see drafts, use Authoring & Management.

API 3: Edge administration

Role: Manage the Edge delivery layer itself — NOT publish content, NOT create delivery keys.

Endpoint: https://edge.sitecorecloud.io/api/admin/v1

Protocol: REST (not GraphQL — the only one in the tour)

Auth: OAuth Bearer (Edge administration credential, edge.* scopes)

Note: This API manages the Edge layer infrastructure. Publishing happens CM-side (through workflow rules or manually triggered through the CM's publishing pipeline). Delivery API keys are managed by the separate Token API below.

Get the Edge admin token

Same OAuth pattern as Management, but use the Edge administration credentials:

POST https://auth.sitecorecloud.io/oauth/token
Content-Type: application/json
{
  "client_id": "{{EDGE_ADMIN_CLIENT_ID}}",
  "client_secret": "{{EDGE_ADMIN_CLIENT_SECRET}}",
  "audience": "https://api.sitecorecloud.io",
  "grant_type": "client_credentials"
}

Decode the returned token on jwt.io and you'll see edge.* scopes, a completely different set from the Automation token.

All 10 REST endpoints

The Admin API exposes exactly these endpoints:

ResourceMethodPathPurpose
CacheDELETE/cacheClear the entire tenant cache (202 Accepted)
ContentDELETE/contentWipe all tenant data (danger — use carefully)
SettingsGET/settingsRead cache TTLs and auto-clear flags
SettingsPUT/settingsReplace all settings
SettingsPATCH/settingsModify individual settings
WebhooksGET/webhooksList all webhooks
WebhooksGET/webhooks/{id}Fetch one
WebhooksPOST/webhooksCreate
WebhooksPUT/webhooks/{id}Update
WebhooksDELETE/webhooks/{id}Delete

Example: clear the cache

DELETE {{EDGE_ADMIN_ENDPOINT}}/cache
Authorization: Bearer {{edge_admin_token}}

Expected response: 202 Accepted with empty body.

Example: create an Edge webhook

POST {{EDGE_ADMIN_ENDPOINT}}/webhooks
Content-Type: application/json
Authorization: Bearer {{edge_admin_token}}
{
  "label": "my-webhook",
  "uri": "https://webhook.site/your-uuid-here",
  "executionMode": "OnEnd"
}

Response contains the new webhook's id. Save it if you want to delete it later.

Example: delete a webhook

DELETE {{EDGE_ADMIN_ENDPOINT}}/webhooks/{id}
Authorization: Bearer {{edge_admin_token}}

Edge webhooks vs cm webhooks

One of the most confusing points in Sitecore. There are two completely different webhook systems:

 Sitecore CM webhooksEdge webhooks
Where storedItems in CM tree (/sitecore/system/Webhooks/…)Edge platform
What triggers themCM events (item saved, workflow transition)Edge events (content published, cache cleared)
Managed bySitecore CM UIEdge Admin REST API
TemplateWebhook Event Handler(Edge-native, no template)

If you see webhooks in Content Editor under /sitecore/system/Webhooks/ but GET /webhooks on the Edge Admin API returns [], that's not a bug. They're separate systems.

API 4 (reference): Edge Token

Role: Programmatically manage the sc_apikey values used by the Delivery API.

Endpoint: https://edge.sitecorecloud.io/api/apikey/v1

Protocol: REST

Auth: OAuth Bearer (same Edge administration credential as Admin API, edge.tokens:* scopes are included)

Typical operations

MethodPathPurpose
POST/tokensCreate a new delivery API key
GET/tokensList all delivery keys
< />< code="" /> < />/tokens/{id}Get one
DELETE/tokens/{id}Revoke a key

Why it exists separately

The Admin API does not create sc_apikey values, even though you'd expect it to given the edge.tokens:* scopes on the Edge admin credential. Sitecore split these into two APIs:

  • Admin API — manages Edge infrastructure (cache, settings, webhooks)
  • Token API — manages Delivery API keys (long-lived keys your website uses)

Both share the same OAuth credential and token. Just different base URLs.

Docs: https://doc.sitecore.com/sai/en/developers/sitecoreai/token-api.html

Gotchas that waste time

These are the specific traps that cost real hours during implementation:

1. The "two credentials for authoring and management" myth

Old blog posts and tutorials say you need separate SITECORE_CLIENT_ID and SITECORE_MANAGEMENT_CLIENT_ID env vars, implying two OAuth credentials. You don't. One Automation credential handles both. The split is historical, not technical. Save yourself the env-var noise.

2. Display name vs __Display Name

What Content Editor shows as "Display name" has the internal field name __Display Name (double underscore, capital N). All Sitecore system fields use the __ prefix. Passing the display label to GraphQL won't work.

3. ItemFieldInput type mismatch on updateItem

This mutation signature looks correct but fails with "value type does not match field type":

mutation UpdateItem($itemId: ID!, $fields: [ItemFieldInput!]!) {
  updateItem(input: { itemId: $itemId, fields: $fields }) {}
}

The fix is to inline the fields array and only parameterize values:

mutation UpdateItem($itemId: ID!, $value: String!) {
  updateItem(input: {
    itemId: $itemId,
    fields: [{ name: "__Display Name", value: $value }]
  }) { item { itemId name } }
}

4. Tenant id in the JWT token

The access_token returned from OAuth contains a tenant_id claim (a UUID) and sometimes a human-readable tenant name. Decode the token on jwt.io if you need to verify which environment the credential is bound to, as the portal's credentials list doesn't show this.

Example from a real Edge admin token:

"https://auth.sitecorecloud.io/claims/tenant_id": "820303df-29b7-4a38-182d-08dce89597b5"

Cross-reference this UUID against your environment's Details page in the portal.

5. Project display name vs hostname slug

The Sitecore portal shows a friendly project name like "Tidal Accelerator / dev" but the actual hostname slug can include legacy names like navigatoracc468:

xmc-fishtankcon7604-navigatoracc468-dev2cbf.sitecorecloud.io

When debugging, trust the Environment host name on the Details tab, not the project display name. This bit me when Edge webhook responses returned tenantId: fishtankcon7604-navigatoracc468-… and I thought I was in the wrong environment. I wasn't.

6. Token caching

Tokens expire (typically 24 hours for Edge admin, less for Automation). Hitting the OAuth endpoint on every request will rate-limit you. Cache the token and refresh with a 5-minute buffer before expiry:

if (cachedToken && cachedToken.expiresAt > Date.now()) {
  return cachedToken.value;
}
// ...refresh
cachedToken = {
  value: newToken,
  expiresAt: Date.now() + (expires_in - 300) * 1000, // 5 min buffer
};

7. GUID format for itemid

Sitecore GraphQL expects GUIDs with braces and hyphens:

❌ 110EC58AA0F24AC48393C866D813B8D1
✅ {110EC58A-A0F2-4AC4-8393-C866D813B8D1}

Strip all braces/hyphens/spaces from the input and reformat to the canonical shape before sending.

8. Environment dropdown not selected in Postman

If your variables show as orange/red in the URL bar and never resolve, check the top-right of Postman. The environment dropdown must be explicitly selected. "No environment" is the default and is the silent killer of Postman debugging sessions.

Credential-to-API cheat sheet

One table to rule them all:

What you want to doCredentialScope on tokenEndpointAuth header
Read content on your siteEdge delivery key(key, no scope)/sitecore/api/graph/edgesc_apikey: {key}
Create / edit contentAutomationxmcloud.cm:admin/sitecore/api/authoring/graphql/v1Authorization: Bearer {token}
Advance a workflowAutomation (same)xmcloud.cm:admin/sitecore/api/authoring/graphql/v1Authorization: Bearer {token}
Query / search CMAutomation (same)xmcloud.cm:admin/sitecore/api/authoring/graphql/v1Authorization: Bearer {token}
Clear CDN cacheEdge administrationedge.caches:clear/api/admin/v1/cacheAuthorization: Bearer {token}
Manage webhooksEdge administrationedge.webhooks:/api/admin/v1/webhooksAuthorization: Bearer {token}
Manage Edge settingsEdge administrationedge.settings:/api/admin/v1/settingsAuthorization: Bearer {token}
Create delivery API keyEdge administrationedge.tokens:create/api/apikey/v1/tokensAuthorization: Bearer {token}

Credentials needed to cover the whole surface:

  1. One Edge delivery key (sc_apikey — a string)
  2. One Automation credential (for everything CM-side)
  3. One Edge administration credential (for both Admin and Token APIs)

Three credentials, full API coverage. That's it.

Pre-flight checklist

Use this the first time you wire up a new environment:

  • [ ] Automation credential created in portal — copy client_id + client_secret
  • [ ] Edge administration credential created in portal — copy client_id + client_secret
  • [ ] Edge delivery key obtained (from CM or Token API)
  • [ ] Postman environment created with all variables filled
  • [ ] Environment dropdown activated in Postman (top-right)
  • [ ] POST /oauth/token (Automation) returns 200 and saves token
  • [ ] POST /oauth/token (Edge admin) returns 200 and saves token
  • [ ] Decode Edge admin token on jwt.io — verify tenant_id matches target environment
  • [ ] GET /sitecore/api/graph/edge with a simple query returns content
  • [ ] POST /sitecore/api/authoring/graphql/v1 with a simple mutation succeeds
  • [ ] DELETE /api/admin/v1/cache returns 202 Accepted

If all pass, you have working access to every API on the platform.

Final thoughts on SitecoreAI APIs

SitecoreAI's API surface is more cohesive than it first appears. Once you accept three facts (Authoring and Management are one API, the credential type determines the scope, and Experience Edge has three sibling APIs sharing one admin credential) everything clicks. The confusion comes from naming inconsistencies in docs and UI labels, not from genuine architectural complexity.

The patterns presented here have been battle-tested against live SitecoreAI instances running workflow automation, content approvals across multiple sites, and bulk content updates. If you're building any programmatic integration with SitecoreAI, start with this guide, make Postman your friend, and decode every token you get your hands on.

Related resources