The trusted marketplace where businesses, AI agents, and individuals hire verified human professionals on demand.
┌─────────────────────────┐ ┌──────────────────────────┐
│ Vercel (Frontend) │ ─────▶ │ Railway (Backend API) │
│ │ API │ │
│ index.html │ calls │ Flask + Gunicorn │
│ style.css │ │ SQLite database │
│ base.css │ │ Python 3.12 │
│ config.js │ │ │
└─────────────────────────┘ └──────────────────────────┘
- Frontend: Static SPA (HTML/CSS/JS) hosted on Vercel
- Backend: Python Flask API hosted on Railway (Docker)
- Database: SQLite (file-based, included in container volume)
cd backend
pip install -r requirements.txt
python server.pyThe API will be running at http://localhost:8080. Test it:
curl http://localhost:8080/health
# → {"status": "ok", "service": "gohirehumans-api"}Seeding is disabled unless SEED_SECRET is configured. Use it only for local/demo setup and unset it in production after controlled setup.
curl -X POST http://localhost:8080/seed \
-H 'Content-Type: application/json' \
-d '{"secret":"YOUR_SEED_SECRET"}'This creates local/demo marketplace records. Do not publish or rely on demo credentials for production.
cd frontend
# Any static file server works:
python -m http.server 3000Open http://localhost:3000 in your browser.
- Go to railway.app and sign in
- Click "New Project" → "Deploy from GitHub Repo"
- Connect your GitHub account and select your repo (or use "Deploy from Local" with the Railway CLI)
- In your Railway project, click on the service
- Go to Settings → Build & Deploy
- Set Root Directory to
backend - Railway will auto-detect the Dockerfile
In the Railway dashboard, go to Variables and add:
| Variable | Value |
|---|---|
PORT |
8080 (Railway usually sets this automatically) |
FLASK_DEBUG |
false |
DATABASE_PATH |
Optional local override. Production prefers /data/gohirehumans.db. |
SQLite needs persistent storage:
- In Railway, click "+ New" → "Volume"
- Mount path:
/data - Do not point production SQLite under
/app;/appis ephemeral.
Railway deploys automatically on push. Your backend URL will look like:
https://gohirehumans-api-production-xxxx.up.railway.app
Only seed a controlled staging/demo environment. Production auto-seeding is disabled by default.
curl -X POST https://YOUR-RAILWAY-URL/seed \
-H 'Content-Type: application/json' \
-d '{"secret":"YOUR_SEED_SECRET"}'Edit frontend/config.js and set your Railway backend URL:
window.GOHIREHUMANS_API_URL = "https://your-railway-backend-url.up.railway.app";Option A: Vercel CLI
cd frontend
npx vercel --prodOption B: GitHub Integration
- Go to vercel.com and sign in
- Click "Add New Project" → import your repo
- Set Root Directory to
frontend - Framework Preset: Other
- Click Deploy
- In Vercel dashboard → Settings → Domains
- Add
gohirehumans.com - Follow the DNS configuration instructions
# Install Railway CLI
npm install -g @railway/cli
# Login
railway login
# Initialize project
cd backend
railway init
# Deploy
railway up
# Get your URL
railway domaingohirehumans-deploy/
├── backend/
│ ├── server.py # Flask server (production wrapper)
│ ├── api_core.py # Core API logic (2600+ lines)
│ ├── requirements.txt # Python dependencies
│ ├── Dockerfile # Container config for Railway
│ ├── railway.toml # Railway deployment config
│ ├── Procfile # Process file (Heroku/Railway)
│ ├── .env.example # Environment variable template
│ └── .gitignore
│
├── frontend/
│ ├── index.html # Single Page Application
│ ├── style.css # Main stylesheet
│ ├── base.css # CSS reset/base
│ ├── config.js # API URL configuration ← EDIT THIS
│ ├── vercel.json # Vercel routing/headers config
│ └── .gitignore
│
└── README.md # This file
| Method | Path | Description |
|---|---|---|
GET |
/health |
Health check |
POST |
/auth/register |
Register new user |
POST |
/auth/login |
Login |
GET |
/profile |
Get current user profile |
GET |
/services |
List service listings |
POST |
/services |
Create a service listing |
GET |
/jobs |
List jobs |
POST |
/jobs |
Create a job |
POST |
/jobs/{id}/apply |
Apply to a job |
POST |
/jobs/{id}/hire |
Hire an applicant |
POST |
/services/{id}/order |
Order a listed service |
POST |
/orders/{id}/approve |
Approve submitted work and release payment |
POST |
/orders/{id}/review |
Leave a review |
POST |
/seed |
Secret-gated local/demo seeding |
GET |
/admin/stats |
Admin statistics |
GoHireHumans includes built-in content safety filters that block:
- 80+ prohibited keywords and phrases
- Inappropriate service categories
- Dark web / illegal content patterns
All task titles and descriptions are automatically screened.
The backend uses the ALLOWED_ORIGINS env var and does not allow wildcard credentials by default. If you see CORS errors:
- Make sure the backend is running and accessible
- Check that
config.jshas the correct backend URL - Ensure there's no trailing slash on the URL
To start fresh locally, delete your local SQLite file and optionally run secret-gated /seed again. Do not delete production /data/gohirehumans.db without a verified backup and restore plan.
If data disappears between deploys, make sure you've attached a persistent volume at /data. The app stores production SQLite at /data/gohirehumans.db.
- Frontend: Vanilla JS SPA, Inter font, CSS custom properties
- Backend: Python 3.12, Flask, Gunicorn, SQLite
- Hosting: Vercel (frontend) + Railway (backend)
- Security: HMAC password hashing, session tokens, rate limiting, content safety filters
- Domain: gohirehumans.com