Skip to main content
GET
/
v1
/
documents
/
{doc_id}
/
download
Download Document (Direct)
curl --request GET \
  --url https://api.agentoffice.dev/v1/documents/{doc_id}/download \
  --header 'Authorization: Bearer <token>'
{
  "detail": "File not found"
}

Download Document Directly

Get the document file directly as a binary response, eliminating the two-step presigned URL process. This endpoint is ideal for programmatic downloads and reduces latency. Supports both Word (.docx) and PDF (.pdf) formats.

Path Parameters

doc_id
string
required
The unique identifier of the document to download (UUID)

Response

Returns the document file directly with appropriate headers:
  • Content-Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document (for .docx) or application/pdf (for .pdf)
  • Content-Disposition: attachment; filename="your-document.docx" (or .pdf)

Code Examples

const docId = "a1b2c3d4-e5f6-7890-abcd-ef1234567890";

const response = await fetch(
  `https://api.agentoffice.dev/v1/documents/${docId}/download`,
  {
    headers: {
      Authorization: "Bearer YOUR_API_KEY",
    },
  }
);

// Get filename from Content-Disposition header
const contentDisposition = response.headers.get("Content-Disposition");
let filename = "document.docx";
if (contentDisposition) {
  const match = contentDisposition.match(/filename="?(.+?)"?$/);
  if (match) filename = match[1];
}

// Convert to blob and trigger download
const blob = await response.blob();
const url = window.URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = filename;
a.click();
window.URL.revokeObjectURL(url);

Benefits over Presigned URL Method

Reduced Latency

One request instead of two - no intermediate S3 URL step

Simpler Code

Fewer lines of code, cleaner implementation

Better for APIs

Perfect for server-to-server communication

Same Features

Supports tracked changes and all document features

Complete Workflow Example

Here’s a complete example showing upload, edit, and direct download:
import { v4 as uuidv4 } from "uuid";

const API_KEY = "YOUR_API_KEY";
const BASE_URL = "https://api.agentoffice.dev";

async function processDocument(file) {
  // 1. Upload document
  const formData = new FormData();
  formData.append("file", file);

  const uploadResponse = await fetch(`${BASE_URL}/v1/documents/`, {
    method: "POST",
    headers: { Authorization: `Bearer ${API_KEY}` },
    body: formData,
  });

  const { docId } = await uploadResponse.json();
  console.log("Uploaded document:", docId);

  // 2. Apply edit
  const editResponse = await fetch(`${BASE_URL}/v1/documents/${docId}/edits`, {
    method: "POST",
    headers: {
      Authorization: `Bearer ${API_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      editUid: uuidv4(),
      editInstructions: "Update all dates to 2024",
    }),
  });

  const editResult = await editResponse.json();
  console.log("Edit applied:", editResult.editApplied);

  // 3. Download edited document directly
  const downloadResponse = await fetch(
    `${BASE_URL}/v1/documents/${docId}/download`,
    {
      headers: { Authorization: `Bearer ${API_KEY}` },
    }
  );

  // Get filename from header
  const contentDisposition = downloadResponse.headers.get(
    "Content-Disposition"
  );
  let filename = "document.docx";
  if (contentDisposition) {
    const match = contentDisposition.match(/filename="?(.+?)"?$/);
    if (match) filename = match[1];
  }

  // Download the file
  const blob = await downloadResponse.blob();

  // Trigger browser download
  const url = window.URL.createObjectURL(blob);
  const a = document.createElement("a");
  a.href = url;
  a.download = filename;
  a.click();
  window.URL.revokeObjectURL(url);

  console.log("Downloaded:", filename);
}

Comparison: Direct vs Presigned URL

FeatureDirect Download (/download)Presigned URL (GET /{doc_id})
Number of Requests1 request2 requests (get URL, then download)
LatencyLower - single round tripHigher - two round trips
Use CaseProgrammatic/API usageClient-side downloads, sharing links
URL ExpirationN/A - direct downloadConfigurable (1 second - 24 hours)
SecurityAPI key required for each downloadAnyone with URL can download (until expiration)
Tracked Changes✅ Supported✅ Supported
Best ForServer-to-server, automated workflowsTemporary sharing, client downloads

When to Use Each Method

  • Building server-to-server integrations
  • Automating document processing workflows
  • You need the lowest possible latency
  • You want tighter security control (API key per request)
  • Processing documents in CI/CD pipelines
  • Sharing documents with users without API access
  • You need temporary, expiring download links
  • Building client-side applications with limited backend
  • You want to offload download traffic from your API
  • Implementing time-limited document sharing

Tracked Changes Support

Both download methods support tracked changes. If you enabled tracked_changes when uploading the document, the downloaded file will show all edits with Word’s track changes feature.
Example with tracked changes
// Upload with tracked changes enabled
const formData = new FormData();
formData.append("file", file);
formData.append("tracked_changes", "true");
formData.append("author_name", "Your Name");

const { docId } = await (
  await fetch(`${BASE_URL}/v1/documents/`, {
    method: "POST",
    headers: { Authorization: `Bearer ${API_KEY}` },
    body: formData,
  })
).json();

// ... make edits ...

// Download shows tracked changes
const response = await fetch(`${BASE_URL}/v1/documents/${docId}/download`, {
  headers: { Authorization: `Bearer ${API_KEY}` },
});

Error Responses

{
  "detail": "File not found"
}
For best performance in production, use the direct download endpoint for automated workflows and server-to-server communication.