Starting an Export from within Your App
If your app needs to initiate an export as part of your own functionality or in events specific to your app, you can use the macro-based integration as an alternative to the exporter’s REST API.
Use the REST API, if a dedicated Confluence user account should be used for the exports
Use the macro-based integration, if your app impersonates any Confluence user and needs to perform an export in the scope of that user
Getting Started
To use the macro based approach:
Your app sends a storage format fragment with a macro containing export instructions to Confluence
Confluence then asks the Scroll Exporter macro endpoint to render the macro
Upon rendering the macro, Scroll Exporter initiates an export and reports the export job ID as macro output to Confluence, which includes it in the render output returned back to your app
Your app uses the same mechanism to poll the export job’s status (repeatedly), until the job finished and a download URL is available
Your app fetches the exported file via the download URL
All render requests your app makes to Confluence must include a user-impersonating access token.
Connect apps require the ACT_AS_USER
scope to do so.
See https://developer.atlassian.com/cloud/confluence/user-impersonation-for-connect-apps for further details.
Export Macro
The export macro is provided by the Scroll Exporter app but remains hidden from the Confluence editor because it is not intended for use on Confluence pages.
Macro Parameters
When sending export and status requests, you need to prepare storage format containing the macro:
<ac:structured-macro ac:name="scroll-pdf-export-job">
<ac:parameter ac:name="issued-at">1728403475</ac:parameter>
<ac:parameter ac:name="issued-by-app">My custom app</ac:parameter>
<ac:parameter ac:name="export-request"><![CDATA[{"pageId": "1376263", "templateId": "d6d04ab9-53c0-42d9-9ae2-f4903275f654"}]]></ac:parameter>
<ac:parameter ac:name="export-job-id">0f517c20-3e5d-42c0-8021-0cb5e2c168ea</ac:parameter>
</ac:structured-macro>
issued-at
- Set this to the current time in UNIX epoch seconds, for example1728403475
for2024-10-08T16:04:35Z
This is to prevent unintended exports if the macro ends up on a Confluence page.
We allow a leeway of 10 seconds here, so make sure the clock on your server is synchronized and there’s not too much delay between taking the timestamp and sending the request.
issued-by-app
- Specify your app’s name as set in Atlassian Marketplace here. We use this to keep track of other apps using this endpoint.export-request
- A JSON representation of the export configuration.When specified, the macro performs the ‘Start Export’ operation as described in the OpenAPI specs of the REST API docs. The macro output corresponds to that operation’s response value.
The value may be included in a
<[CDATA[ ... ]]>
tag.
export-job-id
- The ID of the export job retrieved when starting the export.When specified, the macro performs the ‘Get Export Status’ operation as described in the OpenAPI specs of the REST API docs. The macro output corresponds to that operation’s response value.
Not all parameters are required in each step. See below for details.
Macro Operation Modes
The set of supplied macro parameters decide what operation the macro invokes: Starting a new export, or reporting the status of an existing export job.
The macro will output some wrapper HTML containing HTML-escaped JSON structures. The wrapper HTML is required to prevent Confluence from modifying the JSON content. The JSON structures correspond to the responses of the export REST APIs.
‘Start Export’ Mode
Storage Format with required parameters:
<ac:structured-macro ac:name="scroll-pdf-export-job">
<ac:parameter ac:name="issued-at">1728403475</ac:parameter>
<ac:parameter ac:name="issued-by-app">My custom app</ac:parameter>
<ac:parameter ac:name="export-request"><![CDATA[{"pageId": "1376263", "templateId": "d6d04ab9-53c0-42d9-9ae2-f4903275f654"}]]></ac:parameter>
</ac:structured-macro>
Macro Output:
<div class="result">
<code class="success">{"jobId":"0f517c20-3e5d-42c0-8021-0cb5e2c168ea"}</code>
</div>
Use the export job ID for retrieving the export job status.
‘Get Export Status’ Mode
Storage Format with required parameters:
<ac:structured-macro ac:name="scroll-pdf-export-job">
<ac:parameter ac:name="issued-at">1728403475</ac:parameter>
<ac:parameter ac:name="export-job-id">0f517c20-3e5d-42c0-8021-0cb5e2c168ea</ac:parameter>
</ac:structured-macro>
Macro Output:
<div class="result">
<code class="success">{"status":"complete","step":3,"totalSteps":3,"stepProgress":100,"downloadUrl":"https://scroll-pdf.us.exporter.k15t.app/download/Demo-v1-20241008_172721.pdf?jwt=..."}</code>
</div>
Error Handling
If the macro is used with invalid parameters, it will output an HTML wrapper with a JSON structure containing error details.
<div class="result">
<code class="error">{"status": 400,"message": "Must set 'issued-at' parameter to current time as Unix Epoch seconds."}</code>
</div>
The code
element now has an error
class instead of success
, and the JSON structure corresponds to the error objects produced by the REST API.
Examples
The examples below are IntelliJ HTTP snippets. Substitute these variables:
{{baseUrl}}
- The base URL of the Confluence instance{{token}}
- A user impersonation token for the user in the context of which the export will be performedthe values of other macro parameters as required
Step 1: Starting an export
Request
### Call export macro: new export request (this is an IntelliJ HTTP snippet, see https://www.jetbrains.com/help/idea/http-client-in-product-code-editor.html)
POST {{baseUrl}}/rest/api/contentbody/convert/export_view
Content-Type: application/json
Authorization: Bearer {{token}}
{
"value": "<ac:structured-macro ac:name=\"scroll-pdf-export-job\"><ac:parameter ac:name=\"issued-at\">{{$timestamp}}</ac:parameter><ac:parameter ac:name=\"issued-by-app\">My App</ac:parameter><ac:parameter ac:name=\"export-request\"><![CDATA[{\"pageId\": \"1376263\", \"scope\": \"current\", \"templateId\": \"d6d04ab9-53c0-42d9-9ae2-f4903275f654\", \"versionId\": \"\", \"variantId\": \"\", \"languageKey\": \"\", \"locale\": \"en-US\", \"timeZone\": \"Europe/Berlin\"}]]></ac:parameter></ac:structured-macro>",
"representation": "storage"
}
Response
The response received from Confluence contains a JSON object as follows:
{
"value": "<div class=\"result\"><code class=\"success\">{"jobId":"0f517c20-3e5d-42c0-8021-0cb5e2c168ea"}</code></div>",
"representation": "export_view",
...
}
Use the extracted ID to request status updates in the next step
Step 2: Polling Export Job Status
Request
### Call export macro: poll status (this is an IntelliJ HTTP snippet, see https://www.jetbrains.com/help/idea/http-client-in-product-code-editor.html)
POST {{baseUrl}}/rest/api/contentbody/convert/export_view
Content-Type: application/json
Authorization: Bearer {{token}}
{
"value": "<ac:structured-macro ac:name=\"scroll-pdf-export-job\"><ac:parameter ac:name=\"issued-at\">{{$timestamp}}</ac:parameter><ac:parameter ac:name=\"export-job-id\">{{$exportJobId}}</ac:parameter></ac:structured-macro>",
"representation": "storage"
}
Response
The response received from Confluence contains a JSON object as follows:
{
"value": "<div class=\"result\"><code class=\"success\">{"status":"complete","step":3,"totalSteps":3,"stepProgress":100,"downloadUrl":"https://scroll-pdf.us.exporter.k15t.app/download/Demo-v1-20241008_172721.pdf?jwt=..."}</code></div>",
"representation": "export_view",
...
}
Repeat polling until status
is either complete
, error
or cancelled
, then extract the value of downloadUrl
if available. See the REST API docs for more information on the properties.
Step 3: Download the Exported File
Simply perform a download from downloadUrl
.
Do not send any Authorization
headers. The URL contains the necessary authentication token as a query parameter.