Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.mirage.strukto.ai/llms.txt

Use this file to discover all available pages before exploring further.

Overview

The Dropbox resource uses OAuth2 with a long-lived refresh token to authenticate against the Dropbox v2 HTTP API:
  • /2/files/list_folder, list folder entries
  • /2/files/download, download file bytes
  • /2/files/search_v2, search files by name/content
  • /2/files/get_metadata, fetch entry metadata
Two flows are supported:
  • Code flow with client secret, for Node/server. Needs client_id, client_secret, refresh_token.
  • PKCE flow, for browsers. Needs only client_id and refresh_token (no secret in the bundle).
Both produce the same long-lived refresh token; the resource auto-refreshes short-lived access tokens (≈4h) behind the scenes.

Setup

1. Create a Dropbox App

  1. Go to https://www.dropbox.com/developers/apps
  2. Click Create app
  3. Choose:
    • API: Scoped access
    • Access type: App folder (sandboxed to one folder Dropbox creates for you) or Full Dropbox (your entire account). Pick App folder for least privilege.
    • Name it (e.g., “Mirage”) -> Create app

2. Configure Permissions

On the app’s settings page, click the Permissions tab and check:
  • files.metadata.read, list folders, read file metadata
  • files.content.read, download file bytes
If you also want write/delete (not used by the read-only resource yet), check files.content.write and files.metadata.write. Click Submit at the bottom of the Permissions tab. Required: Dropbox does not include unchecked scopes in tokens, even if the auth URL requests them.

3. Configure OAuth 2 Redirect URI

On the Settings tab, scroll to OAuth 2 -> Redirect URIs and add:
  • For the CLI flow below: http://localhost:1
  • For the browser PKCE example: http://localhost:5173/dropbox_pkce.html
Click Add after each.

4. Copy the App Key (and Secret)

Still on Settings, copy:
  • App key, this is your DROPBOX_APP_KEY
  • App secret, click Show -> copy. This is your DROPBOX_APP_SECRET. Skip if you only need the PKCE flow.

5. Get the Refresh Token (CLI flow with client secret)

This mirrors the Google flow, easiest path for Node/server use. A) Open this URL in a browser (replace YOUR_APP_KEY):
https://www.dropbox.com/oauth2/authorize?client_id=YOUR_APP_KEY&response_type=code&token_access_type=offline&redirect_uri=http://localhost:1
  • token_access_type=offline, required to receive a refresh token. Without this you only get a short-lived access token.
B) Authorize: sign in -> click Allow. C) Copy the code: the browser redirects to http://localhost:1?code=ABC... (the page won’t load, expected). Copy the code value from the URL bar. D) Exchange the code for a refresh token:
curl https://api.dropboxapi.com/oauth2/token \
  -d "code=THE_CODE_FROM_STEP_C" \
  -d "grant_type=authorization_code" \
  -d "client_id=YOUR_APP_KEY" \
  -d "client_secret=YOUR_APP_SECRET" \
  -d "redirect_uri=http://localhost:1"
The response contains refresh_token, save it. Example:
{
  "access_token": "sl.B...",
  "expires_in": 14400,
  "refresh_token": "abc123...",
  "scope": "files.metadata.read files.content.read",
  "token_type": "bearer",
  "uid": "12345",
  "account_id": "dbid:..."
}

6. Set Environment Variables

# .env.development
DROPBOX_APP_KEY=abc123app4key
DROPBOX_APP_SECRET=def456app4secret
DROPBOX_REFRESH_TOKEN=ghi789refresh4token

Alternative: PKCE Flow (browser, no client secret)

If you’re mounting Dropbox from a browser SPA and don’t want to ship a client secret, use the PKCE flow. The bundled example does the dance end-to-end.
  1. In the Dropbox app Settings tab, ensure the redirect URI http://localhost:5173/dropbox_pkce.html is registered (Step 3).
  2. Set only DROPBOX_APP_KEY in .env.development at the repo root (no secret needed).
  3. From examples/typescript/browser/, run pnpm dev.
  4. Open http://localhost:5173/dropbox_pkce.html and click Connect Dropbox.
The example persists the refresh token to localStorage, then mounts a DropboxResource with just { clientId, refreshToken } and runs ls /dropbox/. Inspect DevTools -> Network -> filter token to confirm refresh calls don’t include client_secret. The same refresh_token can be reused for headless setups, copy it out of localStorage and set it as DROPBOX_REFRESH_TOKEN in your env.

Token Lifetime

TokenLifetime
Access token~4 hours (expires_in: 14400)
Refresh tokenLong-lived; survives until manually revoked
Refresh tokens get revoked if: The DropboxTokenManager in the resource transparently exchanges the refresh token for a fresh access token whenever the cached one is within 5 minutes of expiry.

Scopes Reference

ScopePurpose
files.metadata.readList folders, read file metadata
files.metadata.writeMove, rename, create folders
files.content.readDownload file bytes
files.content.writeUpload, overwrite, delete files
sharing.readList shared links and shared folders
account_info.readAccount email, country, user info
The Mirage resource only needs files.metadata.read + files.content.read for the read-only mount. Add the *.write scopes if/when write commands land.

Troubleshooting

IssueFix
400 invalid_grant on token exchangeThe code is single-use and expires fast, re-do Step 5A with a fresh URL
No refresh_token in token responseAdd token_access_type=offline to the auth URL
path/not_found/. on ls /dropbox/Account is empty, or app is App folder scoped and the sandbox folder hasn’t been created
missing_scope on downloadCheck files.content.read is enabled in the Permissions tab and submitted
Browser PKCE: redirect URI mismatchDropbox is strict, http://localhost:5173/dropbox_pkce.html must match exactly (no trailing slash)
Token works locally but fails after a whileAccess token expired, the TokenManager should auto-refresh; if not, refresh token may be revoked
For TypeScript usage, mount with:
import { DropboxResource } from '@struktoai/mirage-node'

const dropbox = new DropboxResource({
  clientId: process.env.DROPBOX_APP_KEY!,
  clientSecret: process.env.DROPBOX_APP_SECRET!,
  refreshToken: process.env.DROPBOX_REFRESH_TOKEN!,
})
Or browser (PKCE):
import { DropboxResource } from '@struktoai/mirage-browser'

const dropbox = new DropboxResource({
  clientId: 'YOUR_APP_KEY',
  refreshToken: refreshTokenFromLocalStorage,
})