# How to Download Files via OneDrive API: Microsoft Graph Guide

Downloading a file via the OneDrive API requires requesting the binary stream from a driveItem content endpoint using Microsoft Graph. The API responds with an HTTP 302 redirect pointing to a temporary download URL, offloading binary retrieval from API counters. Production pipelines and agents must manage Entra ID permissions, streaming chunk buffers, and HTTP 429 throttling backoff. This guide covers Graph endpoints, Python scripts, and workspace indexing.

Source: https://fast.io/resources/onedrive-api-download-file/
Author: [Derek Labian](https://fast.io/authors/derek-labian/)
Last reviewed: 2026-10-05

## When to Use Microsoft Graph Endpoints for OneDrive File Downloads

Downloading files directly from OneDrive through Microsoft Graph splits an application's architecture between lightweight metadata queries and heavy binary streams. When a background daemon or autonomous agent issues naive HTTP GET requests across hundreds of files, requests trigger HTTP 429 throttling thresholds, exhaust local runtime memory, or stall when network connections drop midway through a multi-gigabyte transfer.

The OneDrive API allows applications to download files via Microsoft Graph using the GET /me/drive/items/{id}/content endpoint, which returns a 302 Found redirect to a temporary, high-speed download location. Developers and platform engineers building automated pipelines interact with Microsoft Graph (`https://graph.microsoft.com/v1.0/`), the unified API surface for Microsoft 365. Inside Microsoft Graph, personal OneDrive accounts and OneDrive for Business libraries are exposed as `drive` resources, while files and folders are represented as `driveItem` objects.

To retrieve the binary content of a file, an application issues an authenticated GET request to the `/content` path of the target driveItem:

```http
GET https://graph.microsoft.com/v1.0/me/drive/items/{item-id}/content
Authorization: Bearer {token}
```

When Microsoft Graph receives this request, the API gateway does not stream the file bytes directly. Instead, the server returns a 302 Found response redirecting to a preauthenticated download URL for the file, which is the same URL available through the @microsoft.graph.downloadUrl property on the driveItem. The `Location` response header provides a temporary, preauthenticated download URL hosted on Microsoft storage clusters (such as `*.files.1drv.com` for personal accounts or SharePoint storage partitions for business tenants).

### The Mechanics of 302 Redirect URLs

The 302 redirect URL bypasses Graph API rate limit counters for binary retrieval. Because the redirect transfers the high-bandwidth download connection directly to Microsoft's distributed storage nodes, reading multi-gigabyte payloads does not consume the client application's per-minute Microsoft Graph API call quotas.

Short-lived download URLs expire within minutes, requiring just-in-time generation. Because authentication credentials are embedded directly inside the preauthenticated download URL query string, client applications must not send the original Microsoft Entra ID `Authorization: Bearer` header to the download URL. Forwarding bearer tokens to the storage CDN endpoint causes authorization rejections and triggers Cross-Origin Resource Sharing (CORS) preflight failures in browser-based clients.

### Addressing Files Across Different OneDrive Contexts

Microsoft Graph provides flexible addressing schemes depending on whether an application operates in a personal OneDrive account, an enterprise employee drive, or an organization-wide drive collection:

| Target Storage Location | Addressing Path | Primary Use Case |
| :--- | :--- | :--- |
| **Current User Drive** | `/me/drive/items/{item-id}/content` | Interactive user scripts and client tools |
| **Specific User Drive** | `/users/{user-id}/drive/items/{item-id}/content` | Tenant admin daemons and IT audit utilities |
| **Drive by Unique ID** | `/drives/{drive-id}/items/{item-id}/content` | Shared organizational drives and team storage |
| **Path-Based Addressing** | `/me/drive/root:/{path-to-file}:/content` | Scripts where file paths are known in advance |
| **Fast.io Workspace via MCP** | Remote MCP (`https://mcp.fast.io/mcp/tools`) | Agent hybrid semantic search with zero local downloads |

Path-based addressing allows applications to request a file without first querying its unique driveItem ID. The path must be prefixed with `root:/` and suffixed with `:/content`. Path strings with spaces or Unicode glyphs must be URL-encoded (for example, replacing spaces with `%20`).

### Accessing Direct Download URLs Without Redirection

In web browser runtimes, client-side JavaScript applications cannot always follow the default 302 redirect from `/content`. When an HTTP client includes an `Authorization` header on a request that encounters a 302 redirect across domains, browser security standards mandate a CORS preflight check that storage CDN nodes often reject.

To avoid redirect complications, client applications can query the driveItem metadata record and explicitly select the preauthenticated download link:

```http
GET https://graph.microsoft.com/v1.0/me/drive/items/{item-id}?$select=id,name,size,@microsoft.graph.downloadUrl
Authorization: Bearer {token}
```

Microsoft Graph returns a JSON payload containing the direct download URL:

```json
{
  "@odata.context": "https://graph.microsoft.com/v1.0/$metadata#drives('b!...')/items/$entity",
  "id": "01BY276AACD5VKKN7AHFA7A2S42LDO7NRW",
  "name": "quarterly-financial-report.pdf",
  "size": 18452104,
  "@microsoft.graph.downloadUrl": "https://public.sn.files.1drv.com/y4m..."
}
```

The application can fetch the binary content directly from the `@microsoft.graph.downloadUrl` address using standard HTTP GET requests without passing an `Authorization` header. Because the download URL is short-lived and generated on demand, applications should retrieve the property immediately before initiating the transfer.

## How to Configure Microsoft Entra ID Authentication and Permissions

Programmatic access to OneDrive through Microsoft Graph requires an application registered within Microsoft Entra ID (formerly Azure Active Directory). The authentication model determines which permission scopes your client needs and how access tokens are acquired.

Microsoft Entra ID supports two core permission types for file operations:

- **Delegated Permissions**: Used when an application signs in on behalf of an interactive human user. The application can only download files that the signed-in user has permission to view. The standard scopes are `Files.Read` (reads files the user can access) and `Files.Read.All` (reads all files across the user's accessible drives).
- **Application Permissions**: Used for background daemons, scheduled sync workers, and autonomous AI agents operating without user interaction. The application authenticates using client credentials (a client secret or certificate). The primary scope is `Files.Read.All`, which grants read access to all OneDrive drives across the entire enterprise tenant.

For consumer Microsoft accounts (personal OneDrive), applications use the Microsoft identity platform endpoint (`https://login.microsoftonline.com/consumers/oauth2/v2.0/token`) with delegated scopes. For enterprise OneDrive for Business accounts, applications use the organization tenant endpoint (`https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/token`).

### Acquiring an App-Only OAuth 2.0 Bearer Token

To authenticate a backend script or background ingestion worker, configure the OAuth 2.0 Client Credentials grant. The application requests a bearer token directly from Microsoft Entra ID:

```bash
pip install requests
```

```python
import requests

def get_entra_app_token(tenant_id: str, client_id: str, client_secret: str) -> str:
    """Acquire an application-only OAuth 2.0 access token from Microsoft Entra ID."""
    token_url = f"https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/token"
    payload = {
        "client_id": client_id,
        "client_secret": client_secret,
        "scope": "https://graph.microsoft.com/.default",
        "grant_type": "client_credentials",
    }
    headers = {"Content-Type": "application/x-www-form-urlencoded"}
    
    response = requests.post(token_url, data=payload, headers=headers, timeout=30)
    response.raise_for_status()
    token_data = response.json()
    return token_data["access_token"]
```

Setting `scope` to `https://graph.microsoft.com/.default` requests all static application permissions consented to by your tenant administrator in the Azure portal. The returned access token is valid for 60 minutes, after which your script must request a new token.

## How to Download OneDrive Files in Python with Microsoft Graph

Downloading files with Python requires careful buffer management. Ingesting multi-hundred megabyte files directly into memory using `response.content` creates memory spikes, degrades garbage collector performance, and risks terminating containerized workers with out-of-memory errors.

Production download routines should stream the response directly to disk in fixed-size chunks using the Python `requests` library.

The following script downloads a file from OneDrive via Microsoft Graph using the driveItem ID:

```python
import os
import requests

def download_onedrive_file_by_id(
    access_token: str,
    drive_id: str,
    item_id: str,
    target_filepath: str,
    chunk_size: int = 8192,
) -> str:
    """Download a file from OneDrive via Microsoft Graph using streaming chunks."""
    url = f"https://graph.microsoft.com/v1.0/drives/{drive_id}/items/{item_id}/content"
    headers = {"Authorization": f"Bearer {access_token}"}
    
    with requests.get(url, headers=headers, stream=True, timeout=120) as response:
        response.raise_for_status()
        
        target_dir = os.path.dirname(target_filepath)
        if target_dir:
            os.makedirs(target_dir, exist_ok=True)
            
        with open(target_filepath, "wb") as file_handle:
            for chunk in response.iter_content(chunk_size=chunk_size):
                if chunk:
                    file_handle.write(chunk)
                    
    return target_filepath
```

When `requests.get` runs with `stream=True`, the client establishes the HTTP connection and inspects headers without immediately downloading the response body. When the server returns `HTTP 302 Found`, `requests` follows the `Location` header to the temporary CDN URL. As chunks arrive across the socket in 8 KiB increments, the loop writes them sequentially to disk, keeping memory consumption negligible.

### Downloading by File Path via Graph REST API

When an automation script knows a document's folder path rather than its internal Microsoft Graph driveItem identifier, path-based addressing retrieves the file directly:

```python
def download_onedrive_file_by_path(
    access_token: str,
    user_id: str,
    relative_path: str,
    target_filepath: str,
    chunk_size: int = 8192,
) -> str:
    """Download a file using its relative path within a user's OneDrive."""
    clean_path = relative_path.strip("/")
    url = f"https://graph.microsoft.com/v1.0/users/{user_id}/drive/root:/{clean_path}:/content"
    headers = {"Authorization": f"Bearer {access_token}"}
    
    with requests.get(url, headers=headers, stream=True, timeout=120) as response:
        response.raise_for_status()
        
        target_dir = os.path.dirname(target_filepath)
        if target_dir:
            os.makedirs(target_dir, exist_ok=True)
            
        with open(target_filepath, "wb") as file_handle:
            for chunk in response.iter_content(chunk_size=chunk_size):
                if chunk:
                    file_handle.write(chunk)
                    
    return target_filepath
```

This pattern simplifies command-line migration scripts and folder backup tools where human operators specify familiar directory paths.

### Partial Range Downloads for Large Assets

When working with large assets such as video recordings, database dumps, or raw datasets, downloading the entire file just to read a header or inspect metadata is wasteful. Microsoft Graph storage backends support HTTP range requests (`RFC 7233`).

Range requests should be directed to the preauthenticated `@microsoft.graph.downloadUrl` rather than the `/content` endpoint, because intermediate 302 redirects can drop custom range headers.

```python
def download_file_range(
    access_token: str,
    drive_id: str,
    item_id: str,
    start_byte: int,
    end_byte: int,
) -> bytes:
    """Download a specific byte range from a OneDrive file using HTTP range requests."""
    metadata_url = (
        f"https://graph.microsoft.com/v1.0/drives/{drive_id}/items/{item_id}"
        "?$select=@microsoft.graph.downloadUrl"
    )
    headers = {"Authorization": f"Bearer {access_token}"}
    
    meta_response = requests.get(metadata_url, headers=headers, timeout=30)
    meta_response.raise_for_status()
    download_url = meta_response.json()["@microsoft.graph.downloadUrl"]
    
    range_headers = {"Range": f"bytes={start_byte}-{end_byte}"}
    range_response = requests.get(download_url, headers=range_headers, timeout=60)
    range_response.raise_for_status()
    
    return range_response.content
```

The storage server returns status code `HTTP 206 Partial Content` along with the exact byte range requested. This technique enables selective data extraction, partial reads, and resumable download pipelines.

## How to Handle HTTP 429 Throttling and Rate Limits During Downloads

Production pipelines that process high volumes of OneDrive files inevitably encounter API rate limits. Microsoft Graph monitors resource usage to protect multi-tenant infrastructure, enforcing limits across individual applications, user mailboxes, and tenant storage partitions.

When an application exceeds rate thresholds, Microsoft Graph returns `HTTP 429 Too Many Requests`. The response includes a `Retry-After` header specifying how many seconds the client must wait before retrying:

```http
HTTP/1.1 429 Too Many Requests
Content-Type: application/json
Retry-After: 10

{
  "error": {
    "code": "TooManyRequests",
    "message": "Please retry again later."
  }
}
```

Backing off requests using the Retry-After delay is the fastest way to recover from throttling because Microsoft Graph continues to log resource usage while a client is being throttled. If an application ignores HTTP 429 errors and retries immediately, Microsoft Graph logs those subsequent attempts as continued usage, extending the throttling duration.

### Implementing Exponential Backoff and Jitter in Python

A resilient download client checks for HTTP 429 responses, pauses for the specified `Retry-After` duration, and incorporates randomized jitter when calculating fallback exponential backoff:

```python
import time
import random
import requests

def download_with_retry_backoff(
    url: str,
    headers: dict,
    destination_path: str,
    max_retries: int = 5,
    base_backoff: float = 2.0,
) -> bool:
    """Download a file with automated HTTP 429 throttling and retry handling."""
    for attempt in range(max_retries):
        response = requests.get(url, headers=headers, stream=True, timeout=120)
        
        if response.status_code == 200:
            target_dir = os.path.dirname(destination_path)
            if target_dir:
                os.makedirs(target_dir, exist_ok=True)
            with open(destination_path, "wb") as f:
                for chunk in response.iter_content(chunk_size=8192):
                    if chunk:
                        f.write(chunk)
            return True
            
        if response.status_code == 429:
            retry_after = response.headers.get("Retry-After")
            if retry_after:
                wait_seconds = float(retry_after)
            else:
                jitter = random.uniform(0.5, 1.5)
                wait_seconds = (base_backoff ** attempt) + jitter
            time.sleep(wait_seconds)
            continue
            
        if response.status_code in (500, 503, 504):
            jitter = random.uniform(1.0, 3.0)
            wait_seconds = (base_backoff ** attempt) + jitter
            time.sleep(wait_seconds)
            continue
            
        response.raise_for_status()
        
    raise RuntimeError(f"Download failed after {max_retries} attempts due to sustained throttling.")
```

### Operational Guidelines for High-Volume OneDrive Downloads

1. **Limit Concurrent Connections**: Keep download thread pools modest (between 3 and 6 concurrent workers). Opening dozens of simultaneous download connections against a single tenant triggers rapid throttling.
2. **Reuse Download URLs**: The `@microsoft.graph.downloadUrl` remains valid for several minutes. If multiple background workers require access to the same document, share the preauthenticated URL rather than calling `/content` repeatedly.
3. **Use Delta Queries for Change Detection**: Do not poll folders on tight cron intervals to check for modified files. Instead, use Microsoft Graph delta queries (`GET /me/drive/root/delta`) to track changes incrementally without downloading unchanged assets.

## Why Agent Storage Workspaces Replace Direct File Downloads

Developers building autonomous AI agents with tools like Claude Code, Codex, Cursor, OpenClaw, CrewAI, or LangGraph encounter a common architectural problem when connecting agents to OneDrive files.

The conventional approach instructs the agent to call the OneDrive API, download complete files to local scratch disk, parse the raw text, and dump whole documents into the model context window.

This direct download pattern introduces severe operational bottlenecks:

- **Context Window Exhaustion**: Agents burn thousands of tokens ingesting entire 50-page PDFs when the user only asked a question about a single pricing clause.
- **Local Storage Sprawl**: Ephemeral agent containers, Docker runners, and serverless sandboxes rapidly exhaust disk space when downloading batches of large files.
- **API Throttling Vulnerability**: High-frequency document parsing by multiple agents quickly triggers tenant-wide HTTP 429 throttling.
- **Stale Local Caches**: Local file copies become out of date the minute a human collaborator updates the original document in OneDrive.

### The Fast.io Architecture: Synchronize Once, Search Over MCP

The modern architecture separates file storage from agent execution. Instead of forcing agents to download raw binary files, teams synchronize their existing OneDrive folders into an intelligent workspace.

Fast.io provides shared, organization-owned [workspaces](/product/workspaces/) designed for collaboration between humans and AI agents. Through Cloud Sync (available for Dropbox, Box, and OneDrive, supporting SharePoint document libraries through the OneDrive connector), folders synchronize one-way or two-way, on a schedule or on demand (never continuous, live, or real-time; Google Drive supports import today with sync coming soon).

```
+-------------------------------------------------------------------+
|                     Enterprise OneDrive Account                   |
|               Shared Team Folders & Document Libraries            |
+-------------------------------------------------------------------+
                                  |
                                  | Cloud Sync via OneDrive Connector
                                  | (Scheduled or on-demand sync)
                                  v
+-------------------------------------------------------------------+
|                         Fast.io Workspace                         |
|  - Automatic Background Hybrid Indexing (Full-Text + Semantic)    |
|  - Per-File Version History & Append-Only Audit Log               |
|  - Structured Document Data Extraction via Metadata Views         |
+-------------------------------------------------------------------+
                                  |
                                  | Streamable HTTP (/mcp/tools)
                                  v
+-------------------------------------------------------------------+
|                     Autonomous AI Agent                           |
|  - Queries Workspace via Consolidated MCP Toolset                 |
|  - Retrieves Exact Citations and Text Passages                    |
|  - Zero Local Binary File Downloads                               |
+-------------------------------------------------------------------+
```

### Automatic Hybrid Indexing and Semantic Retrieval

When OneDrive folders sync into a Fast.io workspace, Intelligence Mode indexes documents automatically upon arrival. Instead of configuring separate vector databases, embedding pipelines, and chunking algorithms, Fast.io builds a unified index combining full-text search, semantic search, and search-by-metadata-value filtering.

Autonomous agents connect to the workspace using the remote MCP server over Streamable HTTP at `https://mcp.fast.io/mcp/tools`. Using a consolidated MCP toolset, agents configure [storage for agents](/storage-for-agents/) and issue semantic queries to retrieve targeted passages and file citations without downloading whole documents to local disk.

### Structured Document Extraction with Metadata Views

When workflows require structured business records rather than freeform text answers, Fast.io provides [Metadata Views](/product/document-data-extraction/).

Users describe the fields they want extracted in natural language. AI designs a typed schema supporting Text, Integer, Decimal, Boolean, URL, JSON, and Date & Time formats. Metadata Views populate a structured, filterable table directly from PDFs, spreadsheets, or scanned documents without manual OCR templates. Agents can create Views, trigger extraction, and query structured results directly via MCP tools.

### Enterprise Governance and Workspace Performance

Workspaces provide enterprise governance including granular permissions (organization, workspace, folder, and file level), per-file version history, and an append-only audit log. When an agent creates and configures workspaces, ownership transfer allows the agent account to hand the organization over to human administrators while maintaining administrative access.

In third-party evaluations published in the [Fastio benchmark comparison](https://fast.io/benchmarks/), Fastio was measured the fastest and the lowest cost of the providers tested. (Note that every measured row in that evaluation was that provider's native connector in Claude Cowork; no row was a local stdio server, a Files-On-Demand stub or SharePoint, and SharePoint was not measured at all).

Monthly plans start with a 30-day free trial, which requires a credit card.

### Summary of Implementation Paths

Use the direct **OneDrive API via Microsoft Graph** when writing administration scripts, managing user file ownership, or transferring individual files where local binary storage is explicitly required.

Use **intelligent workspace synchronization via MCP** when connecting OneDrive assets to AI agents and RAG pipelines. By syncing OneDrive folders to Fast.io workspaces, agents query files semantically, eliminate local disk bloat, and prevent API rate limiting.

## Frequently asked questions

### How do I download a file using the OneDrive API?

To download a file using the OneDrive API, send an HTTP GET request to https://graph.microsoft.com/v1.0/me/drive/items/{item-id}/content with an Entra ID access token in the Authorization Bearer header. The endpoint returns an HTTP 302 Found redirect containing a preauthenticated download URL in the Location header. Follow the redirect without sending the Authorization header to download the raw binary file stream.

### Can I get a direct download link from OneDrive API?

Yes. Instead of calling the /content endpoint which returns an HTTP 302 redirect, query the driveItem metadata endpoint and select the download URL property: GET /me/drive/items/{item-id}?$select=@microsoft.graph.downloadUrl. The returned JSON object contains a short-lived preauthenticated link in the @microsoft.graph.downloadUrl field that can be fetched directly without an Authorization header.

### How do I handle large file downloads in OneDrive Microsoft Graph?

For large file downloads, stream data in fixed chunk sizes (such as 8 KiB) to local disk rather than reading the entire response into memory. For partial reads, request the @microsoft.graph.downloadUrl property first, then issue an HTTP GET to that URL with a Range header (for example, Range: bytes=0-1048575). The server returns HTTP 206 Partial Content with the requested byte slice.

### Why does the OneDrive API return an HTTP 302 redirect for file downloads?

Microsoft Graph returns an HTTP 302 Found redirect to offload high-volume binary data transfers from the central API gateway onto distributed cloud storage content delivery networks. This design improves download throughput, isolates API gateway performance, and prevents binary downloads from consuming per-minute Microsoft Graph API call quotas.

### What permissions are required to download files via Microsoft Graph OneDrive API?

Interactive user applications require delegated permissions such as Files.Read or Files.Read.All. Automated backend scripts and daemon services operating without a user require the Files.Read.All application permission granted via the Microsoft Entra ID OAuth 2.0 Client Credentials flow with admin consent.

### Can AI agents query OneDrive documents without downloading full binary files?

Yes. Instead of downloading whole files to local agent disks, teams can synchronize OneDrive folders into a Fast.io workspace using Cloud Sync. Fast.io automatically indexes documents with Intelligence Mode for hybrid full-text and semantic search. Agents query the workspace over the remote MCP server to retrieve relevant passages and citations without downloading binary files.

## Sources

- [Microsoft Learn: DriveItem: get content](https://learn.microsoft.com/en-us/graph/api/driveitem-get-content?view=graph-rest-1.0): Microsoft Graph returns a 302 Found response redirecting to a preauthenticated download URL when requesting file contents.
- [Microsoft Learn: Microsoft Graph throttling guidance](https://learn.microsoft.com/en-us/graph/throttling): Backing off requests using the Retry-After delay is the fastest way to recover from throttling in Microsoft Graph.

## About Fast.io

Fast.io provides shared workspaces where people and AI agents work on the same files, with built-in semantic search and citation-backed chat over what they hold. Agents reach it through a remote MCP server, a REST API at https://api.fast.io/current/, and a command line client published on npm as @vividengine/fastio-cli. MCP setup is at https://mcp.fast.io/docs: Claude and most MCP clients connect to https://mcp.fast.io/mcp/tools, ChatGPT to https://mcp.fast.io/mcp/operations, and coding agents to https://mcp.fast.io/mcp/code.
