Extract text from Confluence

A download link Atlassian never promises will work without your credentials. Here's how a document actually gets from Confluence to a txtfetch response.

The problem

Confluence's v2 API returns an attachment's downloadLink alongside its metadata. Atlassian never documents that link as pre-authenticated, unlike Microsoft Graph's download URL. Absent that promise, assume the link wants your credentials. Fetch the bytes yourself and send those to txtfetch.

POST the bytes, and why

How Confluence fits the decision table, cited and dated
Pre-authenticated URL?No — none is documented
txtfetch pathPOST the bytes
Link lifetimeNot documented, and not a signed expiry
The trapThe download path has already moved once, from the v1 _links.download field to v2's downloadLink. Check the current API reference before you depend on either.

Atlassian documents no pre-authenticated download URL for an attachment. Microsoft and Dropbox both promise one in writing; Confluence does not, so treat the link as needing your credentials and POST the bytes.

How it works

Request the attachment with GET /wiki/api/v2/attachments/{id} and your own API token. Read downloadLink from the response. Confluence Cloud returns it as a relative path today, so resolve it against your site's /wiki base. Fetch it with the same token, then POST the bytes to txtfetch as a normal file upload.

the script

A plain HTTP call against Confluence's own REST API, then a plain call to txtfetch. No vendor SDK either side.

Python
import os

import requests

BASE_URL = "https://your-domain.atlassian.net/wiki"
ATTACHMENT_ID = "att123456789"
auth = (os.environ["CONFLUENCE_EMAIL"], os.environ["CONFLUENCE_API_TOKEN"])

attachment = requests.get(f"{BASE_URL}/api/v2/attachments/{ATTACHMENT_ID}", auth=auth)
attachment.raise_for_status()
download_link = attachment.json()["downloadLink"]

# Confluence Cloud returns downloadLink as a relative path today. Resolve it
# against the /wiki base, and pass it through if it ever arrives absolute.
file_url = download_link if download_link.startswith("http") else f"{BASE_URL}{download_link}"

file_res = requests.get(file_url, auth=auth)
file_res.raise_for_status()

r = requests.post(
    "https://api.txtfetch.com/v1/extract",
    headers={"Authorization": f"Bearer {os.environ['TXTFETCH_KEY']}"},
    files={"file": (attachment.json()["title"], file_res.content)},
)

print(r.json()["extracted_text"])
JavaScript
const baseUrl = "https://your-domain.atlassian.net/wiki";
const attachmentId = "att123456789";
const auth = "Basic " + Buffer.from(`${process.env.CONFLUENCE_EMAIL}:${process.env.CONFLUENCE_API_TOKEN}`).toString("base64");

const attachmentRes = await fetch(`${baseUrl}/api/v2/attachments/${attachmentId}`, {
  headers: { Authorization: auth },
});
const { title, downloadLink } = await attachmentRes.json();

// Confluence Cloud returns downloadLink as a relative path today. Resolve it
// against the /wiki base, and pass it through if it ever arrives absolute.
const fileUrl = downloadLink.startsWith("http") ? downloadLink : `${baseUrl}${downloadLink}`;

const fileRes = await fetch(fileUrl, { headers: { Authorization: auth } });
const bytes = await fileRes.arrayBuffer();

const form = new FormData();
form.append("file", new Blob([bytes]), title);

const res = await fetch("https://api.txtfetch.com/v1/extract", {
  method: "POST",
  headers: { Authorization: `Bearer ${process.env.TXTFETCH_KEY}` },
  body: form,
});

const { extracted_text } = await res.json();
console.log(extracted_text);

txtfetch ships no connector, plugin, or client for Confluence. The script above is the whole integration. Fetch the document with Confluence's own API, then hand it to txtfetch, the same as any other source of text.

frequently asked questions

Does txtfetch have a Confluence connector?
No. txtfetch ships no Confluence connector. Fetch the attachment yourself with your own API token, then POST the bytes to txtfetch.
Can I pass downloadLink straight to ?url=?
Don't rely on it. Atlassian documents no pre-authenticated download URL for an attachment, so the link may well want your credentials. txtfetch's fetch carries none, and it sends no Authorization header.
Why does this spoke hedge where the others don't?
Microsoft and Dropbox both document their link's auth behaviour and lifetime. Atlassian documents neither, and the download path already changed between v1 and v2. POSTing the bytes works no matter how that settles.

Related

Point it at your Confluence files.

Pass a signed URL and the text comes back. There is no connector to install.

Get an API key →

See the URL docs →