Apple Jobs API endpoint
Discovery endpoint for apple-jobs-search's `location` parameter, whose accepted values are a closed set Apple itself defines (its own `<slug>-<CODE>` location ids -- free-text location names are rejected). Apple exposes no bulk "list everything" option for this; the only lookup is a fuzzy search capped at 10 results per call covering four granularities (country, state/province, metro area, city) with no empty-input listing mode. With no `q`, this returns the full country-level value space (206 values, live-verified) as a static list -- the granularity apple-jobs-search's own examples use and nearly every caller needs. With `q` supplied, this instead looks up Apple's own location filter live so callers can discover state/metro/city-level values for finer filtering; results at those deeper levels may include more than one candidate and are ranked by Apple's own relevance, not alphabetically.
/apple-jobs/locationsApple exposes no bulk "list everything" API for this. Its only upstream source is its own location-filter typeahead (the same one the jobs.apple.com search page's location filter calls as you type), a fuzzy search capped at 10 results per call that covers four distinct granularities — country, state/province, metro area, and city — with no empty-input or list-all mode.
Query parameters:
q (optional): free-text location search, e.g. singapore or cupertino.
apple-jobs-search's own documented examples use (united-states-USA, singapore-SGP) and covers nearly every caller's needs with no live upstream call.q=cupertino returns cupertino-california-united-states-CUP). Results can include more than one candidate and are ranked by Apple's own relevance, not alphabetically. Not every country/state/city Apple's site knows about will match a given q — this is the live, capped search Apple's own frontend uses, not an exhaustive index.Notable response behavior:
scope is country for the default (no-q) response, or search when q was supplied.locations[].location value is exactly what apple-jobs-search's location parameter expects.locations[].level is one of country, state, metro, city, or other (an unrecognized upstream level, included rather than silently dropped).q result's location slug is computed the same way Apple's own frontend computes it (lowercase, non-alphanumeric runs collapsed to a single hyphen, trimmed) and has been verified correct for every case checked, including multi-word/parenthetical country names and city-level results. A city/metro/state name containing non-ASCII characters is the one case this cannot guarantee byte-for-byte, since Apple's own JS may normalize diacritics differently — treat those specific results as best-effort.Example response (q omitted):
{
"code": 200,
"msg": "OK",
"data": {
"scope": "country",
"count": 206,
"locations": [
{"location": "singapore-SGP", "name": "Singapore", "code": "SGP", "level": "country"},
{"location": "united-states-USA", "name": "United States", "code": "USA", "level": "country"}
],
"source_url": "https://jobs.apple.com/api/v1/refData/postlocation",
"fetched_at": "2026-09-16T12:00:00Z"
}
}
Example response (q=cupertino):
{
"code": 200,
"msg": "OK",
"data": {
"query": "cupertino",
"scope": "search",
"count": 2,
"locations": [
{"location": "cupertino-california-united-states-CUP", "name": "Cupertino, California, United States", "code": "CUP", "level": "city"},
{"location": "santa-clara-valley-cupertino-california-united-states-SCV", "name": "Santa Clara Valley (Cupertino), California, United States", "code": "SCV", "level": "city"}
],
"source_url": "https://jobs.apple.com/api/v1/refData/postlocation?input=cupertino",
"fetched_at": "2026-09-16T12:00:00Z"
}
}
| Field | Filled in, of 206 checked | Values in the sample |
|---|---|---|
| location | 206 | “afghanistan-AFG” and 205 other values |
| name | 206 | “Afghanistan” and 205 other values |
| code | 206 | |
| level | 206 | country in all 206 |
| Parameter | Type | Required | Default | Description | Example |
|---|---|---|---|---|---|
| q | string | No | Optional free-text location search. Omit to get the full country-level list; supply to live-search state/metro/city-level values too (e.g. a city name). | singapore | |
| x-api-key (header) | string | Yes | API key required |
curl -X GET "https://api.crawlora.net/api/v1/apple-jobs/locations?q=coffee" \ -H "x-api-key: $CRAWLORA_API_KEY"
{
"code": 200,
"msg": "OK",
"data": {
"scope": "country",
"count": 206,
"locations": [
{
"location": "singapore-SGP",
"name": "Singapore",
"code": "SGP",
"level": "country"
},
{
"location": "united-states-USA",
"name": "United States",
"code": "USA",
"level": "country"
}
],
"source_url": "https://jobs.apple.com/api/v1/refData/postlocation",
"fetched_at": "2026-09-16T12:00:00Z"
}
}Request schema
No body schema
Response schema
#/definitions/applejobs.locationsResponseDoc
| Field | Type | Required | Enum | Bounds | Example | Description |
|---|---|---|---|---|---|---|
| code | integer | No | 200 | |||
| data | applejobs.LocationsResponse | No | ||||
| data.count | integer | No | 206 | |||
| data.fetched_at | string | No | ||||
| data.locations | array | No | ||||
| data.locations[].code | string | No | USA | |||
| data.locations[].level | string | No | country | Level is "country", "state", "metro", or "city" -- see LocationsResponse's doc comment for why only "country" is enumerated by default. | ||
| data.locations[].location | string | No | united-states-USA | |||
| data.locations[].name | string | No | United States | |||
| data.query | string | No | singapore | Query echoes the q parameter. Empty when the response is the default country-level enumeration (Scope == "country"). | ||
| data.scope | string | No | country | Scope is "country" for the default bulk country enumeration, or "search" when q was supplied and the response is a live pass-through of Apple's own location typeahead (which can return country, state, metro, or city-level matches). | ||
| data.source_url | string | No | ||||
| msg | string | No | OK |
| Status | Description | Schema |
|---|---|---|
| 400 | Bad Request | #/definitions/app.Response |
| 429 | Too Many Requests | #/definitions/app.Response |
| 503 | Service Unavailable | #/definitions/app.Response |
Use environment variables for secrets and keep Crawlora API keys server-side.
curl -X GET "https://api.crawlora.net/api/v1/apple-jobs/locations?q=coffee" \
-H "x-api-key: $CRAWLORA_API_KEY"