A spec-driven MVP that converts workout PDFs into Hevy routines using the Hevy API, built with Docker and n8n.
This project provides an automated workflow to extract workout information from PDF files and create structured workout routines in the Hevy fitness tracking app. The solution uses n8n for workflow automation, making it easy to extend and customize.
PDF Upload (Webhook)
โ
PDF Text Extraction
โ
Workout Parser
โ
Exercise Mapper
โ
Hevy Payload Preparation
โ
Hevy API Call
โ
Success/Error Response
- Webhook Node: Receives PDF uploads via HTTP POST
- PDF Text Extractor: Extracts text content from PDF files
- Workout Parser: Parses text into structured workout data
- Exercise Mapper: Maps exercise names to Hevy exercise IDs
- Hevy Payload Preparation: Formats data for Hevy API
- Hevy API Caller: Creates routine via Hevy API
- Error Handler: Handles errors gracefully with detailed responses
- Docker and Docker Compose
- Hevy API key (obtain from Hevy API documentation)
- Basic understanding of n8n workflows
git clone https://github.com/fbaroni/pdf-to-hevy.git
cd pdf-to-hevycp .env.example .envEdit .env and set your configuration:
# Required: Your Hevy API key
HEVY_API_KEY=your_actual_hevy_api_key
# Optional: n8n configuration
N8N_PORT=5678
N8N_BASIC_AUTH_USER=admin
N8N_BASIC_AUTH_PASSWORD=your_secure_passworddocker-compose up -dThis will start n8n on http://localhost:5678
- Open n8n in your browser:
http://localhost:5678 - Log in with the credentials from
.env(default: admin/change_this_password) - Click on "Workflows" โ "Import from File"
- Select
workflows/pdf-to-hevy-workflow.json - Activate the workflow
The webhook endpoint will be available at:
http://localhost:5678/webhook/upload-workout-pdf
Test with curl:
curl -X POST http://localhost:5678/webhook/upload-workout-pdf \
-H "Content-Type: application/json" \
-d '{"mockText": "Chest Day\n1. Bench Press - 4x10 @ 60kg\n2. Incline Press - 3x12 @ 40kg"}'Expected response:
{
"routine": [{
"id": "uuid",
"title": "Chest Day",
"exercises": [
{
"title": "Squat (Barbell)",
"notes": "Bench Press",
"sets": [{"weight_kg": 60, "reps": 10}, ...]
}
]
}]
}pdf-to-hevy/
โโโ docker-compose.yml # Docker services configuration
โโโ .env.example # Environment variables template
โโโ .gitignore # Git ignore rules
โโโ README.md # This file
โโโ workflows/ # n8n workflow definitions
โ โโโ pdf-to-hevy-workflow.json
โโโ src/ # Helper JavaScript modules
โโโ pdfExtractor.js # PDF text extraction logic
โโโ workoutParser.js # Workout parsing logic
โโโ exerciseMapper.js # Exercise name mapping
โโโ hevyApiClient.js # Hevy API client utilities
The workflow accepts a POST request with JSON:
{
"mockText": "Workout Name\n1. Exercise Name - SetsxReps @ Weightkg"
}Example:
{
"mockText": "Chest Day\n1. Bench Press - 4x10 @ 60kg\n2. Incline Press - 3x12 @ 40kg"
}The parser recognizes this format:
Workout Name
1. Exercise Name - SetsxReps @ Weightkg
2. Another Exercise - 3x12 @ 40kg
Success Response (200):
{
"routine": [{
"id": "uuid",
"title": "Chest Day",
"exercises": [
{
"title": "Squat (Barbell)",
"notes": "Bench Press",
"sets": [{"weight_kg": 60, "reps": 10}, ...]
}
]
}]
}Note: Currently all exercises are mapped to "Squat (Barbell)" with the original exercise name stored in notes. Exercise mapping can be customized in the workflow.
Error Response (400):
{
"status": "error",
"message": "Failed to process workout PDF",
"error": "Error details",
"stage": "pdf-extraction"
}Edit src/exerciseMapper.js to add exercise mappings:
const EXERCISE_MAP = {
'your exercise name': {
id: 'hevy_exercise_id',
title: 'Display Name'
},
// ... more exercises
};Update src/workoutParser.js to handle different PDF formats:
function parseExerciseBlock(block) {
// Customize parsing logic here
}- Open n8n UI
- Edit the workflow
- Add new nodes or modify existing ones
- Export and save to
workflows/directory
- Never commit
.envfile - it contains sensitive credentials - Use environment variables - API key is loaded from
$env.HEVY_API_KEY - Rotate API keys regularly - especially after any security incidents
- Enable HTTPS in production environments
- Limit webhook access - use authentication or IP whitelisting
- Monitor n8n logs - check for unauthorized access attempts
Note: The
n8n-data/directory is automatically excluded from the repository as it may contain sensitive workflow execution data and credentials.
- Check that all environment variables are set correctly
- Verify the Hevy API key is valid
- Check n8n logs:
docker-compose logs n8n
- Ensure PDF is text-based (not scanned images)
- Check PDF format matches expected structure
- Review extraction logs in the workflow execution
- Verify API key is correct in
.envfile - Check Hevy API status and rate limits
- Review API response in n8n execution logs
- Ensure
HEVY_API_KEYenvironment variable is properly loaded
- Check that workflow is active in n8n UI
- Verify webhook URL path matches your request
- Check n8n logs:
docker-compose logs n8n - Ensure environment variables are loaded:
docker exec container_name env | grep HEVY
# Fix volume permissions
sudo chown -R 1000:1000 n8n-data/View workflow executions in n8n:
- Navigate to "Executions" in n8n UI
- Check execution history
- Debug failed runs with detailed logs
To update the workflow:
# Pull latest changes
git pull
# Restart services
docker-compose down
docker-compose up -d
# Re-import workflow if needed# View logs
docker-compose logs -f n8n
# Restart n8n
docker-compose restart n8n
# Stop all services
docker-compose downAfter making changes in n8n UI:
- Click "..." menu on workflow
- Select "Export"
- Save to
workflows/pdf-to-hevy-workflow.json
- Fork the repository
- Create a feature branch
- Make your changes
- Test thoroughly
- Submit a pull request
Note: This project was developed with AI assistance. See LICENSE for details about AI contributions.
MIT License - feel free to use and modify as needed. This project includes significant AI assistance in development. See LICENSE for full details.
- n8n - Workflow automation platform
- Hevy - Fitness tracking app
- Built with clarity, modularity, and extensibility in mind
For issues or questions:
- Open a GitHub issue
- Check n8n documentation: https://docs.n8n.io/
- Review Hevy API documentation
- Support for scanned PDF images (OCR)
- Multiple PDF format parsers
- Bulk upload support
- Exercise auto-detection using AI
- Progress tracking dashboard
- Mobile app integration
- Scheduled imports from cloud storage
Happy lifting! ๐ช