See
--help-hooks for complete documentation and example hooks in the repository.Hook Types
Copyparty supports hooks for various events:Upload Hooks
before upload
Execute command before a file upload starts
after upload
Execute command after a file upload finishesMost commonly used hook type for notifications and post-processing.
idle after upload
Execute command after all uploads finish and volume is idleUnlike
xbu/xau (which execute for every file), xiu is given a list of recent uploads on STDIN after the server has been idle for N seconds.File Operation Hooks
before copy
Execute command before a file copy
after copy
Execute command after a file copy
before rename
Execute command before a file rename/move
after rename
Execute command after a file rename/move
before delete
Execute command before a file delete
after delete
Execute command after a file delete
Special Hooks
on message
Execute command when a message is received (via
[📟] send-msg tab)on ban
Execute command when someone gets banned
Hook Flags
Hooks can have additional flags to modify their behavior:check flag
Hook exit code controls the action:
- Exit
0= allow the action, continue to next hook - Exit
100= allow the action, stop running remaining hooks - Any other = reject/prevent the action, don’t run remaining hooks
json flag
Send extended upload info as JSON instead of just the filesystem pathJSON includes: file path, uploader IP, username, size, timestamp, etc.
timeout flag
Timeout after N seconds (important for blocking hooks like REQ/PUSH)
import flag
Import hook as Python module (140x faster startup, but bugs may crash copyparty)
Hook Arguments
Basic Syntax
Information Passed to Hooks
By default, hooks receive the filesystem path as the first (and only) argument. With thej flag, hooks receive a JSON object on STDIN with:
ZeroMQ Hooks
Instead of running programs, hooks can send ZeroMQ messages:The PUSH and REQ patterns need
t[N] (timeout) because they block if no clients are connected.Example ZeroMQ Receiver
See zmq-recv.py for a complete example.Common Use Cases
Desktop Notifications
Discord Webhook Notifications
Using discord-announce.py:Reject Specific File Types
Using reject-extension.py:Remove EXIF from Images
Using image-noexif.py:Download URLs
Using wget.py:[📟] send-msg tab to download files.
Batch Processing
Using xiu-sha.py:Custom Error Messages
Using reject-and-explain.py:Hook Effects
Some hooks can return special instructions to copyparty:Relocation
Redirect an upload to another destination. Example from reloc-by-ext.py:Indexing
Tell copyparty about additional files to scan. Example from podcast-normalizer.py:Configuration Examples
Per-Volume Hooks
Multiple Hooks
Hooks are additive - you can specify multiple hooks of the same type:Global + Volume Hooks
Conditional Hooks by File Type
Create a wrapper script:check-and-process.sh
Writing Custom Hooks
Basic Template (Shell)
hook-template.sh
Basic Template (Python)
hook-template.py
JSON Input Template (Python)
json-hook-template.py
Check Hook Template
check-hook.py
Performance Considerations
1
Test hooks thoroughly
Ensure hooks exit correctly and handle errors gracefully
2
Use xiu for batches
Process multiple uploads at once instead of one-by-one
3
Keep hooks fast
Offload heavy processing to background jobs
4
Monitor hook execution
Check server logs for hook failures or timeouts
Comparison: Hooks vs MTP Plugins
Copyparty has two systems for running external programs:For complex metadata processing, consider mtp plugins instead of hooks.
Troubleshooting
Hook not executing
Hook not executing
- Check file permissions:
chmod +x /path/to/hook.sh - Verify path is absolute, not relative
- Check server logs for error messages
- Test hook manually:
/path/to/hook.sh /test/file.txt
Hook runs but action still fails
Hook runs but action still fails
For
c (check) hooks:- Exit 0 to allow action
- Exit non-zero to reject action
- Check stderr for error messages
ZeroMQ timeout
ZeroMQ timeout
- Add
t[N]timeout flag for PUSH/REQ patterns - Ensure receiver is running and connected
- Check ZeroMQ port is accessible
Hook crashes copyparty
Hook crashes copyparty
- Remove
I(import) flag - Fix Python syntax errors in hook
- Add error handling to hook script
JSON data not received
JSON data not received
- Add
jflag to hook configuration - Read from stdin, not command-line arguments
- Verify JSON parsing in hook script
Example Repository
See the official hooks directory for complete working examples:- notification hooks
- validation/rejection hooks
- message handlers
- batch processing
- webhook integrations