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:

EndpointPurpose
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.xmlA sitemap of your published postings, for search engines.
POST /portal/{slug}/jobs/{job-slug}/applySubmit 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

  1. Fetch GET /portal/{slug} and render the published postings as your job list.
  2. Link each to a detail page fed by GET /portal/{slug}/jobs/{job-slug}.
  3. Build your apply form to POST multipart form data to the apply endpoint, including the resume file field.
  4. Include the website honeypot 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.

Read as Markdown