📡 GoHorse Jobs - API Documentation
Complete API reference with routes, permissions, and modules.
Last Updated: 2026-02-16
Base URL: https://api.gohorsejobs.com/api/v1
Auth: JWT Bearer Token or HttpOnly Cookie
🔐 Authentication
Methods
- Authorization Header:
Authorization: Bearer <token>
- Cookie:
jwt=<token> (HttpOnly, Secure)
Roles
| Role |
Code |
Level |
Description |
| SuperAdmin |
superadmin |
0 |
Platform administrator |
| Admin |
admin |
1 |
Company administrator |
| Recruiter |
recruiter |
2 |
Job poster |
| Candidate |
candidate |
3 |
Candidate |
| Guest |
- |
- |
No authentication |
📋 Module: Authentication
Login
POST /api/v1/auth/login
| Field |
Auth |
Roles |
Description |
| Public |
❌ |
Guest |
Authenticate user |
Request:
{
"identifier": "lol",
"password": "Admin@2025!"
}
Response (200):
{
"token": "eyJhbGciOiJI...",
"user": { "id": 1, "role": "superadmin", "name": "Dr. Horse Expert" }
}
Register Candidate
POST /api/v1/auth/register
| Field |
Auth |
Roles |
Description |
| Public |
❌ |
Guest |
Register new job seeker |
Request:
{
"name": "John Doe",
"email": "john@example.com",
"password": "SecurePass123!"
}
🏢 Module: Companies
Create Company
POST /api/v1/companies
| Field |
Auth |
Roles |
Description |
| Public |
❌ |
Guest |
Register new company |
List Companies
GET /api/v1/companies
| Field |
Auth |
Roles |
Description |
| Smart |
⚪ Optional |
Guest/Admin |
Public list or admin full list |
Update Company Status
PATCH /api/v1/companies/{id}/status
| Field |
Auth |
Roles |
Description |
| Protected |
✅ |
superadmin, admin |
Activate/deactivate company |
👥 Module: Users
Get Current User
GET /api/v1/users/me
| Field |
Auth |
Roles |
Description |
| Protected |
✅ |
Any authenticated |
Get current user profile |
List Users
GET /api/v1/users
| Field |
Auth |
Roles |
Description |
| Protected |
✅ |
superadmin, admin |
List all users |
Create User
POST /api/v1/users
| Field |
Auth |
Roles |
Description |
| Protected |
✅ |
superadmin, admin |
Create new user |
Update User
PATCH /api/v1/users/{id}
| Field |
Auth |
Roles |
Description |
| Protected |
✅ |
Any authenticated |
Update user profile |
Delete User
DELETE /api/v1/users/{id}
| Field |
Auth |
Roles |
Description |
| Protected |
✅ |
superadmin |
Delete user |
List User Roles
GET /api/v1/users/roles
| Field |
Auth |
Roles |
Description |
| Protected |
✅ |
superadmin, admin |
List available roles |
💼 Module: Jobs
List Jobs (Public)
GET /api/v1/jobs
| Field |
Auth |
Roles |
Description |
| Public |
❌ |
Guest |
Search and filter jobs |
Query Parameters:
| Param |
Type |
Description |
q |
string |
Search query (title, description) |
location |
string |
Filter by location |
type |
string |
Employment type filter |
workMode |
string |
onsite, hybrid, remote |
page |
int |
Page number (default: 1) |
limit |
int |
Items per page (default: 20) |
Get Job by ID
GET /api/v1/jobs/{id}
| Field |
Auth |
Roles |
Description |
| Public |
❌ |
Guest |
Get job details |
Create Job
POST /api/v1/jobs
| Field |
Auth |
Roles |
Description |
| Public* |
❌ |
admin, recruiter |
Create new job posting |
Update Job
PUT /api/v1/jobs/{id}
| Field |
Auth |
Roles |
Description |
| Public* |
❌ |
admin, recruiter |
Update job posting |
Delete Job
DELETE /api/v1/jobs/{id}
| Field |
Auth |
Roles |
Description |
| Public* |
❌ |
admin, recruiter |
Delete job posting |
List Jobs for Moderation
GET /api/v1/jobs/moderation
| Field |
Auth |
Roles |
Description |
| Protected |
✅ |
superadmin, admin |
List all jobs for moderation |
Update Job Status
PATCH /api/v1/jobs/{id}/status
| Field |
Auth |
Roles |
Description |
| Protected |
✅ |
superadmin, admin |
Approve/reject/close job |
Duplicate Job
POST /api/v1/jobs/{id}/duplicate
| Field |
Auth |
Roles |
Description |
| Protected |
✅ |
superadmin, admin |
Duplicate job posting |
📝 Module: Applications
Create Application
POST /api/v1/applications
| Field |
Auth |
Roles |
Description |
| Public |
❌ |
Guest/JobSeeker |
Apply to a job |
Request:
{
"job_id": 123,
"name": "John Doe",
"email": "john@example.com",
"phone": "+55 11 99999-9999",
"message": "I am interested in this position...",
"resume_url": "https://..."
}
List Applications
GET /api/v1/applications
| Field |
Auth |
Roles |
Description |
| Public |
❌ |
admin, recruiter |
List applications |
Get Application by ID
GET /api/v1/applications/{id}
| Field |
Auth |
Roles |
Description |
| Public |
❌ |
admin, recruiter |
Get application details |
Update Application Status
PUT /api/v1/applications/{id}/status
| Field |
Auth |
Roles |
Description |
| Public |
❌ |
admin, recruiter |
Update application status |
Request:
{
"status": "hired",
"notes": "Approved after final interview"
}
Status Values:
pending - Awaiting review
reviewed - Seen by recruiter
shortlisted - Selected for interview
rejected - Not selected
hired - Offer accepted
🔔 Module: Notifications
List Notifications
GET /api/v1/notifications
| Field |
Auth |
Roles |
Description |
| Protected |
✅ |
Any authenticated |
Get user notifications |
🏷️ Module: Tags
List Tags
GET /api/v1/tags
| Field |
Auth |
Roles |
Description |
| Protected |
✅ |
superadmin, admin |
List all tags |
Create Tag
POST /api/v1/tags
| Field |
Auth |
Roles |
Description |
| Protected |
✅ |
superadmin, admin |
Create new tag |
Update Tag
PATCH /api/v1/tags/{id}
| Field |
Auth |
Roles |
Description |
| Protected |
✅ |
superadmin, admin |
Update tag |
👤 Module: Candidates
List Candidates
GET /api/v1/candidates
| Field |
Auth |
Roles |
Description |
| Protected |
✅ |
superadmin, admin |
List all candidates |
📊 Module: Audit
List Login Audits
GET /api/v1/audit/logins
| Field |
Auth |
Roles |
Description |
| Protected |
✅ |
superadmin, admin |
Login audit trail |
📦 Module: Storage
Generate Upload URL
POST /api/v1/storage/upload-url
| Field |
Auth |
Roles |
Description |
| Protected |
✅ |
Any authenticated |
Get S3 presigned upload URL |
Generate Download URL
POST /api/v1/storage/download-url
| Field |
Auth |
Roles |
Description |
| Protected |
✅ |
Any authenticated |
Get S3 presigned download URL |
Delete File
DELETE /api/v1/storage/files
| Field |
Auth |
Roles |
Description |
| Protected |
✅ |
Any authenticated |
Delete file from S3 |
📚 Module: Documentation
Swagger UI
GET /docs/
| Field |
Auth |
Roles |
Description |
| Public |
❌ |
Guest |
Interactive API documentation |
🔑 Module: System Credentials
Manage encrypted credentials for external services (Stripe, SMTP, Storage, etc.).
List Configured Services
GET /api/v1/system/credentials
| Field |
Auth |
Roles |
Description |
| Protected |
✅ |
superadmin, admin |
List all configured services (metadata only, no secrets) |
Response (200):
{
"services": [
{
"service_name": "stripe",
"updated_at": "2026-02-23T10:30:00Z",
"updated_by": "admin-uuid",
"is_configured": true
},
{
"service_name": "smtp",
"updated_at": "2026-02-22T14:00:00Z",
"updated_by": "superadmin-uuid",
"is_configured": true
}
]
}
Save Credentials
POST /api/v1/system/credentials
| Field |
Auth |
Roles |
Description |
| Protected |
✅ |
superadmin, admin |
Create or update service credentials |
Request:
{
"serviceName": "stripe",
"payload": {
"secretKey": "sk_live_xxx",
"webhookSecret": "whsec_xxx",
"publishableKey": "pk_live_xxx"
}
}
Response (200):
{
"message": "Credentials saved successfully"
}
Supported Services:
| Service Name |
Fields |
stripe |
secretKey, webhookSecret, publishableKey |
smtp |
host, port, username, password, from_email, from_name, secure |
storage |
endpoint, region, bucket, accessKey, secretKey |
cloudflare_config |
apiToken, zoneId |
firebase |
serviceAccountJson (JSON string) |
appwrite |
endpoint, projectId, apiKey |
lavinmq |
amqpUrl |
cpanel |
host, username, apiToken |
Delete Credentials
DELETE /api/v1/system/credentials/{serviceName}
| Field |
Auth |
Roles |
Description |
| Protected |
✅ |
superadmin, admin |
Delete service credentials |
Response (200):
{
"success": true
}
Security Notes:
- Credentials are encrypted with RSA-OAEP-SHA256 before storage
- Only metadata (service name, timestamps) is returned on list operations
- Actual secret values cannot be retrieved after saving
- Updating credentials overwrites the existing configuration
🔑 Permission Matrix
| Route |
Guest |
JobSeeker |
Recruiter |
CompanyAdmin |
Admin |
SuperAdmin |
POST /auth/login |
✅ |
✅ |
✅ |
✅ |
✅ |
✅ |
POST /auth/register |
✅ |
❌ |
❌ |
❌ |
❌ |
❌ |
GET /jobs |
✅ |
✅ |
✅ |
✅ |
✅ |
✅ |
GET /jobs/{id} |
✅ |
✅ |
✅ |
✅ |
✅ |
✅ |
POST /jobs |
❌ |
❌ |
✅ |
✅ |
✅ |
✅ |
POST /applications |
✅ |
✅ |
❌ |
❌ |
❌ |
❌ |
GET /users/me |
❌ |
✅ |
✅ |
✅ |
✅ |
✅ |
GET /users |
❌ |
❌ |
❌ |
❌ |
✅ |
✅ |
DELETE /users/{id} |
❌ |
❌ |
❌ |
❌ |
❌ |
✅ |
GET /notifications |
❌ |
✅ |
✅ |
✅ |
✅ |
✅ |
GET /audit/logins |
❌ |
❌ |
❌ |
❌ |
✅ |
✅ |
GET /jobs/moderation |
❌ |
❌ |
❌ |
❌ |
✅ |
✅ |
🆔 ID Formats
| Entity |
ID Type |
Example |
| Users |
INT (SERIAL) |
1, 42, 1337 |
| Companies |
INT (SERIAL) |
1, 15, 100 |
| Jobs |
INT (SERIAL) |
1, 500, 2500 |
| Notifications |
UUID v7 |
019438a1-2b3c-7abc-8123-4567890abcdef |
| Tickets |
UUID v7 |
019438a2-3c4d-7xyz-9abc-def0123456789 |
| Payments |
UUID v7 |
019438a3-4e5f-7mno-pqrs-tuvwxyz012345 |
📝 Error Responses
400 Bad Request
{
"error": "Invalid request body",
"details": "Field 'email' is required"
}
401 Unauthorized
{
"error": "Unauthorized",
"message": "Invalid or expired token"
}
403 Forbidden
{
"error": "Forbidden",
"message": "Insufficient permissions"
}
404 Not Found
{
"error": "Not Found",
"message": "Resource not found"
}
500 Internal Server Error
{
"error": "Internal Server Error",
"message": "An unexpected error occurred"
}
📚 Related Documentation