A RESTful API for a job board platform where recruiters can post jobs and applicants can apply without creating accounts.
- Authentication
- Job Management - Create, update and delete job postings
- Smart Filtering - Search and filter jobs by technology, category, salary and location.
- Applications - Apply to job without signing up.
- Email Notifications - Automated status update emails.
- Authorizations - Pundit based permissions.
- Rate Limiting - Protection against spam.
- Resume Upload - Active storage for resume attachments.
- Application Tracking - Status updates - (pending, reviewed, shortlisted, rejected, hired).
- Slack Notifications - Notify your Slack channel when job application status changes.
- OTP Verification - Email based OTP to verify applicants before submission with cooldown and rate limiting.
- Bulk Status Update - Update multiple job application statuses at once.
- Ruby on rails 7.2 (API only).
- PostgreSQL.
- ActiveStorage for file uploads.
- ActionMailer for emails.
- Pundit for authorization.
- Devise and Devise token auth.
- Redis for OTP caching and Sidekiq.
- Sidekiq for background jobs.
- Ruby 3.2.2
- PostgreSQL
- Node.js (for ActiveStorage)
- Redis
# Clone the repository
git clone https://github.com/mayankagnihotri7/hiring_compass.git
cd hiring-compass
# Install dependencies
bundle install
# Setup database
rails db:create db:migrate db:seed
# Start Redis (must be running before the server)
redis-server
# Start Sidekiq (in a separate terminal tab/window)
bundle exec sidekiq
# Start the server
rails sThe API will be available at http://localhost:3000
If you prefer Docker, you can spin up the entire stack with a single command.
git clone https://github.com/mayankagnihotri7/hiring_compass.git
cd hiring-compass
cp .env.example .env
docker compose upThis starts Rails, PostgreSQL, Redis and Sidekiq together. The API will be available at http://localhost:3000
Create a .env file in the directory:
SLACK_WEBHOOK_URL=https://hooks.slack.com/services/xxx/yyy/zzz
SLACK_WEBHOOK_URL is optional. If not set, Slack notifications are silently skipped.
Certain endpoints require authentication for actions for who post jobs, update, etc.
GET /api/v1/jobs
Query Parameters
q- Search by title or company.category- Filter by category (tech, marketing, sales, design, product, finance, operations).technology- Filter by technology name.location- Filter by location.min_salary- Minimum salary.max_salary- Maximum salary.years_of_experience- Maximum years required.status- Job status (open, closed, paused).
Example GET /api/v1/jobs?category=tech&technology=ruby&min_salary=8000
GET /api/v1/jobs/:id
POST /api/v1/jobs
Request body:
{
"job": {
"title": "Senior Ruby Developer",
"description": "We're looking for...",
"company_name": "Wayne Corp",
"category": "tech",
"location": "Gotham City",
"status": "open",
"currency": "USD",
"min_salary": "80000",
"max_salary": "120000",
"years_of_experience": 5,
"technologies": [{ "name": "ruby" }, { "name": "rails" }]
}
}PUT /api/v1/jobs/:id
Same request body as create.
DELETE /api/v1/jobs/:id
GET /api/v1/categories
{
"categories": [
"tech",
"sales",
"marketing",
"design",
"product",
"finance",
"operations"
]
}GET /api/v1/technologies
POST /api/v1/jobs/:job_id/job_applications/send_otp
An OTP is sent to the applicant's email before submission. The OTP is valid for 15 minutes. Requests are rate limited to 3 sends per 15 minutes per email with 60 second cooldown between sends.
GET /api/v1/jobs/:job_id/job_applications
POST /api/v1/jobs/:job_id/job_applications
Request (multipart/form-data):
job_application[first_name]: Bruce
job_application[last_name]: Wayne
job_application[email]: brucewayne@waynecorp.org
job_application[phone_number]: +1 555 123 4567
job_application[years_of_experience]: 5
job_application[visa_sponsorship_required]: false
resume: <file>
GET /api/v1/jobs/:job_id/job_applications/:id
PUT /api/v1/jobs/:job_id/job_applications/:id
Request body
{
"status": "shortlisted"
}Available statuses: pending, reviewed, shortlisted, rejected, hired, withdrawn.
PATCH /api/v1/jobs/:job_id/job_applications/bulk_update_status
Update multiple job applications for a job in a single request. Only job applications belonging to tech specified job are updated. Invalid IDs are silently skipped.
Request body
{
"job_application": {
"ids": [1, 2, 3],
"status": "rejected"
}
}Response
{
"message": "Job Applications updated."
}GET /api/v1/:job_id/job_applications/:id/download
Applicants receive emails when:
- Application is received (automatic).
- Status is updated to reviewed, shortlisted, rejected or hired.
- Only job owners or admin can update/delete their jobs.
- Only job owners can view and update applications for their jobs.
- Anyone can view open jobs and apply.
- API requests are rate limited to prevent abuse.
- Limits vary by endpoint.
- OTP requests are limited to 3 sends per 15 minutes per email with a 60 second cooldown.
- When a job application status is updated, a notification is sent to your configured Slack channel.
- Set
SLACK_WEBHOOK_URLin.envto enable this. - To get a webhook URL, go to
Apps -> Incoming Webhooks -> Add to Slackin your Slack workspace, pick a channel and copy the webhook URL.
rspecrails db:seedThis creates sample users, jobs, technologies and applications.
Please see CONTRIBUTING.md
This project is open source and licensed under the MIT license.