Base URL: http://localhost:8000
Batch 5 adds read-only company and job posting endpoints plus authenticated report and vote writes. Scores are recalculated and snapshotted when reports and votes are created.
Public reads do not require authentication. Report and vote creation require a bearer access token. See auth-api.md.
Deferred to later batches:
- Evidence upload
- Company and job posting create/update/delete (public write APIs)
- Extension backend API integration (deferred)
- Job URL validation API wiring (deferred; offline helper exists from Batch 6D)
- URL-to-posting lookup from extension handoff
Return a paginated list of companies.
Query parameters:
page(default 1)page_size(default 20, max 100)
Response 200:
{
"items": [],
"total": 0,
"page": 1,
"page_size": 20
}Return a company profile.
Response 200: company object matching CompanyResponse.
Errors:
404when the company does not exist
Return the current integrity score breakdown for a company.
Response 200:
{
"score": 72.5,
"breakdown": {
"post_to_hire_ratio": 10.0,
"report_ratio": 18.0
}
}Errors:
404when the company does not exist
Return a job posting profile.
Response 200: posting object matching JobPostingResponse.
Errors:
404when the job posting does not exist
Return the current ghost job risk score breakdown for a posting.
Response 200:
{
"score": 64.0,
"breakdown": {
"posting_age": 12.5,
"repost_history": 8.0
}
}Errors:
404when the job posting does not exist
Submit an integrity report for a job posting. Requires bearer authentication.
Request:
{
"job_posting_id": "uuid",
"report_type": "stale_posting",
"description": "The posting remained active without recruiter follow-up for several months."
}report_type values: ghost_job, no_response, scam, data_harvest, repost_loop, stale_posting, fake_interview
Response 201: report object matching ReportResponse with status: "pending".
Report status values in the schema: pending, verified, dismissed, disputed. New reports start as pending.
Moderation transitions are implemented in Batch 6:
- Admins verify or dismiss reports via
/api/v1/moderation/reports/{id}/verify|dismiss - Verified employers dispute reports by submitting
/api/v1/reports/{id}/responses(movespendingorverified→disputed)
See moderation-api.md and employer-api.md.
Side effects:
- Increments company
report_count - Recalculates job posting and company scores
- Inserts score snapshots
- Writes an audit log entry (
report.created)
Errors:
401when authentication is missing or invalid404when the job posting does not exist422when validation fails
Return a submitted report.
Response 200: report object matching ReportResponse.
Errors:
404when the report does not exist
List reports linked to a job posting.
Query parameters:
job_posting_id(required UUID)page(default 1)page_size(default 20, max 100)
Response 200:
{
"items": [],
"total": 0,
"page": 1,
"page_size": 20
}Errors:
404when the job posting does not exist
Cast a community vote on a report. Requires bearer authentication.
Request:
{
"vote": "up"
}vote values: up, down
Response 201: vote object matching VoteResponse.
Side effects:
- Recalculates job posting and company scores
- Inserts score snapshots
- Writes an audit log entry (
vote.created)
Errors:
401when authentication is missing or invalid404when the report does not exist409when the user already voted on the report (including concurrent duplicate requests)422when validation fails
Score formulas remain defined in scoring-algorithm.md. Batch 5 recalculates scores after report and vote writes and stores historical values in score_snapshots.
Language risk signals default to 0.0 until a future analysis batch adds supported inputs.
Batch 5 writes audit logs for report and vote creation. Batch 6 adds audit logs for employer claim review, report moderation transitions, and employer responses. Read endpoints are not audited.