# API reference

Endpoints, filters, pagination and response fields for jobs and employers.

Base URL: `https://withpanta.com/api/v1`. Search parameters are optional, single-valued and case-sensitive. Unknown and repeated parameters return 400. Unsupported methods return 405. Use `Accept: application/json`.

| Method | Endpoint | Returns |
| --- | --- | --- |
| GET | `/jobs` | Swiss-eligible jobs from enabled sources, with source metadata. |
| GET | `/jobs/{id}` | `job`, `postings` and `countries`, including inactive or past listings. |
| GET | `/companies` | Public employer profiles and canonical active job counts. |
| GET | `/companies/{id}` | A public `company` profile with official domain and description provenance. |
| GET | `/companies/{id}/jobs` | Exact employer's active and past Swiss jobs. |
| POST | `/cv-check` | Transient deterministic CV findings; separate size and rate limits. |

### Job search filters

| Parameter | Meaning |
| --- | --- |
| `q` | Keywords. All searchable terms must match; searches titles and descriptions. At most 12 terms are interpreted. Maximum 200 UTF-8 bytes. |
| `company_id` | Exact canonical employer ID returned by company search; preferred for employer-specific queries. |
| `category` | Reviewed title-based role family, version 2026-10-27.2. Not an employer-sector filter. |
| `company` | Employer name contains this text; not a company ID. Maximum 48 UTF-8 bytes. |
| `canton` | Swiss canton code. |
| `geography` | Work arrangement; does not imply Swiss remote eligibility. |
| `location_class` | Location evidence classification. Swiss search excludes ambiguous and non-Swiss results. |
| `sector` | Employer sector contains this text. Maximum 40 UTF-8 bytes. |
| `employment_type` | Employment type contains this text, e.g. full-time. Maximum 48 UTF-8 bytes. |
| `sort` | Default: relevance with keywords, otherwise newest. |
| `limit` | Results per page (1–50). |
| `offset` | Use next_offset from the previous response; maximum 5000. |

Swiss eligibility is always enabled. Search uses all searchable terms across titles and descriptions, with at most 12 interpreted terms. Check `interpreted_terms` and `query_truncated`. Try shorter or alternative keywords if results are sparse. Canton filtering uses the normalized canton field and can omit remote or multi-location positions without a single canton.

### Employer search filters

| Parameter | Meaning |
| --- | --- |
| `q` | Employer keywords. Maximum 120 UTF-8 bytes. |
| `country` | Headquarters country code, e.g. CH. This is not job location. |
| `sector` | Sector contains this text. Maximum 40 UTF-8 bytes. |
| `swiss_jobs` | When true, only employers with a recorded domain and active Swiss-eligible jobs from enabled sources. Does not imply source freshness. |
| `has_jobs` | Filter on canonical active job count; not restricted to Swiss or fresh sources. |
| `limit` | Results per page (1–50). |
| `offset` | Use next_offset from the previous response; maximum 5000. |

Employer coverage includes companies without current Swiss openings. `country` filters headquarters. `active_jobs` counts canonical active jobs across countries and source tiers, and is not a count of fresh Swiss vacancies. Company profiles expose `sectors` as a string array; unenriched fields are null.

### One employer's active and past jobs

Use `GET /companies/{id}/jobs` with `status=active` (default) or `status=past`, plus `limit` and `offset`. The response includes `company`, `status`, `jobs`, `sources`, `snapshot_at` and pagination metadata. Active results come from trusted employer sources; past results contain inactive Swiss jobs. Source freshness and health remain separate from activity. This endpoint does not provide a complete history of hiring or historical time series.

### Pagination

Both searches return `count: null`, `page_count`, `limit`, `offset`, `has_more`, `next_offset` and `snapshot_at`. Totals are not computed. Use `next_offset` until it is null; maximum offset is 5,000 and maximum page size is 50. Narrow your query to explore further.

The index changes between requests. `snapshot_at` is the search result generation time, not a frozen dataset version or a source verification time. Pagination can repeat or skip records as the index changes; deduplicate by job ID. No bulk export or historical time-series API is provided.
