Upload Hooks
Dropshare 6.16 or newer
Upload Hooks let Dropshare run an action before an upload starts or after it has finished. A hook can call a webhook, run a shell command, run an Apple Shortcut, or open a URL. This makes it easy to connect Dropshare to other tools: post the link to a chat, add it to a notes app, trigger an automation, sync a file elsewhere, or keep your own log of uploads.
Hooks run in the background. They never delay or cancel an upload. If a hook fails, Dropshare shows a notification and writes the error to the log and the Activity Log.
Set up a hook
- Open Dropshare and go to Preferences.
- Open the Uploads tab.
- Click Hooks….
- Click + to add a hook, then fill in the form:
- Name: a label for the hook.
- Run: Before Upload or After Upload.
- Type: Webhook, Shell Command, Apple Shortcut, or Open URL.
- Connections: run the hook for all connections or only for the ones you select.
- Click Test with sample data to run the hook once with example values.
- Click Save.
Hooks can be enabled and disabled with the switch in the list, reordered by dragging, and duplicated or deleted from the context menu.
Hook types
Webhook
Sends an HTTP request to a URL.
- URL: the endpoint to call. Placeholders are allowed and are URL encoded automatically.
- Method:
GET,POST, orPUT. - Body (
POST/PUT): JSON, Form (URL encoded), or None. Leave Custom body empty to send the full payload with all fields. Enter a custom body to control the exact content; placeholders are replaced in it. - With
GET, enable Append payload as query parameters to send all fields in the query string. - Headers: add custom headers, for example
Authorization: Bearer …. Placeholders work in header values, too.
A response with a 2xx status code counts as success. Requests time out after 30 seconds.
TIP
When you use a custom JSON body, values are inserted as-is and are not JSON escaped. If a value may contain quotes (for example a file name), prefer the empty custom body so Dropshare builds the JSON for you.
Shell Command
Runs a command with /bin/zsh -l -c. The payload is passed in three ways:
- Placeholders such as
%filePath%are inserted shell quoted, so paths with spaces are safe. - Environment variables with a
DROPSHARE_prefix in upper snake case, for example$DROPSHARE_URL,$DROPSHARE_FILE_PATH,$DROPSHARE_CONNECTION_TYPE_NAME,$DROPSHARE_SHORT_URL. - The full payload as JSON on stdin.
A non-zero exit code counts as a failure. Commands time out after 60 seconds.
Examples:
# Append every upload to a log file
echo "$DROPSHARE_DATE $DROPSHARE_CONNECTION_NAME $DROPSHARE_URL" >> ~/dropshare-uploads.log# Keep a local copy of every uploaded file
cp %filePath% ~/Uploads/# Pipe the JSON payload into your own script
/usr/local/bin/my-upload-script.pyApple Shortcut
Runs a shortcut from the Shortcuts app. Choose it from the list of installed shortcuts. The shortcut receives the payload as a JSON file as its input. Use the Get Dictionary from Input action in the shortcut and read the fields by name, for example url or fileName.
Shortcuts time out after 60 seconds.
Open URL
Opens a URL or an app URL scheme with its default handler. Placeholder values are URL encoded automatically. This is handy for apps that offer URL schemes, for example:
things:///add?title=%fileName%¬es=%url%Placeholders
Placeholders are written as %name% and are replaced in URLs, headers, bodies, and shell commands. Click a placeholder in the Available placeholders list in the hook editor to copy it.
| Placeholder | Description | Available |
|---|---|---|
%event% | pre-upload or post-upload | Before & After |
%fileName% | Original file name including extension | Before & After |
%filePath% | Local path of the file being uploaded | Before & After |
%fileSize% | File size in bytes | Before & After |
%mimeType% | MIME type of the file | Before & After |
%connectionKey% | Internal identifier of the connection | Before & After |
%connectionName% | Name of the connection as shown in Dropshare | Before & After |
%connectionType% | Connection type identifier, e.g. s3, sftp, dropbox | Before & After |
%connectionTypeName% | Connection type name, e.g. Amazon S3, SFTP, Dropbox | Before & After |
%url% | Final URL (landing page or direct URL). Includes the #dec=… decryption key fragment for encrypted uploads | After |
%directUrl% | Direct URL to the uploaded file | After |
%landingPageUrl% | Landing page URL, empty if no landing page was created | After |
%shortUrl% | Shortened URL, empty if no URL shortener was used | After |
%encrypted% | true if the file was encrypted before uploading | After |
%decryptionKey% | Decryption key for encrypted uploads, otherwise empty | After |
%uploadId% | Identifier of the upload in the history | After |
%uploadedTo% | Remote path or identifier of the uploaded file | After |
%fileHash% | Integrity hash of the uploaded file, if computed | After |
%isScreenshot% | true if the upload was a screenshot | After |
%date% | Upload date in ISO 8601 format | After |
In Before Upload hooks only the first nine placeholders have values. The remaining ones are not known yet at that point: in a custom JSON body a quoted placeholder such as "%url%" becomes null, in shell commands it becomes an empty string '', and everywhere else it is replaced with nothing.
For shell commands the same fields are available as environment variables: %fileName% becomes $DROPSHARE_FILE_NAME, %connectionTypeName% becomes $DROPSHARE_CONNECTION_TYPE_NAME, and so on.
Full payload
When a webhook sends the full payload (empty custom body), or when a shell command reads stdin, or when a shortcut reads its input, the data looks like this:
{
"event": "post-upload",
"fileName": "Screenshot.png",
"filePath": "/Users/you/Desktop/Screenshot.png",
"fileSize": 123456,
"mimeType": "image/png",
"connectionKey": "…",
"connectionName": "My Server",
"connectionType": "sftp",
"connectionTypeName": "SFTP",
"url": "https://example.com/d/screenshot-a1b2c3/",
"directUrl": "https://example.com/d/screenshot-a1b2c3.png",
"landingPageUrl": "https://example.com/d/screenshot-a1b2c3/",
"shortUrl": "https://dshre.com/abc123",
"encrypted": false,
"decryptionKey": "",
"uploadId": "…",
"uploadedTo": "d/screenshot-a1b2c3.png",
"fileHash": "…",
"isScreenshot": true,
"date": "2026-09-26T10:32:15Z"
}fileSize is a number and encrypted and isScreenshot are booleans in JSON. All other fields are strings.
Good to know
- URL shortener: when a shortener is enabled for the connection, Dropshare waits up to 15 seconds for the shortened URL before running After Upload hooks so that
%shortUrl%is filled. If the shortener takes longer, the hook runs with an empty%shortUrl%. - Order: hooks run one after another in the order shown in the list.
- Failures: a failed hook shows a notification with the reason (for example an HTTP status code or a shell exit code) and is listed in the Activity Log with the type Hook (Failed). Successful runs are logged as Hook. The log file contains the details.
- Security: hook settings, including header values such as API tokens, are stored in the encrypted preferences of Dropshare on your Mac. Remember that
%url%can contain the decryption key of encrypted uploads. Only send it to services you trust. - Syncing: hooks are not synchronized to other devices.

