# Using your own website (portal API)

> Power your existing careers site with Kepler’s open portal API — list jobs and take applications headlessly.

_Collection: Job Advertising & Portal (job-portal) — Kepler Help Center. Canonical: https://keplercrm.com/support/articles/portal-api-your-own-website/_

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](/support/articles/review-inbound-applicants/) 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 `POST` multipart form data to the apply endpoint, including the resume file field.

  - 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.

> **NOTE:** Postings you close in Kepler disappear from the list endpoint and stop accepting applications immediately — your site needs no extra logic for job expiry.
