Connection check
verified live · 28h ago
hiring-signals
Find companies hiring for a role and geo, qualify them, and watch them for changes.
Tools
11
GitHub stars
—
Installs / wk
—
Licence
—
Transport
streamable-http
Last checked
28h ago
Tools & capabilities
11 toolsRead from the running server on 28h ago.
get_changes
limitsince*company_idevent_typeplane_api_keyidempotency_key
The `since=cursor` diff feed -- ledger events with `event_seq > since`, plus a `next_cursor`. Meters one `change` unit per event returned, independent of poll count. A free… The `since=cursor` diff feed -- ledger events with `event_seq > since`, plus a `next_cursor`. Meters one `change` unit per event returned, independent of poll count. A free-tier caller is freshness-floored, the same as every other free-tier read. `limit` is bounded: an oversized page is rejected rather than truncated, so replay with `next_cursor` instead of raising `limit`.
get_open_reqs
limitcountryfunctioncompany_id*plane_api_keyidempotency_key
The company's current active reqs, deduped across boards -- ATS/board-only, freshness-floored. `function` must be a function id (as seen in prior results); a plain role nam… The company's current active reqs, deduped across boards -- ATS/board-only, freshness-floored. `function` must be a function id (as seen in prior results); a plain role name like 'engineering' is rejected with an explicit error rather than an empty result. `limit` is bounded: an oversized page is rejected rather than truncated.
get_role
req_key*company_id*plane_api_keyidempotency_key
One open role's detail, addressed by the `company_id` + `req_key` pair every `search_jobs` row already carries -- the follow-up call for a role you hold an identifier for,… One open role's detail, addressed by the `company_id` + `req_key` pair every `search_jobs` row already carries -- the follow-up call for a role you hold an identifier for, instead of re-pulling the whole company with `get_open_reqs`. Scoped exactly as `search_jobs` is: ATS-only and freshness-floored. The body adds `raw_title` (the posting's own title) and `boards`, the full deduped list of boards reporting this req. A role that does not exist, is closed, or has not reached the freshness floor is an explicit error, never an empty success -- and it is not billed.
hiring_pulse
max_agecompany_id*plane_api_keyidempotency_key
A company's hiring velocity/direction/momentum in one call -- dual-metered via `max_age` (seconds). Cold returns `{job_id, status: "crawling"}` instead of a synchronous bod… A company's hiring velocity/direction/momentum in one call -- dual-metered via `max_age` (seconds). Cold returns `{job_id, status: "crawling"}` instead of a synchronous body, same as the REST route.
is_hiring
company_id*plane_api_keyidempotency_key
WHEN an agent already holds a company and needs to qualify it -- the cheap gate before spending a richer call. ATS/board-only and freshness-floored. Takes the integer `company_id`… WHEN an agent already holds a company and needs to qualify it -- the cheap gate before spending a richer call. ATS/board-only and freshness-floored. Takes the integer `company_id` from an earlier result, not a company name or domain. company_id=1234 -> is_hiring true, open_req_count 7, coverage_status "ats_direct_hit". company_id=5678 -> is_hiring false with coverage_status "no_ats_signal" -- that company has no ATS coverage yet, which is not evidence it is quiet, so do not score it as a negative. No key yet? Pass `plane_api_key` as an empty string and the call answers with a signup link instead of an auth error. To find companies in the first place, use `who_is_hiring_for`.
pre_action_brief
max_agecompany_id*plane_api_keyidempotency_key
The motion atoms + history primitives pre-joined into one bounded, compact call -- dual-metered via `max_age`. Cold returns `{job_id, status: "crawling"}`, same as the REST… The motion atoms + history primitives pre-joined into one bounded, compact call -- dual-metered via `max_age`. Cold returns `{job_id, status: "crawling"}`, same as the REST route.
register_webhook
url*secretplane_api_key
Register the delivery target a watch fires to, and get back the `webhook_endpoint_id` `watch_company` needs -- call this first if you do not already hold one. Idempotent: r… Register the delivery target a watch fires to, and get back the `webhook_endpoint_id` `watch_company` needs -- call this first if you do not already hold one. Idempotent: registering the same `url` twice returns the same id, so retrying is safe and never leaves you with two endpoints. `secret` is optional; supply one to verify the `X-Plane-Signature` on delivered payloads, omit it and one is generated (it is never returned). Registration itself is free -- the `watch_company` call that follows is what bills. Plane session only: `webhook_endpoints` is plane-owned and this tool reads no corpus table.
search_jobs
qgeorolesortlimitsince
+3
Flat, role-granular job search -- the individual open roles across companies matching `role` (function) / `geo` (country) / `since`, one row per logical req (each with its… Flat, role-granular job search -- the individual open roles across companies matching `role` (function) / `geo` (country) / `since`, one row per logical req (each with its own `company_id` + `req_key`), ATS-only + freshness-floored. Keyset-paginated via the opaque `cursor` (a prior call's `next_cursor`). Use `who_is_hiring_for` for the company-granular reverse view. `role` must be a function id (as seen in prior results); a plain role name like 'engineering' is rejected with an explicit error rather than an empty result -- pass plain language as `q` instead, which searches the posting's own title, expanded semantically to nearby titles, and reports each row's `relevance` (0-1). `q` is independent of `role`: pass both to search titles within one function. `sort` is 'relevance' (the default with a `q`) or 'recency'; omit both and the page keeps its stable default order. `limit` is bounded: an oversized page is rejected rather than truncated, so page through the full set with `cursor` instead of raising `limit`.
watch_company
company_id*event_types*plane_api_keyidempotency_keywebhook_endpoint_id*
Subscribe to a company's hiring events on a registered webhook -- `webhook_endpoint_id` must belong to the same customer as the authenticated key. Meters one `watch` unit.… Subscribe to a company's hiring events on a registered webhook -- `webhook_endpoint_id` must belong to the same customer as the authenticated key. Meters one `watch` unit. A free key holds a limited number of watches at once; the one past that is refused with the same 402 the REST route raises, and cancelling a watch returns the slot.
who_is_hiring_for
georolelimitsincecursorplane_api_key
+1
WHEN an agent needs to FIND the companies worth working -- the sourcing step, before it knows which companies exist. Reverse who's-hiring-for {role, geo} search: companies with act… WHEN an agent needs to FIND the companies worth working -- the sourcing step, before it knows which companies exist. Reverse who's-hiring-for {role, geo} search: companies with active reqs matching `role`/`geo`/`since`, deduped by company, keyset-paginated via `cursor`. `role` is free text matched against the posting title, not an id. `geo` is resolved to a stored country before matching; an unresolvable one is an explicit error, never a quietly partial page. `limit` is bounded -- page through the full set with `cursor` instead of raising it. Billed per company returned (~0.10 USD each) -- an empty result bills nothing. role="backend engineer", geo="USA" -> the companies with matching active reqs, each with its pulse and its matched reqs. geo="Atlantis" -> an explicit unresolvable-country error rather than an empty page. No key yet? On the hosted HTTP endpoint the first calls are free: pass `plane_api_key` as an empty string and the search runs on a shared demo credential -- a smaller page, billed to nobody -- until a per-IP limit is reached, after which the answer becomes a signup link whose minted key finishes this exact search. On any other transport a blank key answers with that signup link straight away. Already holding a company_id and only need a yes/no? Use `is_hiring`.
write_outcome
outcome*req_keycompany_id*observed_at*plane_api_key