> ## Documentation Index
> Fetch the complete documentation index at: https://docs.agentoffice.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Download Document

> Get a presigned URL to download your edited document

## Download a Document

Retrieve a presigned S3 URL to download your document. The URL is temporary and secure, expiring after the specified duration.

### Path Parameters

<ParamField path="doc_id" type="string" required>
  The unique identifier of the document to download (UUID)
</ParamField>

### Query Parameters

<ParamField query="expiresIn" type="integer">
  Number of seconds until the download URL expires (1-86400). Default is 3600 (1
  hour).
</ParamField>

### Response

<ResponseField name="docId" type="string" required>
  UUID of the document
</ResponseField>

<ResponseField name="downloadUrl" type="string" required>
  Presigned S3 URL for downloading the document
</ResponseField>

<ResponseField name="expiresIn" type="integer" required>
  Number of seconds until the URL expires
</ResponseField>

<ResponseField name="filename" type="string" required>
  Original filename of the document
</ResponseField>

### Code Examples

<CodeGroup>
  ```javascript JavaScript (Fetch) theme={null}
  const docId = "a1b2c3d4-e5f6-7890-abcd-ef1234567890";

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

  const data = await response.json();

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

  // Create download link
  const url = window.URL.createObjectURL(blob);
  const a = document.createElement("a");
  a.href = url;
  a.download = data.filename;
  a.click();
  ```

  ```python Python (Requests) theme={null}
  import requests

  doc_id = 'a1b2c3d4-e5f6-7890-abcd-ef1234567890'
  url = f'https://api.agentoffice.dev/v1/documents/{doc_id}'

  headers = {
      'Authorization': 'Bearer YOUR_API_KEY'
  }

  params = {
      'expiresIn': 3600
  }

  response = requests.get(url, headers=headers, params=params)
  data = response.json()

  # Download the file
  download_response = requests.get(data['downloadUrl'])

  # Save to disk
  with open(data['filename'], 'wb') as f:
      f.write(download_response.content)

  print(f"Downloaded: {data['filename']}")
  ```

  ```python Python SDK theme={null}
  from agent_office import AgentOffice
  import requests
  import os

  client = AgentOffice(api_key=os.getenv('AGENT_OFFICE_API_KEY'))

  doc_id = "a1b2c3d4-e5f6-7890-abcd-ef1234567890"

  result = client.documents.download(
      doc_id=doc_id,
      expires_in=3600
  )

  # Download the file
  download_response = requests.get(result.download_url)

  # Save to disk
  with open(result.filename, 'wb') as f:
      f.write(download_response.content)

  print(f"Downloaded: {result.filename}")
  ```

  ```javascript Node.js with fs theme={null}
  import fs from "fs";

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

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

  const data = await response.json();

  // Download and save the file
  const downloadResponse = await fetch(data.downloadUrl);
  const buffer = await downloadResponse.arrayBuffer();

  fs.writeFileSync(data.filename, Buffer.from(buffer));
  console.log(`Downloaded: ${data.filename}`);
  ```

  ```bash cURL theme={null}
  curl -X GET 'https://api.agentoffice.dev/v1/documents/a1b2c3d4-e5f6-7890-abcd-ef1234567890?expiresIn=3600' \
    -H 'Authorization: Bearer YOUR_API_KEY'
  ```
</CodeGroup>

### Example Response

```json theme={null}
{
  "docId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "downloadUrl": "https://s3.amazonaws.com/bucket/document.docx?X-Amz-Algorithm=...",
  "expiresIn": 3600,
  "filename": "report.docx"
}
```

## Complete Workflow Example

Here's a complete example showing upload, edit, and download:

<CodeGroup>
  ```javascript JavaScript theme={null}
  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
    const downloadResponse = await fetch(`${BASE_URL}/v1/documents/${docId}`, {
      headers: { Authorization: `Bearer ${API_KEY}` },
    });

    const { downloadUrl, filename } = await downloadResponse.json();

    // Download the file
    const fileResponse = await fetch(downloadUrl);
    const blob = await fileResponse.blob();

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

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

  ```python Python theme={null}
  import requests
  import uuid

  API_KEY = 'YOUR_API_KEY'
  BASE_URL = 'https://api.agentoffice.dev'

  def process_document(file_path):
      headers = {'Authorization': f'Bearer {API_KEY}'}

      # 1. Upload document
      with open(file_path, 'rb') as f:
          files = {'file': f}
          upload_response = requests.post(
              f'{BASE_URL}/v1/documents/',
              headers=headers,
              files=files
          )

      doc_id = upload_response.json()['docId']
      print(f'Uploaded document: {doc_id}')

      # 2. Apply edit
      edit_payload = {
          'editUid': str(uuid.uuid4()),
          'editInstructions': 'Update all dates to 2024'
      }

      edit_response = requests.post(
          f'{BASE_URL}/v1/documents/{doc_id}/edits',
          headers={**headers, 'Content-Type': 'application/json'},
          json=edit_payload
      )

      edit_result = edit_response.json()
      print(f"Edit applied: {edit_result['editApplied']}")

      # 3. Download edited document
      download_response = requests.get(
          f'{BASE_URL}/v1/documents/{doc_id}',
          headers=headers
      )

      download_data = download_response.json()
      download_url = download_data['downloadUrl']
      filename = download_data['filename']

      # Download and save file
      file_response = requests.get(download_url)
      with open(f'edited_{filename}', 'wb') as f:
          f.write(file_response.content)

      print(f'Downloaded: edited_{filename}')

  # Usage
  process_document('document.docx')
  ```
</CodeGroup>

## Presigned URL Security

<Warning>
  The presigned URL allows anyone with the link to download the document. Keep
  URLs private and don't share them publicly.
</Warning>

### URL Expiration

* Presigned URLs expire after the specified duration (default 1 hour)
* You can generate a new URL at any time by calling the endpoint again
* Expired URLs will return a 403 Forbidden error

### Best Practices

<AccordionGroup>
  <Accordion title="Short Expiration Times">
    Use shorter expiration times (e.g., 300 seconds) for sensitive documents
  </Accordion>

  {" "}

  <Accordion title="One-Time Downloads">
    Generate a new URL for each download to maintain security
  </Accordion>

  <Accordion title="Programmatic Downloads">
    Download files programmatically instead of exposing URLs to end users
  </Accordion>
</AccordionGroup>

## Error Responses

<ResponseExample>
  ```json 404 Not Found theme={null}
  {
    "detail": "Document not found or has expired"
  }
  ```

  ```json 403 Forbidden theme={null}
  {
    "detail": "Access denied to this document"
  }
  ```
</ResponseExample>

<Tip>
  Documents are automatically deleted after their TTL expires. Make sure to
  download important documents before they expire.
</Tip>
