# get_postings

> Ad volume and its trend

**Call:** `GET /v1/postings`  
**Price:** Uses credits (see each response's `X-Credits-Charged`)  
**Available:** soft launch  
**Contract:** https://api.gwix.ai/docs/reference

## What it's for

Count job ads first posted, by period, for any combination of company, location, industry, role and level, with optional change over time.

## Use it when

- "How many ads did X post?" "Is hiring for Y rising or falling in Z?"
- Comparing demand across places, companies or periods.

## Inputs

| Name | In | Type | Required | Meaning |
|---|---|---|---|---|
| `company_id` | query | list of string |  | One or more brand-level company IDs (from the company lookup). Use only one of `company_id`, `parent_company_id` or `ticker`. |
| `parent_company_id` | query | string |  | Ultimate parent company ID; combines all its brands into one group. Uses current ownership for every period (`meta.ownership_basis`). |
| `ticker` | query | string |  | Stock ticker (`MAR`). Resolves to the listed company and is treated as `parent_company_id` (the whole corporate group, current ownership). Add `country` when the ticker is used in more than one country. |
| `split` | query | string: brand |  | With `parent_company_id`, return one row per brand instead of one group row. |
| `location_id` | query | list of string |  | One or more location IDs - country (`US`), state (`US-CO`) or metro (`mtr_…`). A city or postcode resolves to its metro through the location lookup. |
| `country` | query | string |  | ISO 3166-1 alpha-2 country code. |
| `industry_id` | query | list of string |  | One or more 4-digit NAICS industry groups. Statistics are built at 4 digits only, with no 2-, 3- or 6-digit rollups; to cover a wider sector, list its 4-digit codes or aggregate the results. |
| `role_id` | query | list of string |  | One or more standardized role IDs. Use one occupation filter. Role with a company, parent company or ticker is not pre-computed at launch (501); role with an industry is. |
| `job_family_id` | query | list of string |  | One or more job families (the broadest occupation level). |
| `sub_job_family_id` | query | list of string |  | One or more sub-job families (the level between job family and role). |
| `soc_id` | query | list of string |  | One or more US SOC 2018 detailed occupations (`soc_15-1252`), computed from each ad's SOC code. Geography and job level only; with a company, parent, ticker or industry filter 501. |
| `occupation_code` | query | list of string |  | One or more occupation codes as `<system>:<code>`: `soc_2018:15-1252`, `soc_2010:15-1132`, `onet_soc:15-1252.00`, `isco_08:2512`, `esco:2512.4` (short names `soc`, `soc2010`, `onet`, `isco` are accepted; a bare `15-1252` is SOC 2018). Each code resolves to the SOC 2018 detailed occupations it maps to (see `crosswalk`); the response has one row set per SOC occupation, each with `matched_from`, and `meta.occupation_codes` lists every mapping, including SOC occupations without data. A partial match covers only part of the SOC occupation; rows are never pooled across SOC occupations. Unknown code 422 `unknown_code`; a code whose SOC occupations have no ads 422 `no_data_for_code`. Same limits as `soc_id`.  |
| `job_level_id` | query | list of string |  | One or more job levels (seniority). |
| `interval` | query | string: week | month | quarter | year |  | Period type. Month = 4 weeks, quarter = 13, year = 52, anchored to complete weeks ending on or before the period's last day. |
| `start_period` | query | string |  | First period label, e.g. `2025-01`, `2025-Q2`, `2025`, `2025-W14`. |
| `end_period` | query | string |  |  |
| `compare` | query | string: previous | 12_month |  | Add the change against the previous period, or against the same period 52 weeks earlier. |
| `cursor` | query | string |  | Opaque cursor from `paging.next_cursor`. |
| `limit` | query | integer |  | Rows per page, 1 to 1,000 (default 100). Requests needing more than 1,000 rows in total answer 501; narrow them. |

Headers: `Idempotency-Key`, `GWIX-Agent-Id`, `GWIX-On-Behalf-Of`.

## What comes back

`rows`, `meta`, `paging`.
If an input is ambiguous: `status: needs_disambiguation` with `candidates`, the `missing` input and a `retry_with` template (no charge).

## Rules

**What an ad is.** An ad is one de-duplicated job advertisement within a dataset. Ads are not de-duplicated across different partners' datasets. Counts are ads first posted in the period.

**Periods.** Periods are whole Monday-Sunday weeks. A month is 4 weeks, a quarter 13, a year 52, anchored to complete weeks ending on or before the period's last day. There are no partial periods; the current week is never included until it is complete. Ask for periods with `interval` plus `start_period` and `end_period` labels (custom date ranges are not available at launch).

**Zeros and coverage.** `coverage_status: covered` means GWIX sources were watching, so a zero means no ads were observed. `not_covered` means GWIX cannot say; values are null. Periods and named values are always returned, even when zero; unnamed zero rows are omitted and counted in `meta.zero_rows_omitted`.

**Geography.** Statistics are built at metro level. Location filters work at metro, state and country at launch; a city or postcode resolves to its metro. Every row is specific to one country.

**Company groups and ownership.** Company groups (`parent_company_id`, `ticker`) use current ownership for every period (`meta.ownership_basis: current`). A brand acquired last year is counted in its current parent's history.

**IDs, not plain text.** Statistics take IDs. Resolve names to IDs first with `lookup` (company, ticker, place, city, postcode, job family, sub-job family) or send occupation codes (`occupation_code`). Plain-text filters (`title`, `company`, `location`, `job_family`) are not available at launch and answer 501 with a `retry_with` lookup link.

**Request size.** A request answers up to 1,000 rows and 200 filter combinations inline; larger requests answer 501 `job_required` - narrow the filters or periods. Asynchronous jobs come later.

**Provenance and reproducibility.** Every response carries `meta.provenance` (the data release and its last complete week) and a ready-made `meta.citation`. Statistics come from the live weekly release; each response names it.

## Notes

- Add `compare=previous` or `compare=12_month` for the change; `change_null_reason` explains a null change.
- Use one company filter and one occupation filter per call.
- Occupation codes: send `occupation_code=isco_08:2512` (also `soc_2018`, `soc_2010`, `onet_soc`, `esco`) or `soc_id`; you get one row set per SOC 2018 detailed occupation the code maps to, each with `matched_from`. A `partial` match covers only part of the SOC occupation - say so. Never add SOC rows together for pay. SOC occupations are by geography and job level only.
- `parent_company_id` or `ticker` combines all brands; add `split=brand` for one row per brand.
- Weekly figures (`interval=week`) are served for occupations, single companies (also brand by brand with `split=brand`) and industries on their own; for a parent company or ticker, a company or industry combined with an occupation, or industry benchmarks, use month, quarter or year (weekly returns 501).

## How to word results

- Cite GWIX using `meta.citation`.
- Say "advertised pay" or "pay in job ads", never "salary paid" or "what X pays".
- State the currency of every pay figure (the row's `currency`).
- Say "ads first posted", not "jobs" or "hires" or "openings filled".
- Report suppressed percentiles as "not enough ads stating pay to report", not as zero.
- Report zeros with `covered` as "no ads observed in GWIX sources", not "no jobs exist".
- State the level actually used (e.g. metro, 4-digit NAICS) from `meta`.
- For company groups, say figures use current ownership.
- Never: present figures as official statistics or as an employer's actual pay.
- Never: name a data vendor; name datasets as they appear in `meta.provenance`.

## When it doesn't work

| Status | What to do |
|---|---|
| 202 | Still running: you have a job. Poll `get_job` or wait for a webhook. |
| 400 | Fix the request; `invalid_params` names each bad parameter. |
| 401 | Send a valid API key (`Authorization: Bearer ...`). |
| 402 | Not enough credits. The body lists packs and plans that would cover it. |
| 403 | Not allowed for this key or tier, a cap is reached, or the agent is unidentified; read `type` and `detail`. |
| 409 | Idempotency-Key reused with a different request, or the action conflicts with the current state. |
| 422 | Parameters conflict (e.g. two company filters) or use a reserved feature. |
| 429 | Rate or concurrency limit. Wait `Retry-After` seconds. |
| 503 | Temporarily unavailable; see `get_status`. |

## Next steps

[`get_pay`](/context/get_pay) · [`lookup`](/context/lookup)

## Example response

```json
{
  "rows": [
    {
      "period_label": "2026-Q3",
      "period_start": "2026-06-29",
      "period_end": "2026-09-27",
      "country": "US",
      "company": {
        "id": "cmp_acme_retail",
        "name": "Acme Retail"
      },
      "job_family": {
        "id": "jfm_nursing",
        "name": "Nursing"
      },
      "coverage_status": "covered",
      "new_postings": 1284,
      "prior_new_postings": 1102,
      "change_pct": 16.5
    }
  ],
  "meta": {
    "request_id": "gwx_req_8f3k2m",
    "resolved": [],
    "period_definition": "13-week quarters of whole Monday\u2013Sunday weeks",
    "zero_rows_omitted": 0,
    "provenance": {
      "datasets": [
        {
          "id": "us-postings-core",
          "last_complete_week": "2026-10-25"
        }
      ],
      "data_release": "2026-W43",
      "taxonomy_version": "utb-1.0",
      "computed_at": "2026-10-28T14:02:09Z"
    },
    "citation": {
      "text": "GWIX ad volume, Acme Retail, Nursing, US, 2026-Q3, release 2026-W43, retrieved 28 Oct 2026 (gwx_req_8f3k2m)",
      "url": "https://api.gwix.ai/v1/requests/gwx_req_8f3k2m"
    }
  },
  "paging": {
    "next_cursor": null
  }
}
```
