# How to resolve Referenced Images # [#](#supporting-the-referenced-image-macro-in-your-app)Supporting the Referenced Image macro in your app Capable for Confluence and Capable Images for Confluence support the **Referenced image** macro, letting you include one image on multiple pages and update it once to reflect everywhere. This suits documentation and knowledge bases well. This page explains how to read a Referenced image macro and pull the underlying image, the same way Capable Sites does it during a site export. ## [#](#step-1-get-the-macro-config-out-of-the-adf)Step 1: Get the macro config out of the ADF The macro is a Forge extension node in the ADF of a Confluence page. Its config lives under `attrs.parameters`: ``` { "type": "extension", "attrs": { "extensionKey": "//static/-cf-mc-imgref", "parameters": { "guestParams": { "imageId": "cc-12345678", "imageTitle": "Product logo", "aspectRatio": "16:9", "alignment": "center", "showCaption": true } } } } ``` Depending on the app, the extension key differs: ``` # Capable for Confluence App ID - 940ba09e-2961-4460-b5d2-92bc1d4754e8 Env ID - a4748ec2-e494-4e79-8df6-4bef5e1e06a3 Macro ID - njyzjq-cf-mc-imgref # Capable Images for Confluence App ID - d8793129-11a0-4c18-95d6-1a929675d702 Env ID - 2d326cd8-28a0-408d-9d0e-c55ae8fffd4f Macro ID - mmving-cf-mc-imgref ``` Find pages containing the macro with CQL: ``` macro = "njyzjq-cf-mc-imgref" OR macro = "mmving-cf-mc-imgref" ``` ## [#](#step-2-fetch-the-referenced-image-asset)Step 2: Fetch the Referenced Image asset `imageId` is the id of a Confluence **custom-content** entity. Fetch it with `body-format=raw`; the raw body is a JSON string describing the asset. ``` GET /wiki/api/v2/custom-content/{imageId}?body-format=raw Accept: application/json ``` ``` const cc = await res.json(); const body = JSON.parse(cc.body.raw.value); // the record described below ``` The parsed body is the stored asset record. The image payload is nested under `data` (a tagged union on `data.type`), and thumbnail fields sit at the top level: ``` { "title": "Product logo", // caption fallback "data": { "type": "attachment", "attachment": { "id": "att-998877", // attachment id — child of the custom-content entity "title": "product-logo.png", "extension": "png", "version": 3, "checksum": "a1b2c3d4" // changes when the image is replaced }, "url": "..." // optional pre-computed URL (browser-session only — see note) }, "thumbnailId": "att-112233", // low-res fallback attachment "thumbnailExtension": "png" } ``` ## [#](#step-3-download-the-image)Step 3: Download the image Download the **full-resolution attachment** by its id from the **custom-content container**, using the Confluence REST child-attachment endpoint: ``` GET /wiki/rest/api/content/{imageId}/child/attachment/{data.attachment.id}/download ``` * `{imageId}` — the custom-content id (the container the attachment is a child of). * `{data.attachment.id}` — the `att-xxx` attachment id from Step 2. Fetch it with **app authentication** (Forge `principal: 'app'`). > **Do not use** `/wiki/download/attachments/{imageId}/{filename}` **for server-side fetches.** That public download URL (and the v2 `_links.download` link) returns `401 "scope does not match"` for app-scoped Forge fetch. The `/child/attachment/{id}/download` REST path is the one that works for app auth. The `data.url` field and the `/wiki/download/...` form only resolve inside an authenticated end-user browser session (e.g. an `` tag), not from your backend. ### [#](#thumbnail-fallback)Thumbnail fallback If `data.attachment.id` is missing, or the full-res download fails, fall back to the thumbnail — same container, `thumbnailId` as the attachment, `thumbnailExtension` for the file extension: ``` GET /wiki/rest/api/content/{imageId}/child/attachment/{thumbnailId}/download ``` ### [#](#if-you-only-have-the-attachment-id-no-container)If you only have the attachment id (no container) Resolve the container first, then download: ``` GET /wiki/api/v2/attachments/{attachmentId} ```