Skip to main content

Tutorial5 min

Retrieve a report

The feed and search return metadata only. Fetch a report by id to get its Markdown body and images.
API reference
Endpoint
GET /reports/{id}
Auth
X-API-Key
Path
id
Returns
200 { …, body, imageUrls }

Before you start​

  1. A Core API base URL

    Pick the environment you are building against. Base URLs has the details.

    • ProductionProvided at onboardingMutual TLS required
    • Sandboxhttps://staging-api.emergentriskinternational.com/api/v1Same contract as production
    • Localhttp://127.0.0.1:3001/api/v1apps/backend on your machine
  2. An API Key

    Organization-scoped, sent in the X-API-Key header and issued by ERI support. See Authentication.

  3. A report id

    Any id from the feed or a search.

  1. 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.
    Terminal
    export 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 "$CORE_API_BASE_URL/reports/01a04100-0000-7000-8000-000000000004" \
    -H "X-API-Key: $ERI_API_KEY"
    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"]
    }
  2. 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.

    from pathlib import Path

    folder = 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)
  3. Step 3: Handle the response​

    Errors share one JSON envelope with a stable code to 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.