Message API/docs/components/batch-export/download

Batch Download

POST multiple export identifiers and receive either one zip file or a JSON list of exported URLs.

Endpoint

This route resolves multiple exports and returns either one zip file or a URL list.

  • Method: `POST`
  • Path: `/viewer/exports/download-batch`
  • Content-Type: `application/json`
  • Auth header: `x-api-key: CLIENT_API_KEY` when the backend protects export routes. If you need to issue or manage that client key, see API Key Management Overview.
  • Base URL example: `https://db-backend-domain/api`

Prerequisite

Protected backend download routes require a valid client API key in `x-api-key` before batch requests will succeed.

Request Body

Send an `items` array. Each item should contain `sourceFileUrl`.

Request example

{
  "items": [
    { "sourceFileUrl": "https://example.com/original-1.pdf" },
    { "sourceFileUrl": "https://example.com/original-2.pdf" },
    { "sourceFileUrl": "https://example.com/original-3.pdf" }
  ]
}

Route Examples

Call the same batch route in one of two ways depending on the response you need.

Without responseType

POST https://db-backend-domain/api/viewer/exports/download-batch

With responseType=urls

POST https://db-backend-domain/api/viewer/exports/download-batch?responseType=urls

Response Modes

The route supports one binary mode and one JSON mode.

  • Default: backend returns one zip file stream.
  • URL mode: `POST /viewer/exports/download-batch?responseType=urls` returns JSON.
  • URL response shape: `{ "success": true, "exportedUrls": ["https://..."], "skipped": [...] }`
  • Zip naming: duplicate filenames are made unique by the backend inside the zip.

Frontend Handling

The frontend should choose its parsing logic before sending the request.

  • Default mode: read the response as a blob and trigger one zip download.
  • URL mode: read the response as JSON.
  • Filename source: prefer `Content-Disposition` from the backend.
  • Fallback zip name: `canvas-exports.zip` only when the header is missing.

Client Example

Use separate client examples for the default zip response and the URL-only response.

Without responseType

async function downloadBatchExports(items) {
  const response = await fetch('https://db-backend-domain/api/viewer/exports/download-batch', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'x-api-key': CLIENT_API_KEY,
    },
    body: JSON.stringify({ items }),
  });

  if (!response.ok) {
    throw new Error(`Batch export failed with status ${response.status}.`);
  }

  const blob = await response.blob();
  const header = response.headers.get('content-disposition');
  const match = header?.match(/filename\*?=(?:UTF-8''|")?([^;"]+)/i);
  const fileName = match?.[1] ? decodeURIComponent(match[1]) : 'canvas-exports.zip';
  const objectUrl = URL.createObjectURL(blob);

  try {
    const anchor = document.createElement('a');
    anchor.href = objectUrl;
    anchor.download = fileName;
    document.body.appendChild(anchor);
    anchor.click();
    anchor.remove();
  } finally {
    URL.revokeObjectURL(objectUrl);
  }
}

With responseType=urls

async function fetchBatchExportUrls(items) {
  const response = await fetch(
    'https://db-backend-domain/api/viewer/exports/download-batch?responseType=urls',
    {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'x-api-key': CLIENT_API_KEY,
      },
      body: JSON.stringify({ items }),
    },
  );

  if (!response.ok) {
    throw new Error(`Batch export URL request failed with status ${response.status}.`);
  }

  return response.json();
}

Recommended Flow

Keep export registration and export download as separate steps in the application flow.

  • 11. Register exports first in your normal export flow.
  • 22. Store `sourceFileUrl` values in app state.
  • 33. Load the client API key before calling protected download routes.
  • 44. Build the batch payload only when the user requests download.
  • 55. Choose response mode based on whether the UI needs a zip file or URL data.
  • 66. Surface status clearly for `400`, `401/403`, `404`, and backend failures.