# Microsoft Jobs API

> Query Microsoft's postings through one API with ?source=microsoft — plus the list field that swears every job is on-site, and a page size hard-capped at ten.

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

Microsoft is not a platform. It's one employer with a bespoke careers site, and
this adapter reaches Microsoft and nothing else. Write [Workday](/ats/workday) once
and you reach every Workday tenant; write this one and you reach Microsoft.
`company` is ignored — there is one.

Its jobs are worth having, and the only way to have them is a dedicated adapter
maintained forever. We run it: query it with `?source=microsoft`.
[`/v1/meta`](/docs/api-reference/meta) is the authoritative live vocabulary, with
the current count per source.

## How Microsoft Careers actually works

Microsoft moved to a platform it calls **pcsx** (`apply.careers.microsoft.com`);
the old `gcsservices` API is dead. It's the same Eightfold-family platform our
[Eightfold](/ats/eightfold) adapter already reads — same `workLocationOption` enum.
No browser, no auth: a plain browser User-Agent gets a 200.

```
GET /api/pcsx/search?domain=microsoft.com&query=&start=N&num=10          → positions[], count
GET /api/pcsx/position_details?position_id=<id>&domain=microsoft.com     → full HTML body
```

The list is structured but ships **no description**, so the detail call is an N+1
you can't skip — run only for the day's new reqs. Page 0 carries `count` (~1,600
jobs); the rest fan out in parallel.

<Warning title="`num` is capped at ten, server-side">
  Ask for `num=100` and you get **ten**. The page size is fixed at ten no matter
  what you send, so a ~1,600-job board is ~160 list pages, then ~1,600 detail
  fetches on a cold run. Paginate sequentially and you blow the time budget; the
  adapter fans the pages out concurrently instead.
</Warning>

### The list swears every job is on-site

`workLocationOption` on the list record reads `"onsite"` for **every job** —
measured 10 out of 10, including fully-remote roles with zero days in office. It is
a broken field. The real arrangement lives on the *detail* payload, in
`efcustomTextWorkSite` — `"0 days / week in-office – remote"`, `"3 days / week
in-office"`, `"Fully on-site"` — which the adapter parses into Remote / Hybrid /
On-site, falling back to the broken list field only when the detail is missing.

Take `workLocationOption` at face value and you'd label a remote-first employer
100% on-site, with a well-formed field and nothing to alert you.

## What bites you

<Warning title="A 403 here is transient, not a ban">
  The pcsx edge is Akamai, and it's **reputation-gated**. From a clean IP a plain
  request 200s and the whole board scrapes. Hammer it — a handful of full-board
  runs inside fifteen minutes — and it trips a temporary IP-wide block that 403s
  even `curl`, then decays on its own. So a 403 is a momentary soft-block, not a
  wall: it's retried, and a persistently-blocked run fails **safe** (returns
  nothing, expires nothing) rather than wrongly shrinking the board.
</Warning>

**Locations come two ways, and one is backwards.** `standardizedLocations` is
city-first (`"Redmond, WA, US"`) — the shape a parser wants; `locations` is
country-first (`"United States, Washington, Redmond"`). The adapter prefers the
former and only falls back to the latter.

**The cold start is the expensive one.** ~1,600 detail fetches behind a
ten-per-page list is real work; warm re-scrapes detail only the day's new reqs, and
a detail that fails leaves the job with its structured list fields rather than
dropping it.

## Or use ours

A ten-capped page size fanned out, a mandatory detail N+1 for descriptions, a
work-arrangement field that lies on the list and has to be recovered from the
detail, and an Akamai soft-block handled as transient — with Microsoft's rows in
the same [`Job`](/docs/objects/job) shape as every other
[source](/docs/reference/sources), dedup against the same role on
[LinkedIn](/ats/linkedin), and the adapter's upkeep being ours instead of yours.
Same deal as [Amazon](/ats/amazon), [Apple](/ats/apple), [Uber](/ats/uber),
[TikTok](/ats/tiktok), [Google](/ats/google) and [IBM](/ats/ibm).

[Sources](/docs/reference/sources) · [Quickstart](/docs/quickstart)
