Using your own website (portal API)
Power your existing careers site with Kepler’s open portal API — list jobs and take applications headlessly.
The hosted portal is the zero-effort option, but if you already run a careers site you can keep it and use Kepler as the engine behind it. The portal's public API is a stable, unauthenticated, CORS-open contract — your website can call it directly from the browser.
The endpoints
Your workspace's endpoints are listed (with copy buttons) on Settings → Job Portal under Use your own website, along with a ready-made Sample embed code snippet you can copy into your site:
| Endpoint | Purpose |
|---|---|
GET /portal/{slug} | Portal settings + the list of published postings (title, location, summary). |
GET /portal/{slug}/jobs/{job-slug} | The full advertised posting. |
GET /portal/{slug}/sitemap.xml | A sitemap of your published postings, for search engines. |
POST /portal/{slug}/jobs/{job-slug}/apply | Submit an application — multipart form data. |
The apply payload
The apply endpoint takes multipart form data with first_name, last_name and email (required), plus optional phone, location, linkedin_url and a resume file. It also expects a hidden website field that must be left empty — that's the spam trap.
How it behaves
- No auth required — these endpoints are public by design and only ever expose advertised content. Internal fields are never present in responses.
- Open CORS — call them from any origin, including directly from client-side JavaScript.
- Same validation as the hosted portal — published-posting checks, email format validation, CV file type/size limits (PDF/DOC/DOCX, ≤ 10 MB), rate limiting, honeypot support and 24-hour dedupe.
- Same intake policy — submissions create inbound applications and are parsed, scored and screened like hosted-portal applicants. Depending on the workspace or posting setting, a clean applicant is either ready for recruiter review in the Inbound queue or added to the pipeline automatically; junk is moved to Screened out, and possible duplicates remain for review.
A minimal integration
- Fetch
GET /portal/{slug}and render the published postings as your job list. - Link each to a detail page fed by
GET /portal/{slug}/jobs/{job-slug}. - Build your apply form to
POSTmultipart form data to the apply endpoint, including the resume file field. - Include the
websitehoneypot field as a hidden input and leave it empty — submissions that fill it are rejected.
The hosted portal and this headless API use the same application-processing path, so changing the intake setting affects both without any change to your website.
Postings you close in Kepler disappear from the list endpoint and stop accepting applications immediately — your site needs no extra logic for job expiry.