Flask API for extracting unsold estimates from ServiceTitan and sending them to GoHighLevel.
app.py- Main Flask applicationrequirements.txt- Python dependenciesProcfile- Railway deployment configrailway.json- Railway settings
cd /Users/officemac/railway-servicetitan-api
git init
git add .
git commit -m "Initial commit: ServiceTitan sync API"Option A: Using Railway CLI
# Install Railway CLI if not installed
npm install -g @railway/cli
# Login to Railway
railway login
# Create new project
railway init
# Deploy
railway upOption B: Using GitHub
- Create a new GitHub repo
- Push this code to GitHub
- Go to Railway dashboard: https://railway.app
- Click "New Project" → "Deploy from GitHub repo"
- Select your repo
- Railway will auto-detect Python and deploy
After deployment, Railway will give you a public URL like:
https://servicetitan-api-production.up.railway.app
GET /healthPOST /sync
Content-Type: application/json
{
"daysBack": 30
}Response:
{
"success": true,
"metrics": {
"jobs_checked": 337,
"unsold_estimates_found": 195,
"total_value": 2530232,
"enriched_with_contacts": 195,
"sent_to_ghl": 195,
"days_back": 30
},
"estimates": [...]
}# Create virtual environment
python3 -m venv venv
source venv/bin/activate
# Install dependencies
pip install -r requirements.txt
# Run locally
python app.pyThen test:
curl http://localhost:5000/health
curl -X POST http://localhost:5000/sync \
-H "Content-Type: application/json" \
-d '{"daysBack": 30}'Once deployed, create a simple 3-node workflow in n8n:
- Schedule Trigger - Run daily at 9am
- HTTP Request - POST to your Railway URL
/sync - Send Success Email - Optional notification
- Method: POST
- URL:
https://your-railway-url.up.railway.app/sync - Body:
{"daysBack": 30} - Headers:
Content-Type: application/json
All credentials are hardcoded in app.py:
- ServiceTitan Client ID, Secret, App Key
- GHL Webhook URL
Security Note: For production, move these to Railway environment variables.