{"openapi":"3.1.0","info":{"title":"HuntLog API","description":"Job Application Tracker API — track applications, enforce lifecycle transitions, and get analytics on your job search progress.","contact":{"name":"Prajwal Banakar","url":"https://prajwal-banakar.me","email":"prajwal.banakara@gmail.com"},"version":"1.0.0"},"servers":[{"url":"https://huntlog-coga.onrender.com","description":"Generated server url"}],"security":[{"Bearer Authentication":[]}],"tags":[{"name":"Analytics","description":"Job search statistics for the authenticated user"},{"name":"Authentication","description":"Register and login endpoints"},{"name":"Job Applications","description":"Create and manage job applications with state machine-validated status transitions"},{"name":"User Preferences","description":"Manage user account settings"}],"paths":{"/api/v1/users/me/preferences":{"get":{"tags":["User Preferences"],"summary":"Get user preferences","description":"Retrieve current notification and account preferences.","operationId":"getPreferences","responses":{"200":{"description":"Preferences retrieved successfully","content":{"*/*":{"schema":{"$ref":"#/components/schemas/UserPreferencesResponse"}}}}},"security":[{"Bearer Authentication":[]}]},"put":{"tags":["User Preferences"],"summary":"Update email preferences","description":"Enable or disable automated follow-up email reminders for stale applications.","operationId":"updatePreferences","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdatePreferencesRequest"}}},"required":true},"responses":{"200":{"description":"Preferences updated successfully","content":{"*/*":{"schema":{"$ref":"#/components/schemas/UserPreferencesResponse"}}}}},"security":[{"Bearer Authentication":[]}]}},"/api/v1/applications/{id}":{"get":{"tags":["Job Applications"],"summary":"Get application by ID","operationId":"getById","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"Application found","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApplicationResponse"}}}},"404":{"description":"Application not found or belongs to another user","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApplicationResponse"}}}}},"security":[{"Bearer Authentication":[]}]},"put":{"tags":["Job Applications"],"summary":"Update an application","description":"Update status, notes, or other fields. Status transitions are validated — invalid transitions return 422 with allowed transitions listed.","operationId":"update","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateApplicationRequest"}}},"required":true},"responses":{"200":{"description":"Application updated successfully","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApplicationResponse"}}}},"404":{"description":"Application not found","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApplicationResponse"}}}},"422":{"description":"Invalid status transition","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApplicationResponse"}}}}},"security":[{"Bearer Authentication":[]}]},"delete":{"tags":["Job Applications"],"summary":"Delete an application","operationId":"delete","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"204":{"description":"Application deleted"},"404":{"description":"Application not found"}},"security":[{"Bearer Authentication":[]}]}},"/api/v1/auth/register":{"post":{"tags":["Authentication"],"summary":"Register a new user","description":"Creates a new user account and returns a JWT token immediately. No separate login step required.","operationId":"register","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterRequest"}}},"required":true},"responses":{"201":{"description":"User registered successfully","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AuthResponse"}}}},"409":{"description":"Email already registered","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AuthResponse"}}}},"400":{"description":"Validation errors","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AuthResponse"}}}}}}},"/api/v1/auth/login":{"post":{"tags":["Authentication"],"summary":"Login","description":"Authenticates user credentials and returns a JWT token valid for 24 hours.","operationId":"login","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginRequest"}}},"required":true},"responses":{"200":{"description":"Login successful","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AuthResponse"}}}},"401":{"description":"Invalid credentials","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AuthResponse"}}}}}}},"/api/v1/applications":{"get":{"tags":["Job Applications"],"summary":"List all applications","description":"Returns paginated applications for the authenticated user. Filter by status or company name.","operationId":"getAll","parameters":[{"name":"status","in":"query","description":"Filter by application status","required":false,"schema":{"type":"string","enum":["APPLIED","SCREENING","INTERVIEW","OFFER","ACCEPTED","REJECTED","WITHDRAWN"]}},{"name":"company","in":"query","description":"Case-insensitive company name search","required":false,"schema":{"type":"string"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":0},"example":0},{"name":"size","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":10,"maximum":50},"example":10},{"name":"sort","in":"query","required":false,"schema":{"type":"string","default":"lastUpdated,desc"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PageApplicationResponse"}}}}},"security":[{"Bearer Authentication":[]}]},"post":{"tags":["Job Applications"],"summary":"Create a new job application","description":"Creates an application with status=APPLIED. The response includes allowedNextStatuses showing valid next states.","operationId":"create","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApplicationRequest"}}},"required":true},"responses":{"201":{"description":"Application created successfully","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApplicationResponse"}}}}},"security":[{"Bearer Authentication":[]}]}},"/api/v1/analytics":{"get":{"tags":["Analytics"],"summary":"Get job search analytics","description":"Returns statistics including total applications, breakdown by status, response rate, weekly/monthly counts, and top companies.","operationId":"getAnalytics","responses":{"200":{"description":"Analytics retrieved successfully","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AnalyticsResponse"}}}}},"security":[{"Bearer Authentication":[]}]}},"/api/v1/users/me":{"delete":{"tags":["User Preferences"],"summary":"Delete user account","description":"Permanently delete user account and all associated applications.","operationId":"deleteAccount","responses":{"204":{"description":"Account deleted successfully"}},"security":[{"Bearer Authentication":[]}]}}},"components":{"schemas":{"UpdatePreferencesRequest":{"type":"object","description":"Request body to update user notification preferences","properties":{"emailRemindersEnabled":{"type":"boolean","description":"Whether to receive email reminders for stale pending applications","example":true}},"required":["emailRemindersEnabled"]},"UserPreferencesResponse":{"type":"object","description":"User notification preferences","properties":{"emailRemindersEnabled":{"type":"boolean","description":"Whether email reminders are enabled","example":true}}},"UpdateApplicationRequest":{"type":"object","description":"Request body to update an existing job application","properties":{"status":{"type":"string","description":"Target application status. Transition is validated by the state machine.","enum":["APPLIED","SCREENING","INTERVIEW","OFFER","ACCEPTED","REJECTED","WITHDRAWN"],"example":"SCREENING"},"company":{"type":"string","description":"Updated company name","example":"Google","maxLength":100,"minLength":0},"role":{"type":"string","description":"Updated job role or title","example":"Software Engineer I","maxLength":100,"minLength":0},"notes":{"type":"string","description":"Updated notes","example":"Completed technical phone screen","maxLength":2000,"minLength":0},"jobUrl":{"type":"string","description":"Updated job posting URL","example":"https://careers.google.com/123","maxLength":500,"minLength":0},"location":{"type":"string","description":"Updated work location","example":"Remote","maxLength":100,"minLength":0}}},"ApplicationResponse":{"type":"object","description":"Job application with current status and allowed next transitions","properties":{"id":{"type":"integer","format":"int64"},"company":{"type":"string"},"role":{"type":"string"},"status":{"type":"string","enum":["APPLIED","SCREENING","INTERVIEW","OFFER","ACCEPTED","REJECTED","WITHDRAWN"]},"appliedDate":{"type":"string","format":"date"},"lastUpdated":{"type":"string","format":"date-time"},"jobUrl":{"type":"string"},"notes":{"type":"string"},"location":{"type":"string"},"allowedNextStatuses":{"type":"array","description":"Valid status transitions from current status. Use these values when calling PUT /api/v1/applications/{id}","example":["SCREENING","REJECTED","WITHDRAWN"],"items":{"type":"string","enum":["APPLIED","SCREENING","INTERVIEW","OFFER","ACCEPTED","REJECTED","WITHDRAWN"]}}}},"RegisterRequest":{"type":"object","description":"Request body to register a new user account","properties":{"name":{"type":"string","description":"User's full name","example":"John Doe","maxLength":100,"minLength":0},"email":{"type":"string","description":"User's unique email address","example":"john@example.com","maxLength":150,"minLength":0},"password":{"type":"string","description":"Account password (minimum 8 characters)","example":"password123","maxLength":2147483647,"minLength":8}},"required":["email","name","password"]},"AuthResponse":{"type":"object","description":"Authentication response containing JWT token and user info","properties":{"token":{"type":"string","description":"JWT bearer token for authenticating subsequent requests","example":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."},"email":{"type":"string","description":"User email address","example":"john@example.com"},"name":{"type":"string","description":"User full name","example":"John Doe"}}},"LoginRequest":{"type":"object","description":"Request body to authenticate a user","properties":{"email":{"type":"string","description":"User email address","example":"john@example.com"},"password":{"type":"string","description":"User password","example":"password123"}},"required":["email","password"]},"CreateApplicationRequest":{"type":"object","description":"Request body to create a new job application","properties":{"company":{"type":"string","description":"Company name","example":"Google","maxLength":100,"minLength":0},"role":{"type":"string","description":"Job role or title","example":"Software Engineer I","maxLength":100,"minLength":0},"jobUrl":{"type":"string","description":"URL of the job posting","example":"https://careers.google.com/123","maxLength":500,"minLength":0},"notes":{"type":"string","description":"Additional notes or context","example":"Applied via referral","maxLength":2000,"minLength":0},"location":{"type":"string","description":"Work location or remote status","example":"Mountain View, CA","maxLength":100,"minLength":0},"appliedDate":{"type":"string","format":"date","description":"Date application was submitted (defaults to today if null)"}},"required":["company","role"]},"PageApplicationResponse":{"type":"object","properties":{"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"first":{"type":"boolean"},"last":{"type":"boolean"},"numberOfElements":{"type":"integer","format":"int32"},"pageable":{"$ref":"#/components/schemas/PageableObject"},"size":{"type":"integer","format":"int32"},"content":{"type":"array","items":{"$ref":"#/components/schemas/ApplicationResponse"}},"number":{"type":"integer","format":"int32"},"sort":{"$ref":"#/components/schemas/SortObject"},"empty":{"type":"boolean"}}},"PageableObject":{"type":"object","properties":{"unpaged":{"type":"boolean"},"pageNumber":{"type":"integer","format":"int32"},"paged":{"type":"boolean"},"pageSize":{"type":"integer","format":"int32"},"offset":{"type":"integer","format":"int64"},"sort":{"$ref":"#/components/schemas/SortObject"}}},"SortObject":{"type":"object","properties":{"unsorted":{"type":"boolean"},"sorted":{"type":"boolean"},"empty":{"type":"boolean"}}},"AnalyticsResponse":{"type":"object","description":"Aggregated job search statistics for the authenticated user","properties":{"totalApplications":{"type":"integer","format":"int64"},"byStatus":{"type":"object","additionalProperties":{"type":"integer","format":"int64"}},"appliedThisWeek":{"type":"integer","format":"int64"},"appliedThisMonth":{"type":"integer","format":"int64"},"responseRate":{"type":"number","format":"double"},"averageDaysToFirstUpdate":{"type":"number","format":"double"},"oldestPendingDays":{"type":"integer","format":"int64"},"topCompaniesByApplications":{"type":"array","items":{"$ref":"#/components/schemas/CompanyCountResponse"}}}},"CompanyCountResponse":{"type":"object","description":"Count of applications by company","properties":{"company":{"type":"string","description":"Company name","example":"Google"},"count":{"type":"integer","format":"int64","description":"Total number of applications submitted to this company","example":3}}}},"securitySchemes":{"Bearer Authentication":{"type":"http","description":"Enter your JWT token. Get it from POST /api/v1/auth/login","scheme":"bearer","bearerFormat":"JWT"}}}}