Tutorial5 min
Retrieve a report
The feed and search return metadata only. Fetch a report by id to get its Markdown body and images.
- Endpoint
GET /reports/{id}- Auth
X-API-Key- Path
id- Returns
200 { …, body, imageUrls }
Before you start
A Core API base URL
Pick the environment you are building against. Base URLs has the details.
- ProductionProvided at onboardingMutual TLS required
- Sandbox
https://staging-api.emergentriskinternational.com/api/v1Same contract as production - Local
http://127.0.0.1:3001/api/v1apps/backend on your machine
An API Key
Organization-scoped, sent in the
X-API-Keyheader and issued by ERI support. See Authentication.
Step 1: Fetch the report
Request the report by its
id. The response repeats the list fields and adds two:body: the full analysis as a Markdown string.imageUrls: the images the body embeds, often an empty array.
Terminalexport CORE_API_BASE_URL="http://127.0.0.1:3001/api/v1"export ERI_API_KEY="<raw API Key from bootstrap or ERI support>"- cURL
- Python
- Node.js
curl "$CORE_API_BASE_URL/reports/01a04100-0000-7000-8000-000000000004" \-H "X-API-Key: $ERI_API_KEY"import os, requestsreport_id = "01a04100-0000-7000-8000-000000000004"response = requests.get(f"{os.environ['CORE_API_BASE_URL']}/reports/{report_id}",headers={"X-API-Key": os.environ["ERI_API_KEY"]},)report = response.json()const reportId = "01a04100-0000-7000-8000-000000000004";const response = await fetch(`${process.env.CORE_API_BASE_URL}/reports/${reportId}`, {headers: { "X-API-Key": process.env.ERI_API_KEY },});const report = await response.json();200 OK{"id": "01a04100-0000-7000-8000-000000000004","title": "Baltic Corridor - Cyber Threat Bulletin","publicationDate": "2026-08-29T10:53:16.189Z","region": "Europe","reportType": "Rapid Reaction Brief","body": "## Baltic Corridor - Cyber Threat Bulletin\n\n…","imageUrls": [],"regions": ["Europe"],"countries": ["Estonia", "Latvia", "Lithuania"],"topics": ["Cyberthreat"],"sectors": ["Maritime"]}Step 2: Keep the images
Each image URL is pre-signed and expires shortly after the response. Download the images in the same run and store your own copies; a saved URL stops working.
If a URL has expired, fetch the report again for fresh ones.
- Python
- Node.js
from pathlib import Pathfolder = Path("reports") / report["id"]folder.mkdir(parents=True, exist_ok=True)(folder / "body.md").write_text(report["body"])for index, image_url in enumerate(report["imageUrls"]):image = requests.get(image_url)image.raise_for_status()(folder / f"image-{index}").write_bytes(image.content)import { mkdir, writeFile } from "node:fs/promises";const folder = `reports/${report.id}`;await mkdir(folder, { recursive: true });await writeFile(`${folder}/body.md`, report.body);for (const [index, imageUrl] of report.imageUrls.entries()) {const image = await fetch(imageUrl);if (!image.ok) throw new Error(`Image download failed: ${image.status}`);await writeFile(`${folder}/image-${index}`, Buffer.from(await image.arrayBuffer()));}Step 3: Handle the response
Errors share one JSON envelope with a stable
codeto branch on. Pick a status to see the exact body.200OK- When
- The full report: the list fields plus the Markdown body and imageUrls.
- What to do
- Store the body. Download any images now: the URLs are pre-signed and short-lived.
Response body{"id": "01a04100-0000-7000-8000-000000000004","title": "Baltic Corridor - Cyber Threat Bulletin","publicationDate": "2026-08-29T10:53:16.189Z","region": "Europe","reportType": "Rapid Reaction Brief","body": "## Baltic Corridor - Cyber Threat Bulletin\n\n…","imageUrls": [],"regions": ["Europe"],"countries": ["Estonia", "Latvia", "Lithuania"],"topics": ["Cyberthreat"],"sectors": ["Maritime"]}
You have the full report
Body and images are stored on your side, so nothing depends on a URL that expires.