Connect Dropbox
Verified against the Dropbox console, October 2026
Dropbox has no built-in Kody OAuth app. Create a Dropbox app in its developer console, then connect it to Kody with the authorization code + PKCE flow. PKCE is a public-client flow, so Kody never needs the app secret.
What you get
Once connected, you can ask Kody things like:
- "Upload this report to my reports folder in Dropbox."
- "Find last month's invoices in my Dropbox and list them."
- "Make a share link for the onboarding deck."
Before you start
- Dropbox apps are free. A new app is in development status, which is fine for your own account.
- Dropbox serves its API from three hosts, and a connection needs all three:
api.dropboxapi.comfor RPC calls such as listing folders and metadatacontent.dropboxapi.comfor uploads and downloadsnotify.dropboxapi.comfor change longpolling
- A connection that only allows
api.dropboxapi.comcan list files but fails every upload and download. The connect link below includes all three hosts.
Create the app
- Open the Dropbox App Console and click Create app.
- Choose Scoped access, then App folder (Kody sees only
/Apps/<your app name>) or Full Dropbox. Name the app. - On the Settings tab, add the redirect URI
https://kody.codes/connect/oauthunder OAuth 2 → Redirect URIs. A self-hosted deployment registers its own origin plus/connect/oauth. Matching is exact. Leave Allow public clients (Implicit Grant & PKCE) on. - On the Permissions tab, enable the scopes from the Scopes section and click Submit. Dropbox refuses an authorize request for a scope the app does not have.
- Copy the App key from the Settings tab. It is the OAuth client ID.
Connect to Kody
Open the prefilled connect link while signed in to Kody:
https://kody.codes/connect/oauth?provider=dropbox&authorizeUrl=https%3A%2F%2Fwww.dropbox.com%2Foauth2%2Fauthorize&tokenUrl=https%3A%2F%2Fapi.dropboxapi.com%2Foauth2%2Ftoken&apiBaseUrl=https%3A%2F%2Fapi.dropboxapi.com&scopes=account_info.read%20files.metadata.read%20files.metadata.write%20files.content.read%20files.content.write%20sharing.read%20sharing.write&extraAuthorizeParams=%7B%22token_access_type%22%3A%22offline%22%7D&allowedHosts=api.dropboxapi.com%2Ccontent.dropboxapi.com%2Cnotify.dropboxapi.com&dashboardUrl=https%3A%2F%2Fwww.dropbox.com%2Fdevelopers%2FappsDecoded: authorize URL https://www.dropbox.com/oauth2/authorize, token URL
https://api.dropboxapi.com/oauth2/token,
apiBaseUrl=https://api.dropboxapi.com, the scopes listed below
(space-separated), extraAuthorizeParams={"token_access_type":"offline"}, and
allowedHosts=api.dropboxapi.com,content.dropboxapi.com,notify.dropboxapi.com.
flow=pkce is Kody's default, so the link has no flow parameter. Paste the app
key into the setup form, then authorize.
token_access_type=offline makes Dropbox return a refresh token. Without it,
Dropbox issues a short-lived access token only, and the connection stops working
after about four hours.
Name the connection dropbox: that is the name
@kentcdodds/dropbox reads. To
connect a second account, change provider (for example
provider=dropbox-work).
See the OAuth guide for query parameters and reconnect behavior.
Fix an existing connection
A Dropbox connection made before this link existed may allow only
api.dropboxapi.com. Either:
- Open the connect link above again and reconnect. Kody keeps the connection's hosts and adds the ones in the link.
- Or open the connection on your Credentials page, choose Edit hosts,
and add
content.dropboxapi.comandnotify.dropboxapi.com.
Scopes
| Scope | Needed for |
|---|---|
account_info.read | account and space usage, smoke test |
files.metadata.read | list folders, search, metadata |
files.metadata.write | move, rename, delete |
files.content.read | download |
files.content.write | upload, save from a URL |
sharing.read | list shared links |
sharing.write | create shared links |
Request only what your workflows need. Enable each scope on the app's Permissions tab first. After changing permissions, reconnect so the new token carries them.
Use the @kentcdodds/dropbox package and verify
Credentials alone are not the finish. Install or fork
@kentcdodds/dropbox, then verify
from execute (adjust the import to your fork):
import smokeTest from 'kody:@kentcdodds/dropbox/smoke-test'
export default async function main() {
return smokeTest()
}A successful response looks like { ok: true, … } without account details.
Optional raw probe with the runtime helper, which exercises the content host:
import { createAuthenticatedFetch } from 'kody:runtime'
export default async function main() {
const dropboxFetch = await createAuthenticatedFetch('dropbox')
const response = await dropboxFetch(
'https://content.dropboxapi.com/2/files/upload',
{
method: 'POST',
headers: {
'Content-Type': 'application/octet-stream',
'Dropbox-API-Arg': JSON.stringify({
path: '/kody-smoke-test.txt',
mode: 'overwrite',
}),
},
body: 'hello from Kody',
},
)
if (!response.ok) {
throw new Error(`Dropbox upload failed: ${response.status}`)
}
const file = (await response.json()) as { path_display?: string }
return { uploaded: file.path_display }
}Troubleshooting
does not allow requests to host "content.dropboxapi.com": the connection is missing a Dropbox host. See Fix an existing connection.redirect_urimismatch: the registered redirect must be exactlyhttps://kody.codes/connect/oauth.- Authorize fails with a scope error: enable that scope on the app's Permissions tab, or drop it from the link.
401after a few hours: the connection has no refresh token. Reconnect with the link above, which asks fortoken_access_type=offline.path/not_foundwith an App folder app: paths are relative to/Apps/<your app name>, which Dropbox creates on the first write.
Related
- OAuth
- Integration bootstrap
@kentcdodds/dropboxlisting