# Comeet Jobs API

> How Comeet's boards actually work, why the read token is public rather than secret, and what ?source=comeet returns in the HyperJobs API.

Source: https://hyperjobs.io/ats/comeet

Comeet is a mid-market ATS with a strong base in Israeli, European and US tech
companies. Boards live at `comeet.com/jobs/<slug>/<company_uid>`, and once you
have the two things the board page hands you, a single call returns the whole
board with every description inline.

## Board HTML, then a public read token, then the whole board

Two steps, and the first one exists only to get a key out of the page:

```bash
# 1. The board page — embeds "company_uid": "76.008" and "token": "…"
curl "https://www.comeet.com/jobs/<slug>/<company_uid>"

# 2. The whole board, one call, bodies inline
curl "https://www.comeet.co/careers-api/2.0/company/<uid>/positions?token=<t>&details=true"
```

Two details are easy to get wrong here. The board is on **comeet.com** and the
API is on **comeet.co** — different TLDs, one letter apart. And a board is
addressed by *both* its slug and its numeric uid; neither alone loads it.

The token is worth being clear about, because "token" reads like a credential.
It isn't. It's a public read key the board ships to its own front-end so the page
can render itself, sitting in the HTML that any visitor receives. There's nothing
to register for and nothing to mint. Without it the API answers `400` with
"Account uid or token are not valid", which is a routing failure rather than an
authorization one.

`&details=true` is the parameter that makes this cheap. It inlines the posting
bodies, so there is no per-job detail call at all — a 166-job board is two
requests total.

## What bites you

<Warning title="`location.name` is a label the tenant typed, not a place">
  Across one 166-job board, `location.name` reads `"HQ"`. The structured
  `city` / `state` / `country` beside it says `Petah Tikva, Center District, IL`.
  Another tenant's label reads `"Ukraine"` while the structured parts say Kyiv.

  `"HQ"` geocodes to nothing at all, and a bare country throws away a city you
  were handed. The structured parts are ground truth; `name` is only a last resort
  for tenants that leave them blank.
</Warning>

**`time_updated` is an edit stamp, not a publish date.** It's the only timestamp
Comeet exposes, and the temptation is obvious: it's a date, it's right there, and
a job needs a `posted_at`. Map it and every posting an employer touches looks
brand new. A two-year-old role with a typo fix in it outranks everything actually
fresh, and the freshness window stops meaning anything. It is better to have no
date than a wrong one, so it isn't mapped.

**`details[]` is titled sections and you need all of them.** The body arrives as
an array of `{name, value}` blocks — Description, Requirements, and whatever else
the tenant configured. Take the first and stop, and you drop the Requirements
section, which is often half the posting.

**Position uids are globally unique**, which is a small mercy: one API namespace
across the platform, so ids don't collide across boards the way most per-tenant
counters do.

## What you get

166 of 166 descriptions on the reference board, and 153 of 160 postings
resolving to a real city once the structured location fields are read instead of
the label. Comeet also gives you `experience_level` as a genuine seniority and a
clean three-way `workplace_type` (`remote` / `hybrid` / `on_site`), so the
arrangement doesn't have to be guessed out of a location string the way
[Rippling](/ats/rippling) and [Personio](/ats/personio) make you.

Query it with `?source=comeet` — the public slug, and the same string in the
filter, in the keys of [`/v1/meta`](/docs/api-reference/meta) → `sources`, and in
the `source` field on every row that comes back. `/v1/meta` is the live
vocabulary; read the value off it rather than off a page.

See [all platforms](/ats) · [coverage](/docs/reference/coverage)
