Skip to content

REST API Reference

ApprovalFlow provides a REST API for programmatic access to change sets and page submissions. The API uses Atlassian Forge’s apiRoute mechanism with 3-legged OAuth (3LO) authentication.

All endpoints accept and return JSON.

The API uses Atlassian 3LO OAuth 2.0 to authenticate external callers. You need to create a 3LO integration in the Atlassian Developer Console and configure the required scopes.

Your 3LO integration needs two types of scopes:

Atlassian product scope (required for all Forge app API calls):

ScopePurpose
read:forge-app:confluenceAllows external API access to ApprovalFlow’s Forge endpoints. Without this scope, all API calls will fail.

ApprovalFlow custom scopes (select the app and environment in the Developer Console):

ScopeUsed By
read:change-set:customList change sets, get change set detail, preflight change set
write:change-set:customCreate, update, archive, and submit change sets
read:approval:customPreflight single page
write:approval:customSubmit single page

Important: The read:forge-app:confluence scope is configured under the Atlassian product scopes section of your 3LO integration’s Permissions tab. The custom scopes are configured separately under the app-specific section. Both are required.

Before making API calls:

  1. Enable App REST APIs — A site administrator must enable REST APIs for ApprovalFlow via Atlassian Administration > Connected Apps.
  2. Create a 3LO integration — In the Atlassian Developer Console, create a 3LO integration for your Confluence site with the scopes listed above.
  3. Obtain an access token — Complete the OAuth 2.0 authorization flow (authorization code → token exchange) to get a bearer token.

Include the access token in every request:

Authorization: Bearer <access_token>

The authenticated user’s Atlassian account is resolved automatically from the OAuth token. You do not pass a user ID in the request body.

All API-initiated actions are marked (via API) in the audit trail, with the OAuth client ID recorded for traceability.

Forge app APIs use the following base URL pattern:

https://api.atlassian.com/svc/confluence/<cloud-id>/apps/<app-id>_<env-id>

Alternatively, you can use the site-relative format:

https://<your-site>.atlassian.net/gateway/api/svc/confluence/apps/<app-id>_<env-id>

Where:

  • <cloud-id> — Your Confluence Cloud site ID. Retrieve it from https://<your-site>.atlassian.net/_edge/tenant_info.
  • <app-id> — The ApprovalFlow app ID (available from the Developer Console or your site administrator).
  • <env-id> — The ApprovalFlow environment ID (production or development).

All endpoint paths in this document are relative to the base URL above.

List all change sets in a space with version data and rollup state.

GET /changeSets?spaceId={spaceId}

Required scope: read:change-set:custom

Parameters:

ParameterLocationRequiredDescription
spaceIdQuery or bodyYesThe Confluence space ID.

Response:

{
"success": true,
"changeSets": [
{
"id": "cs-abc123",
"spaceId": "12345",
"title": "PR-184 Auth docs update",
"summary": "Updated authentication pages for new token refresh flow.",
"referenceUrl": "https://github.com/org/repo/pull/184",
"status": "open",
"rollupState": "in_review",
"pageRefs": [...],
"createdAt": "2026-03-27T10:00:00.000Z",
"createdBy": "user-account-id"
}
]
}

Get a single change set with full per-page version enrichment.

GET /changeSets/detail?changeSetId={changeSetId}

Required scope: read:change-set:custom

Parameters:

ParameterLocationRequiredDescription
changeSetIdQueryYesThe change set ID.

Response includes per-page:

  • currentPageVersion — Latest page version in Confluence.
  • approvedAtVersion — Version that was approved (if any).
  • isStale — Whether the page was edited after approval.
  • versionDelta — Number of versions between approved and current.

Create a new change set in a space.

POST /changeSets

Required scope: write:change-set:custom

Request body:

{
"spaceId": "12345",
"title": "PR-184 Auth docs update",
"summary": "Updated authentication pages for new token refresh flow.",
"referenceUrl": "https://github.com/org/repo/pull/184",
"pageRefs": [
{ "pageId": "67890" },
{ "pageId": "67891" }
]
}
FieldRequiredDescription
spaceIdYesThe Confluence space ID.
titleYesChange set title.
summaryNoDescription of the change.
referenceUrlNoExternal URL (e.g., GitHub PR, Jira issue).
pageRefsYesArray of page references with pageId.

Update title, summary, reference URL, or page list of an existing change set.

POST /changeSets/update

Required scope: write:change-set:custom

Request body:

{
"changeSetId": "cs-abc123",
"title": "Updated title",
"summary": "Updated summary",
"referenceUrl": "https://github.com/org/repo/pull/184",
"pageRefs": [
{ "pageId": "67890" },
{ "pageId": "67891" },
{ "pageId": "67892" }
]
}

Archive a completed change set. Archived change sets are read-only.

POST /changeSets/archive

Required scope: write:change-set:custom

Request body:

{
"changeSetId": "cs-abc123"
}

Submit all eligible pages in a change set for approval.

POST /changeSets/submit

Required scope: write:change-set:custom

Request body:

{
"changeSetId": "cs-abc123"
}

Response:

{
"success": true,
"submittedCount": 5,
"skippedCount": 2,
"results": [
{
"pageId": "67890",
"success": true,
"workflowId": "wf-123"
},
{
"pageId": "67893",
"success": false,
"reason": "No workflow assigned to page"
}
]
}

Partial success is allowed. Pages that cannot be submitted are skipped with a reason, while eligible pages proceed normally.

When pages are submitted through a change set, Confluence page comments include the change set title, summary, and a clickable reference URL link.


Submit a single page for approval. Requires that the page already has a workflow assigned.

POST /pages/submit

Required scope: write:approval:custom

Request body:

{
"pageId": "67890"
}

Note: The single-page submit endpoint enforces strict workflow assignment. If the page does not have an explicit workflow assigned and the space has multiple active workflows, the submission is rejected.


Dry-run evaluation of a change set. Checks submission eligibility for all pages without writing any data.

POST /changeSets/preflight

Required scope: read:change-set:custom

Request body:

{
"changeSetId": "cs-abc123"
}

Response:

{
"success": true,
"summary": {
"total": 7,
"submittable": 5,
"blocked": 2
},
"results": [
{
"pageId": "67890",
"canSubmit": true,
"workflowId": "wf-123"
},
{
"pageId": "67893",
"canSubmit": false,
"reason": "Page already has a pending approval"
}
]
}

Use preflight to validate a change set before committing to a bulk submit. This is particularly useful for CI/CD pipelines and automation that need to check eligibility before triggering a review cycle.


Check submission eligibility for a single page.

POST /pages/preflight

Required scope: read:approval:custom

Request body:

{
"pageId": "67890"
}

All endpoints return a consistent error format:

{
"success": false,
"error": "Description of what went wrong"
}

Common HTTP status codes:

CodeMeaning
200Success.
400Bad request — missing or invalid parameters.
403License not active or insufficient OAuth scope.
500Internal server error.

All API actions are recorded in the ApprovalFlow audit trail:

  • Marker: Actions initiated via API are tagged (via API) to distinguish them from UI-initiated actions.
  • OAuth client ID: The OAuth app’s client ID is stored alongside each audit event.
  • Change set context: When pages are submitted through a change set, the audit event includes the change set title, summary, reference URL, submitted count, and skipped count.

Audit records are visible in the Approval Queue and Workflow Analytics tabs, and are included in audit exports.