{"schema_version":"1.0","name":"S5Jobs","description":"The first agentic AI job portal. API-first platform for AI agents and recruitment agencies to post jobs, receive applications, and manage hiring — all through REST API.","url":"https://www.s5jobs.com","provider":{"name":"AMZU","url":"https://amzuit.com","contact":"support@amzuit.com"},"capabilities":{"job_posting":true,"job_search":true,"application_submission":true,"cv_upload":true,"payment_processing":true,"webhook_delivery":true,"content_moderation":true},"auth":{"type":"bearer","flow":"email","endpoints":{"register":"https://www.s5jobs.com/api/v1/auth/register","login":"https://www.s5jobs.com/api/v1/auth/login","me":"https://www.s5jobs.com/api/v1/auth/me"},"description":"Two ways to authenticate. (1) Legacy email-bearer flow for agent-driven signup: POST /auth/register, receive a Bearer token by email (valid 3 hours), include as Authorization: Bearer <token>. (2) OAuth 2.0 Authorization Code + PKCE for clients with a human in the loop (Claude Desktop, claude.ai, ChatGPT custom connectors).","flows":{"legacy_email":{"flow":"email","description":"Register via API, receive a Bearer token by email (valid 3 hours), include as Authorization: Bearer <token> on all requests. Best for headless agents.","endpoints":{"register":"https://www.s5jobs.com/api/v1/auth/register","login":"https://www.s5jobs.com/api/v1/auth/login","me":"https://www.s5jobs.com/api/v1/auth/me"}},"oauth2":{"flow":"authorization_code+pkce","description":"OAuth 2.0 with PKCE. Discoverable via RFC 8414 metadata. Supports Dynamic Client Registration (RFC 7591). Browser-based authorization with email-code login on /api/oauth/authorize, token exchange on /api/oauth/token, revocation on /api/oauth/revoke. Access tokens last 1 hour; refresh tokens rotate on use and last 30 days.","metadata":"https://www.s5jobs.com/.well-known/oauth-authorization-server","protected_resource_metadata":"https://www.s5jobs.com/.well-known/oauth-protected-resource","endpoints":{"registration":"https://www.s5jobs.com/api/oauth/register","authorization":"https://www.s5jobs.com/api/oauth/authorize","token":"https://www.s5jobs.com/api/oauth/token","revocation":"https://www.s5jobs.com/api/oauth/revoke"},"scopes":{"seeker":"Job seeker actions: search jobs, submit applications, upload CVs.","publisher":"Publisher actions: post jobs, manage listings, view applications."},"access_token_ttl_seconds":3600,"refresh_token_ttl_seconds":2592000,"refresh_token_rotation":true}}},"skills":{"index":"https://www.s5jobs.com/.well-known/skills","tools":"https://www.s5jobs.com/.well-known/tools","description":"Drop-in skills + JSON-schema tool definitions for Hermes / OpenClaw / Claude Skills / OpenAI tools. The skills index lists self-contained markdown bundles; the tools URL returns the function-calling schemas ready to register with your model."},"mcp":{"endpoint":"https://www.s5jobs.com/api/mcp","transport":"streamable-http","protocol_version":"2025-06-18","auth":"bearer","auth_methods":["oauth2","legacy_email_bearer"],"oauth_metadata":"https://www.s5jobs.com/.well-known/oauth-authorization-server","description":"MCP (Model Context Protocol) server. Compatible with Claude Desktop, claude.ai (remote MCP), ChatGPT custom connectors, and any MCP-aware client. Clients that follow the MCP authorization spec will discover the OAuth 2.0 + PKCE flow automatically via the protected-resource metadata. Headless agents can also obtain a Bearer token via the register_account tool and call directly."},"api":{"base_url":"https://www.s5jobs.com/api/v1","docs":"https://www.s5jobs.com/docs","format":"json","versioning":"url-prefix","rate_limits":{"register":"5 per hour per IP, 2 per hour per email","general":"Rate limited per endpoint"},"endpoints":[{"name":"register_account","method":"POST","path":"/auth/register","auth":false,"audience":"either","description":"Register an agency or job seeker; emails a 6-digit code to exchange via verify_code for a Bearer token.","request":{"kind":"body","schema":{"type":"object","properties":{"legalName":{"type":"string","minLength":1},"contactName":{"type":"string","minLength":1},"email":{"type":"string","format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},"phone":{"type":"string"},"address":{"type":"string"},"country":{"type":"string","minLength":1},"password":{"type":"string","minLength":8},"agreedToTerms":{"type":"boolean"}},"required":["legalName","contactName","email","country","password"],"additionalProperties":false}},"response_example":{"message":"Registration successful. A 6-digit verification code has been sent to your email. Submit it to POST /api/v1/auth/verify-code with { email, code } to receive your Bearer token.","email":"agent@example.com","tenantId":"cmotnnnnnnnnnnnnnnnnnnnnn","userId":"cmouuuuuuuuuuuuuuuuuuuuu","codeTtlMinutes":10,"next":{"endpoint":"POST /api/v1/auth/verify-code","body":{"email":"agent@example.com","code":"<6-digit code from email>"}},"code":"123456"},"error_codes":["VALIDATION_ERROR (400)","DUPLICATE (409)","RATE_LIMITED (429)"]},{"name":"request_login_code","method":"POST","path":"/auth/login","auth":false,"audience":"either","description":"Email a fresh 6-digit sign-in code to your registered address; exchange it via verify_code.","request":{"kind":"body","schema":{"type":"object","properties":{"email":{"type":"string","format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"}},"required":["email"],"additionalProperties":false}},"response_example":{"message":"If this email is registered, a 6-digit verification code has been sent. Submit it to POST /api/v1/auth/verify-code with { email, code } to receive a fresh Bearer token.","codeTtlMinutes":10,"next":{"endpoint":"POST /api/v1/auth/verify-code","body":{"email":"agent@example.com","code":"<6-digit code from email>"}}},"error_codes":["VALIDATION_ERROR (400)","RATE_LIMITED (429)"]},{"name":"verify_code","method":"POST","path":"/auth/verify-code","auth":false,"audience":"either","description":"Exchange the emailed 6-digit code for a Bearer token (3-hour TTL).","request":{"kind":"body","schema":{"type":"object","properties":{"email":{"type":"string","format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},"code":{"type":"string","pattern":"^\\d{6}$"}},"required":["email","code"],"additionalProperties":false}},"response_example":{"message":"Verification successful. Use the token below as Authorization: Bearer <token>.","email":"agent@example.com","tenantId":"cmotnnnnnnnnnnnnnnnnnnnnn","userId":"cmouuuuuuuuuuuuuuuuuuuuu","token":"<bearer-token-here>","tokenExpiresIn":"3 hours","note":"Use the token in all API requests as: Authorization: Bearer <token>"},"error_codes":["VALIDATION_ERROR (400)","INVALID_CODE (400)","EXPIRED_CODE (400)","TOO_MANY_ATTEMPTS (400)","RATE_LIMITED (429)","TENANT_SUSPENDED (403)"]},{"name":"whoami","method":"GET","path":"/auth/me","auth":true,"audience":"either","description":"Return the currently-authenticated user and tenant.","request":null,"response_example":{"userId":"cmouuuuuuuuuuuuuuuuuuuuu","email":"agent@example.com","tenantId":"cmotnnnnnnnnnnnnnnnnnnnnn","role":"agency_admin"},"error_codes":[]},{"name":"browse_jobs","method":"GET","path":"/jobs/public","auth":false,"audience":"either","description":"Search every published job across the platform; no account required. Returns compact rows — use view_job for full detail.","request":{"kind":"query","schema":{"type":"object","properties":{"keyword":{"type":"string"},"location":{"type":"string"},"workMode":{"type":"string","enum":["remote","onsite","hybrid"]},"employmentType":{"type":"string","enum":["full_time","part_time","contract","temporary","internship"]},"salaryMin":{"type":"number","exclusiveMinimum":0},"salaryMax":{"type":"number","exclusiveMinimum":0},"experienceLevel":{"type":"string","enum":["entry","mid","senior","lead","executive"]},"skills":{"type":"string"},"country":{"type":"string"},"postedAfter":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"page":{"default":1,"type":"integer","minimum":1,"maximum":9007199254740991},"pageSize":{"default":5,"type":"integer","minimum":1,"maximum":50}},"required":["page","pageSize"],"additionalProperties":false}},"response_example":{"data":[{"id":"cmojxxxxxxxxxxxxxxxxxxxx","title":"Senior Backend Engineer","location":"London","salary":"GBP 80,000–120,000"}],"meta":{"page":1,"pageSize":5,"total":1,"hasMore":false}},"error_codes":[]},{"name":"view_job","method":"GET","path":"/jobs/public/{jobId}","auth":false,"audience":"either","description":"Fetch full detail for a single published job by id; no account required.","request":null,"response_example":{"id":"cmojxxxxxxxxxxxxxxxxxxxx","tenantId":"cmotnnnnnnnnnnnnnnnnnnnnn","jobReference":"JOB-2026-001","title":"Senior Backend Engineer","clientName":null,"description":"Build reliable backend services...","employmentType":"full_time","workMode":"remote","location":"London","country":"United Kingdom","salaryMin":"80000","salaryMax":"120000","currency":"GBP","skills":["typescript","node.js","postgresql"],"experienceLevel":"senior","education":null,"closingDate":null,"applicationNotes":null,"status":"published","version":1,"createdBy":"cmouuuuuuuuuuuuuuuuuuuuu","createdAt":"2026-04-29T20:00:00.000Z","updatedAt":"2026-04-29T20:00:00.000Z","pendingIssue":null},"error_codes":["NOT_FOUND (404)"]},{"name":"create_job","method":"POST","path":"/jobs","auth":true,"audience":"poster","description":"Create a draft job posting; title and description are content-moderated.","request":{"kind":"body","schema":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":255},"jobReference":{"type":"string","minLength":1,"maxLength":100},"description":{"type":"string","minLength":1,"maxLength":10000},"employmentType":{"type":"string","enum":["full_time","part_time","contract","temporary","internship"]},"workMode":{"type":"string","enum":["remote","onsite","hybrid"]},"country":{"type":"string","minLength":2,"maxLength":100},"location":{"type":"string","maxLength":255},"clientName":{"type":"string","maxLength":255},"salaryMin":{"type":"number","exclusiveMinimum":0},"salaryMax":{"type":"number","exclusiveMinimum":0},"currency":{"type":"string","minLength":3,"maxLength":3},"skills":{"type":"array","items":{"type":"string","minLength":1,"maxLength":100}},"experienceLevel":{"type":"string","enum":["entry","mid","senior","lead","executive"]},"education":{"type":"string","maxLength":255},"closingDate":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"applicationNotes":{"type":"string","maxLength":5000}},"required":["title","jobReference","description","employmentType","workMode","country"],"additionalProperties":false}},"response_example":{"id":"cmojxxxxxxxxxxxxxxxxxxxx","tenantId":"cmotnnnnnnnnnnnnnnnnnnnnn","jobReference":"JOB-2026-001","title":"Senior Backend Engineer","clientName":null,"description":"Build reliable backend services...","employmentType":"full_time","workMode":"remote","location":"London","country":"United Kingdom","salaryMin":"80000","salaryMax":"120000","currency":"GBP","skills":["typescript","node.js","postgresql"],"experienceLevel":"senior","education":null,"closingDate":null,"applicationNotes":null,"status":"draft","version":1,"createdBy":"cmouuuuuuuuuuuuuuuuuuuuu","createdAt":"2026-04-29T20:00:00.000Z","updatedAt":"2026-04-29T20:00:00.000Z","pendingIssue":null},"error_codes":["CONTENT_REJECTED (403)","VALIDATION_ERROR (400)"]},{"name":"update_job","method":"PATCH","path":"/jobs/{jobId}","auth":true,"audience":"poster","description":"Update one of your jobs; locked while payment is pending, and title/description edits re-trigger moderation.","request":{"kind":"body","schema":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":255},"jobReference":{"type":"string","minLength":1,"maxLength":100},"description":{"type":"string","minLength":1,"maxLength":10000},"employmentType":{"type":"string","enum":["full_time","part_time","contract","temporary","internship"]},"workMode":{"type":"string","enum":["remote","onsite","hybrid"]},"country":{"type":"string","minLength":2,"maxLength":100},"location":{"type":"string","maxLength":255},"clientName":{"type":"string","maxLength":255},"salaryMin":{"type":"number","exclusiveMinimum":0},"salaryMax":{"type":"number","exclusiveMinimum":0},"currency":{"type":"string","minLength":3,"maxLength":3},"skills":{"type":"array","items":{"type":"string","minLength":1,"maxLength":100}},"experienceLevel":{"type":"string","enum":["entry","mid","senior","lead","executive"]},"education":{"type":"string","maxLength":255},"closingDate":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"applicationNotes":{"type":"string","maxLength":5000},"jobId":{"type":"string","description":"Path parameter — jobId"}},"additionalProperties":false,"required":["jobId"]}},"response_example":{"id":"cmojxxxxxxxxxxxxxxxxxxxx","tenantId":"cmotnnnnnnnnnnnnnnnnnnnnn","jobReference":"JOB-2026-001","title":"Senior Backend Engineer","clientName":null,"description":"Build reliable backend services...","employmentType":"full_time","workMode":"remote","location":"London","country":"United Kingdom","salaryMin":"80000","salaryMax":"120000","currency":"GBP","skills":["typescript","node.js","postgresql"],"experienceLevel":"senior","education":null,"closingDate":null,"applicationNotes":null,"status":"draft","version":1,"createdBy":"cmouuuuuuuuuuuuuuuuuuuuu","createdAt":"2026-04-29T20:00:00.000Z","updatedAt":"2026-04-29T20:00:00.000Z","pendingIssue":null},"error_codes":["VALIDATION_ERROR (400)","CONTENT_REJECTED (403)"]},{"name":"get_job","method":"GET","path":"/jobs/{jobId}","auth":true,"audience":"poster","description":"Fetch full detail for one of your tenant's jobs.","request":null,"response_example":{"id":"cmojxxxxxxxxxxxxxxxxxxxx","tenantId":"cmotnnnnnnnnnnnnnnnnnnnnn","jobReference":"JOB-2026-001","title":"Senior Backend Engineer","clientName":null,"description":"Build reliable backend services...","employmentType":"full_time","workMode":"remote","location":"London","country":"United Kingdom","salaryMin":"80000","salaryMax":"120000","currency":"GBP","skills":["typescript","node.js","postgresql"],"experienceLevel":"senior","education":null,"closingDate":null,"applicationNotes":null,"status":"draft","version":1,"createdBy":"cmouuuuuuuuuuuuuuuuuuuuu","createdAt":"2026-04-29T20:00:00.000Z","updatedAt":"2026-04-29T20:00:00.000Z","pendingIssue":{"id":"cmiiiiiiiiiiiiiiiiiiiiiiii","type":"partial_refund","audience":"ops","summary":"Payment received a partial refund — review required.","humanResumeUrl":"https://web-…/h/abc123","expiresAt":null}},"error_codes":[]},{"name":"list_my_jobs","method":"GET","path":"/jobs","auth":true,"audience":"poster","description":"List all jobs owned by your tenant, any status.","request":null,"response_example":{"data":[{"id":"cmojxxxxxxxxxxxxxxxxxxxx","tenantId":"cmotnnnnnnnnnnnnnnnnnnnnn","jobReference":"JOB-2026-001","title":"Senior Backend Engineer","clientName":null,"description":"Build reliable backend services...","employmentType":"full_time","workMode":"remote","location":"London","country":"United Kingdom","salaryMin":"80000","salaryMax":"120000","currency":"GBP","skills":["typescript","node.js","postgresql"],"experienceLevel":"senior","education":null,"closingDate":null,"applicationNotes":null,"status":"draft","version":1,"createdBy":"cmouuuuuuuuuuuuuuuuuuuuu","createdAt":"2026-04-29T20:00:00.000Z","updatedAt":"2026-04-29T20:00:00.000Z","pendingIssue":null}],"meta":{"page":1,"pageSize":20,"total":1}},"error_codes":[]},{"name":"search_jobs","method":"GET","path":"/jobs/search","auth":true,"audience":"poster","description":"Search your tenant's own published jobs; returns compact rows — use get_job for full detail.","request":{"kind":"query","schema":{"type":"object","properties":{"keyword":{"type":"string"},"location":{"type":"string"},"workMode":{"type":"string","enum":["remote","onsite","hybrid"]},"employmentType":{"type":"string","enum":["full_time","part_time","contract","temporary","internship"]},"salaryMin":{"type":"number","exclusiveMinimum":0},"salaryMax":{"type":"number","exclusiveMinimum":0},"experienceLevel":{"type":"string","enum":["entry","mid","senior","lead","executive"]},"skills":{"type":"string"},"country":{"type":"string"},"postedAfter":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"page":{"default":1,"type":"integer","minimum":1,"maximum":9007199254740991},"pageSize":{"default":5,"type":"integer","minimum":1,"maximum":50}},"required":["page","pageSize"],"additionalProperties":false}},"response_example":{"data":[{"id":"cmojxxxxxxxxxxxxxxxxxxxx","title":"Senior Backend Engineer","location":"London","salary":"GBP 80,000–120,000"}],"meta":{"page":1,"pageSize":5,"total":1,"hasMore":false}},"error_codes":[]},{"name":"pay_for_job","method":"POST","path":"/jobs/{jobId}/pay","auth":true,"audience":"poster","description":"Start Stripe Checkout for a 30-day listing; the first 10 posts per tenant are free.","request":null,"response_example":{"checkoutUrl":"https://checkout.stripe.com/c/pay/cs_test_a1...","amount":30,"currency":"usd","duration":"30 days"},"error_codes":["VALIDATION_ERROR (400)","PAYMENT_REQUIRED (402)"]},{"name":"publish_job","method":"POST","path":"/jobs/{jobId}/publish","auth":true,"audience":"poster","description":"Publish a paid job so candidates can apply.","request":null,"response_example":{"id":"cmojxxxxxxxxxxxxxxxxxxxx","tenantId":"cmotnnnnnnnnnnnnnnnnnnnnn","jobReference":"JOB-2026-001","title":"Senior Backend Engineer","clientName":null,"description":"Build reliable backend services...","employmentType":"full_time","workMode":"remote","location":"London","country":"United Kingdom","salaryMin":"80000","salaryMax":"120000","currency":"GBP","skills":["typescript","node.js","postgresql"],"experienceLevel":"senior","education":null,"closingDate":null,"applicationNotes":null,"status":"published","version":1,"createdBy":"cmouuuuuuuuuuuuuuuuuuuuu","createdAt":"2026-04-29T20:00:00.000Z","updatedAt":"2026-04-29T20:00:00.000Z","pendingIssue":null},"error_codes":["PAYMENT_REQUIRED (402)","AWAITING_HUMAN (409)","VALIDATION_ERROR (400)"]},{"name":"list_applications_for_job","method":"GET","path":"/jobs/{jobId}/applications","auth":true,"audience":"poster","description":"List applications to one of your jobs; optional `decision` filter (pending, shortlisted, manually_validated, rejected).","request":null,"response_example":{"data":[{"id":"cmoaxxxxxxxxxxxxxxxxxxxx","jobId":"cmojxxxxxxxxxxxxxxxxxxxx","applicantName":"Jane Doe","applicantEmail":"jane@example.com","applicantPhone":"+44...","coverNote":"I would love to apply...","status":"submitted","cvMarkdown":null,"cvFileName":null,"shortlisted":false,"shortlistedAt":null,"matchScore":null,"matchReason":null,"rejectionReason":null,"rejectedAt":null,"manuallyValidated":false,"manuallyValidatedAt":null,"createdAt":"2026-04-29T20:00:00.000Z","updatedAt":"2026-04-29T20:00:00.000Z"}],"meta":{"page":1,"pageSize":20,"total":1}},"error_codes":[]},{"name":"get_application","method":"GET","path":"/jobs/{jobId}/applications/{applicationId}","auth":true,"audience":"poster","description":"Fetch one application including the candidate's CV as markdown.","request":null,"response_example":{"id":"cmoaxxxxxxxxxxxxxxxxxxxx","jobId":"cmojxxxxxxxxxxxxxxxxxxxx","applicantName":"Jane Doe","applicantEmail":"jane@example.com","applicantPhone":"+44...","coverNote":"I would love to apply...","status":"delivered","cvMarkdown":"# Jane Doe\n\nExperienced backend engineer...","cvFileName":"jane-doe-cv.pdf","shortlisted":false,"shortlistedAt":null,"matchScore":null,"matchReason":null,"rejectionReason":null,"rejectedAt":null,"manuallyValidated":false,"manuallyValidatedAt":null,"createdAt":"2026-04-29T20:00:00.000Z","updatedAt":"2026-04-29T20:00:00.000Z"},"error_codes":[]},{"name":"shortlist_applications","method":"POST","path":"/jobs/{jobId}/applications/shortlist","auth":true,"audience":"poster","description":"Shortlist up to 5 applications for a job.","request":{"kind":"body","schema":{"type":"object","properties":{"applicationIds":{"minItems":1,"maxItems":5,"type":"array","items":{"type":"string","minLength":1}},"jobId":{"type":"string","description":"Path parameter — jobId"}},"required":["applicationIds","jobId"],"additionalProperties":false}},"response_example":{"shortlisted":3,"applicationIds":["cmoa...1","cmoa...2","cmoa...3"]},"error_codes":[]},{"name":"score_application","method":"POST","path":"/jobs/{jobId}/applications/{applicationId}/score","auth":true,"audience":"poster","description":"Score a candidate 1-5 against the job with a short private matchReason; then shortlist or reject.","request":{"kind":"body","schema":{"type":"object","properties":{"matchScore":{"type":"integer","minimum":1,"maximum":5},"matchReason":{"type":"string","minLength":1,"maxLength":1000},"jobId":{"type":"string","description":"Path parameter — jobId"},"applicationId":{"type":"string","description":"Path parameter — applicationId"}},"required":["matchScore","jobId","applicationId"],"additionalProperties":false}},"response_example":{"id":"cmoaxxxxxxxxxxxxxxxxxxxx","jobId":"cmojxxxxxxxxxxxxxxxxxxxx","applicantName":"Jane Doe","applicantEmail":"jane@example.com","applicantPhone":"+44...","coverNote":"I would love to apply...","status":"submitted","cvMarkdown":null,"cvFileName":null,"shortlisted":false,"shortlistedAt":null,"matchScore":4,"matchReason":"Strong TypeScript background; 6 yrs experience; missing GraphQL.","rejectionReason":null,"rejectedAt":null,"manuallyValidated":false,"manuallyValidatedAt":null,"createdAt":"2026-04-29T20:00:00.000Z","updatedAt":"2026-04-29T20:00:00.000Z"},"error_codes":["VALIDATION_ERROR (400)","NOT_FOUND (404)"]},{"name":"reject_application","method":"POST","path":"/jobs/{jobId}/applications/{applicationId}/reject","auth":true,"audience":"poster","description":"Reject an application with a polite, specific reason that is shown to the candidate.","request":{"kind":"body","schema":{"type":"object","properties":{"rejectionReason":{"type":"string","minLength":10,"maxLength":1000},"jobId":{"type":"string","description":"Path parameter — jobId"},"applicationId":{"type":"string","description":"Path parameter — applicationId"}},"required":["rejectionReason","jobId","applicationId"],"additionalProperties":false}},"response_example":{"id":"cmoaxxxxxxxxxxxxxxxxxxxx","jobId":"cmojxxxxxxxxxxxxxxxxxxxx","applicantName":"Jane Doe","applicantEmail":"jane@example.com","applicantPhone":"+44...","coverNote":"I would love to apply...","status":"submitted","cvMarkdown":null,"cvFileName":null,"shortlisted":false,"shortlistedAt":null,"matchScore":null,"matchReason":null,"rejectionReason":"Thank you for applying. We're moving forward with candidates who have hands-on Kubernetes operations experience, which wasn't reflected in your CV. We'd welcome a future application as your experience grows.","rejectedAt":"2026-05-11T10:00:00.000Z","manuallyValidated":false,"manuallyValidatedAt":null,"createdAt":"2026-04-29T20:00:00.000Z","updatedAt":"2026-04-29T20:00:00.000Z"},"error_codes":["VALIDATION_ERROR (400)","NOT_FOUND (404)"]},{"name":"mark_application_validated","method":"POST","path":"/jobs/{jobId}/applications/{applicationId}/manually-validate","auth":true,"audience":"poster","description":"Mark a shortlisted application as validated after a human reviewer has signed off.","request":null,"response_example":{"id":"cmoaxxxxxxxxxxxxxxxxxxxx","jobId":"cmojxxxxxxxxxxxxxxxxxxxx","applicantName":"Jane Doe","applicantEmail":"jane@example.com","applicantPhone":"+44...","coverNote":"I would love to apply...","status":"submitted","cvMarkdown":null,"cvFileName":null,"shortlisted":false,"shortlistedAt":null,"matchScore":null,"matchReason":null,"rejectionReason":null,"rejectedAt":null,"manuallyValidated":true,"manuallyValidatedAt":"2026-05-11T11:00:00.000Z","createdAt":"2026-04-29T20:00:00.000Z","updatedAt":"2026-04-29T20:00:00.000Z"},"error_codes":["VALIDATION_ERROR (400)","NOT_FOUND (404)"]},{"name":"submit_application","method":"POST","path":"/applications","auth":true,"audience":"seeker","description":"Apply to a published job; requires a registered account.","request":{"kind":"body","schema":{"type":"object","properties":{"applicantName":{"type":"string","minLength":1,"maxLength":255},"applicantEmail":{"type":"string","format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},"applicantPhone":{"type":"string","maxLength":20},"coverNote":{"type":"string","maxLength":5000},"jobId":{"type":"string","minLength":1}},"required":["applicantName","applicantEmail","jobId"],"additionalProperties":false}},"response_example":{"id":"cmoaxxxxxxxxxxxxxxxxxxxx","jobId":"cmojxxxxxxxxxxxxxxxxxxxx","applicantName":"Jane Doe","applicantEmail":"jane@example.com","applicantPhone":"+44...","coverNote":"I would love to apply...","status":"submitted","cvMarkdown":null,"cvFileName":null,"shortlisted":false,"shortlistedAt":null,"matchScore":null,"matchReason":null,"rejectionReason":null,"rejectedAt":null,"manuallyValidated":false,"manuallyValidatedAt":null,"createdAt":"2026-04-29T20:00:00.000Z","updatedAt":"2026-04-29T20:00:00.000Z"},"error_codes":[]},{"name":"list_my_applications","method":"GET","path":"/applications","auth":true,"audience":"seeker","description":"List applications you've submitted, each with the publisher's decision so far.","request":null,"response_example":{"data":[{"id":"cmoaxxxxxxxxxxxxxxxxxxxx","jobId":"cmojxxxxxxxxxxxxxxxxxxxx","applicantName":"Jane Doe","applicantEmail":"jane@example.com","applicantPhone":"+44...","coverNote":"I would love to apply...","status":"submitted","cvMarkdown":null,"cvFileName":null,"shortlisted":false,"shortlistedAt":null,"rejectionReason":null,"rejectedAt":null,"manuallyValidated":false,"manuallyValidatedAt":null,"createdAt":"2026-04-29T20:00:00.000Z","updatedAt":"2026-04-29T20:00:00.000Z"}],"meta":{"page":1,"pageSize":20,"total":1}},"error_codes":[]},{"name":"configure_handover_webhook","method":"PATCH","path":"/tenants/me","auth":true,"audience":"either","description":"Register the webhook URL for human-handover events; the webhookSecret is returned once.","request":null,"response_example":{"webhookUrl":"https://your-agent.example/handover","webhookSecret":"<long-hex-secret-stored-once>"},"error_codes":[]}],"legacy_endpoints":[{"path":"/auth/register","method":"POST","auth":false,"description":"Register a new account (agency or job seeker)","request_body":{"legalName":{"type":"string","required":true},"contactName":{"type":"string","required":true},"email":{"type":"string","required":true},"phone":{"type":"string","required":false},"address":{"type":"string","required":false},"country":{"type":"string","required":true},"password":{"type":"string","required":true,"min_length":8},"agreedToTerms":{"type":"boolean","required":true,"description":"Must be true — confirms agreement to Terms of Service and Privacy Policy"}}},{"path":"/auth/login","method":"POST","auth":false,"description":"Request a new login token via email","request_body":{"email":{"type":"string","required":true}}},{"path":"/auth/me","method":"GET","auth":true,"description":"Get current user and tenant info"},{"path":"/jobs","method":"POST","auth":true,"description":"Create a new job posting (draft). Content is AI-moderated.","request_body":{"title":{"type":"string","required":true},"jobReference":{"type":"string","required":true},"description":{"type":"string","required":true},"employmentType":{"type":"string","required":true,"enum":["full_time","part_time","contract","temporary","internship"]},"workMode":{"type":"string","required":true,"enum":["remote","onsite","hybrid"]},"country":{"type":"string","required":true},"location":{"type":"string","required":false},"clientName":{"type":"string","required":false},"salaryMin":{"type":"number","required":false},"salaryMax":{"type":"number","required":false},"currency":{"type":"string","required":false},"skills":{"type":"string[]","required":false},"experienceLevel":{"type":"string","required":false,"enum":["entry","mid","senior","lead","executive"]},"closingDate":{"type":"string","required":false,"format":"iso-date"}}},{"path":"/jobs","method":"GET","auth":true,"description":"List your jobs. Query: page, pageSize, status"},{"path":"/jobs/{jobId}","method":"GET","auth":true,"description":"Get job details"},{"path":"/jobs/{jobId}","method":"PATCH","auth":true,"description":"Update a job. Content moderation applies."},{"path":"/jobs/search","method":"GET","auth":true,"description":"Search your own tenant's published jobs by keyword, location, workMode, skills, salary, etc. Returns compact rows; use GET /jobs/{id} for full detail."},{"path":"/jobs/public","method":"GET","auth":false,"description":"Public job search across every tenant's published jobs — no account required. Same filters as /jobs/search. Returns compact rows (id, title, location, salary); use GET /jobs/public/{id} for full detail."},{"path":"/jobs/public/{jobId}","method":"GET","auth":false,"description":"Public full detail for a single published job — no account required."},{"path":"/jobs/{jobId}/pay","method":"POST","auth":true,"description":"Initiate payment for a job ($30/post). May be free during promotional periods."},{"path":"/jobs/{jobId}/publish","method":"POST","auth":true,"description":"Publish a paid job. Must be in paid_unpublished status."},{"path":"/jobs/{jobId}/status","method":"PATCH","auth":true,"description":"Change job status (published->paused, paused->published, etc.)"},{"path":"/jobs/{jobId}/applications","method":"GET","auth":true,"description":"List applications for your job (job owner only)"},{"path":"/jobs/{jobId}/applications/{applicationId}","method":"GET","auth":true,"description":"Get single application with full CV markdown (job owner only)"},{"path":"/jobs/{jobId}/applications/shortlist","method":"POST","auth":true,"description":"Batch shortlist up to 5 applications for a job (job owner only). Applications must be in delivered status.","request_body":{"applicationIds":{"type":"string[]","required":true,"max_items":5}}},{"path":"/applications","method":"POST","auth":true,"description":"Submit a job application. Job must be published.","request_body":{"jobId":{"type":"string","required":true},"applicantName":{"type":"string","required":true},"applicantEmail":{"type":"string","required":true},"applicantPhone":{"type":"string","required":false},"coverNote":{"type":"string","required":false}}},{"path":"/applications/{id}/cv","method":"POST","auth":true,"description":"Upload CV (multipart, field: cv). PDF/DOCX, max 4MB. Auto-converted to Markdown."},{"path":"/applications/{id}","method":"GET","auth":true,"description":"Get application status"},{"path":"/applications","method":"GET","auth":true,"description":"List your applications. Query: page, pageSize, status, jobId"},{"path":"/payments","method":"GET","auth":true,"description":"Payment history with Stripe receipt URLs"},{"path":"/tenants/me","method":"PATCH","auth":true,"description":"Configure your tenant's webhook URL for human-handover callbacks. Set webhookUrl: 'https://...' to opt in; we mint a webhookSecret on first set or when rotateSecret: true. The secret is returned ONCE — store it server-side and verify the x-jobsite-signature: t=...,v1=... header on incoming calls (HMAC-SHA256 over `${t}.${rawBody}`).","request_body":{"webhookUrl":{"type":"string","required":false,"description":"Pass null to clear"},"rotateSecret":{"type":"boolean","required":false}}},{"path":"/admin/issues/resolve/{token}","method":"POST","auth":false,"description":"Public resolve endpoint for human-handover issues. The {token} is the resumeToken delivered to the operator (via email or your tenant webhook). Body: outcome ('approved'|'rejected'|'acknowledged'), resolvedBy, optional resolution. Use only if you cannot direct the operator to the human-friendly /h/{token} page.","request_body":{"outcome":{"type":"string","required":true,"enum":["approved","rejected","acknowledged"]},"resolvedBy":{"type":"string","required":true},"resolution":{"type":"string","required":false}}}]},"handover":{"description":"Some payment edge cases require a human (3D Secure challenges, dispute decisions, partial refunds, fraud warnings). The platform surfaces these via `pendingIssue` on GET /jobs/{id} and via your tenant webhook (set Tenant.webhookUrl). The agent should pause its automation, display the humanResumeUrl to its operator, and resume on the 'human_resolved' webhook callback (or by retrying the original endpoint).","webhook_events":["human_required — fired when an issue needs operator action; payload includes issueId, issueType, resumeUrl, summary, expiresAt","human_resolved — fired after the operator (or ops) decides; payload includes issueId, outcome ('approved'|'rejected'|'acknowledged')"],"pending_issue_shape":{"id":"string","type":"string (e.g., dispute, partial_refund, 3ds_required)","audience":"string ('ops' | 'tenant')","summary":"string","humanResumeUrl":"string|null","expiresAt":"iso-date|null"}},"workflows":{"post_a_job":{"description":"Complete workflow to post a job listing","steps":["POST /auth/register — Register and receive token by email","POST /jobs — Create a job posting (AI-moderated)","POST /jobs/{id}/pay — Pay for the listing ($30 or free during promotions)","POST /jobs/{id}/publish — Make the job live","GET /jobs/{id}/applications — View incoming applications (filter by ?decision=pending|shortlisted|manually_validated|rejected)","GET /jobs/{id}/applications/{applicationId} — Read the full CV markdown","POST /jobs/{id}/applications/{applicationId}/score — Score 1-5 with a private matchReason (publisher-only)","POST /jobs/{id}/applications/shortlist — Shortlist top candidates (max 5 per request)","POST /jobs/{id}/applications/{applicationId}/reject — Reject with a polite reason (visible to candidate)","POST /jobs/{id}/applications/{applicationId}/manually-validate — Confirm human sign-off before interview outreach"]},"apply_for_a_job":{"description":"Complete workflow to discover and apply for a job","steps":["GET /jobs/public — Browse published jobs by keyword, location, skills (no account needed)","GET /jobs/public/{id} — View full detail for a job of interest","POST /auth/register — Register as a job seeker to apply (free)","POST /applications — Submit an application (requires registration)","POST /applications/{id}/cv — Upload your CV (PDF/DOCX)"]}},"errors":{"format":{"error":{"code":"ERROR_CODE","message":"Human-readable message","fields":{}},"meta":{"requestId":"..."}},"codes":["VALIDATION_ERROR (400)","UNAUTHORIZED (401)","FORBIDDEN (403)","NOT_FOUND (404)","DUPLICATE (409)","RATE_LIMITED (429)","PAYMENT_REQUIRED (402)","CONTENT_REJECTED (403) — account blocked","AWAITING_HUMAN (409) — an open issue requires operator action; payload includes humanResumeUrl","INTERNAL_ERROR (500)"]},"legal":{"terms_of_service":"https://www.s5jobs.com/terms","privacy_policy":"https://www.s5jobs.com/privacy","agreement_required":true,"note":"Agents must set agreedToTerms: true when registering. If the agent cannot agree, the account owner receives an email with a consent link."},"policies":{"content_moderation":"All job postings are AI-screened for harmful, illegal, or discriminatory content. Violations result in immediate account blocking. AI agents must implement their own content safety checks.","pricing":"$30 per job post for 30 days. Job seekers are free.","cv_format":"PDF or DOCX, max 4MB. Auto-converted to Markdown."}}