# Jobs: API reference

8 endpoints. Base URL `https://princegeorgepulse.ca/api/v1`. Conventions (envelope, paging, fields, formats, limits) are on the [overview](https://princegeorgepulse.ca/developers/). [All endpoints](https://princegeorgepulse.ca/developers/reference/).

## GET /api/v1/jobs {#get-jobs}

Open job postings in Prince George, newest first, with search and filters.

Aggregated from Job Bank and other public sources every 2 hours. Wages are as published; `wage.hourlyMin` converts other units at 7.5 h a day, 37.5 h a week and 1,950 h a year (2,080 h for WorkBC postings, which WorkBC annualises at 40 h a week) so postings can be compared. There is no full job description: follow `url` to read and apply at the source.

- Cache: 10 min
- Source: [PG Pulse jobs, aggregated from public job boards and employer career sites (each posting links its source)](https://princegeorgepulse.ca/jobs/)
- Licence: Posting facts from each source (see `source`, `via` and `url` per posting); Job Bank content © Government of Canada, reproduced for non-commercial information with attribution
- Paginated: `limit` (default 50, max 1000) and `offset`; also `format=csv`

| Parameter | In | Type | Description |
| --- | --- | --- | --- |
| `q` | query | string | Search title, employer, category and snippet. Example: `nurse`. |
| `category` | query | string | Category name or slug (see /jobs/categories). Example: `health-care`. |
| `employer` | query | string | Employer slug (see /jobs/employers). Example: `northern-health`. |
| `term` | query | string | Permanent, Temporary, Casual, Seasonal, Contract or Auxiliary. |
| `hours` | query | string | full-time or part-time. One of: `full-time`, `part-time`. |
| `workplace` | query | string | on-site, hybrid, remote or on-the-road (only when the posting says). One of: `on-site`, `hybrid`, `remote`, `on-the-road`. |
| `within` | query | integer | Posted within this many days. Example: `7`. |
| `minWage` | query | number | Minimum hourly-equivalent wage (only postings that publish a wage). Example: `25`. |
| `source` | query | string | Source id (see /jobs/sources). Example: `jobbank`. |
| `sort` | query | string | newest (default), closing, wage or title. One of: `newest`, `closing`, `wage`, `title`. |
| `since` | query | string | Incremental sync: only postings added, changed or closed after this ISO date-time, oldest change first, including closed ones (`status: closed`, `closedAt`). Store `meta.updatedAt` and pass it next time. Example: `2026-09-30T00:00:00Z`. |
| `limit` | query | integer | Items per page (default 50, max 500 unless noted). Example: `20`. |
| `offset` | query | integer | Items to skip. Use `links.next` to page. Example: `0`. |

Also accepts `fields` (sparse fieldset) and `format` (`json`, `md`, `csv`).

**Example request**

```bash
curl "https://princegeorgepulse.ca/api/v1/jobs?limit=3"
```

**Example response** (trimmed)

```json
{
  "data": [
    {
      "id": "_uk2n7RXh1jU",
      "title": "Hardware Sales Associate: Full Time - PRINCE GEORGE",
      "employer": "The Home Depot",
      "location": "Prince George, BC",
      "workplace": null,
      "posted": "2026-10-16",
      "closes": null,
      "term": null,
      "hours": "Full time",
      "wage": {
        "min": 39312,
        "max": 41392,
        "unit": "year",
        "hourlyMin": 18.9,
        "text": "$39,312 - $41,392 annually"
      },
      "snippet": "",
      "category": "Sales & service",
      "…": "10 more keys"
    },
    {
      "id": "bPIWv6sJ84Gk",
      "title": "Housekeeping supervisor",
      "employer": "Sandman Hotel Group",
      "location": "Prince George, BC",
      "workplace": null,
      "posted": "2026-10-16",
      "closes": null,
      "term": "Permanent",
      "hours": "Full time",
      "wage": {
        "min": 20.3,
        "max": null,
        "unit": "hour",
        "hourlyMin": 20.3,
        "text": "$20.30 to $20.30 hourly"
      },
      "snippet": "",
      "category": "Sales & service",
      "…": "10 more keys"
    },
    "… 1 more"
  ],
  "meta": {
    "source": "PG Pulse jobs, aggregated from public job boards and employer career sites (each posting links its source)",
    "sourceUrl": "https://princegeorgepulse.ca/jobs/",
    "updatedAt": "2026-10-16T13:36:24.083Z",
    "ageSec": 7976,
    "license": "Posting facts from each source (see `source`, `via` and `url` per posting); Job Bank content © Government of Canada, reproduced for non-commercial information with attribution",
    "attribution": "Each posting’s source, via PG Pulse (princegeorgepulse.ca)",
    "total": 782,
    "count": 3,
    "limit": 3,
    "offset": 0
  },
  "links": {
    "self": "/api/v1/jobs?limit=3",
    "next": "/api/v1/jobs?limit=3&offset=3",
    "docs": "/developers/reference/jobs/#get-jobs"
  }
}
```

## GET /api/v1/jobs/categories {#get-jobs-categories}

Job categories with open-posting counts.

- Cache: 10 min
- Source: [PG Pulse jobs, aggregated from public job boards and employer career sites (each posting links its source)](https://princegeorgepulse.ca/jobs/)
- Licence: Posting facts from each source (see `source`, `via` and `url` per posting); Job Bank content © Government of Canada, reproduced for non-commercial information with attribution

Also accepts `fields` (sparse fieldset) and `format` (`json`, `md`).

**Example request**

```bash
curl "https://princegeorgepulse.ca/api/v1/jobs/categories"
```

**Example response** (trimmed)

```json
{
  "data": [
    {
      "name": "Health care",
      "slug": "health-care",
      "count": 208
    },
    {
      "name": "Education & child care",
      "slug": "education-and-child-care",
      "count": 88
    },
    "… 13 more"
  ],
  "meta": {
    "source": "PG Pulse jobs, aggregated from public job boards and employer career sites (each posting links its source)",
    "sourceUrl": "https://princegeorgepulse.ca/jobs/",
    "updatedAt": "2026-10-16T13:36:24.083Z",
    "ageSec": 7976,
    "license": "Posting facts from each source (see `source`, `via` and `url` per posting); Job Bank content © Government of Canada, reproduced for non-commercial information with attribution",
    "attribution": "Each posting’s source, via PG Pulse (princegeorgepulse.ca)"
  },
  "links": {
    "self": "/api/v1/jobs/categories",
    "next": null,
    "docs": "/developers/reference/jobs/#get-jobs-categories"
  }
}
```

## GET /api/v1/jobs/employers {#get-jobs-employers}

Employers with open postings, most first.

- Cache: 10 min
- Source: [PG Pulse jobs, aggregated from public job boards and employer career sites (each posting links its source)](https://princegeorgepulse.ca/jobs/)
- Licence: Posting facts from each source (see `source`, `via` and `url` per posting); Job Bank content © Government of Canada, reproduced for non-commercial information with attribution
- Paginated: `limit` (default 50, max 1000) and `offset`; also `format=csv`

| Parameter | In | Type | Description |
| --- | --- | --- | --- |
| `limit` | query | integer | Items per page (default 50, max 500 unless noted). Example: `20`. |
| `offset` | query | integer | Items to skip. Use `links.next` to page. Example: `0`. |

Also accepts `fields` (sparse fieldset) and `format` (`json`, `md`, `csv`).

**Example request**

```bash
curl "https://princegeorgepulse.ca/api/v1/jobs/employers?limit=5"
```

**Example response** (trimmed)

```json
{
  "data": [
    {
      "slug": "northern-health",
      "name": "Northern Health",
      "count": 136,
      "top": true
    },
    {
      "slug": "sd57",
      "name": "School District No. 57 (Prince George)",
      "count": 54,
      "top": true
    },
    "… 3 more"
  ],
  "meta": {
    "source": "PG Pulse jobs, aggregated from public job boards and employer career sites (each posting links its source)",
    "sourceUrl": "https://princegeorgepulse.ca/jobs/",
    "updatedAt": "2026-10-16T13:36:24.083Z",
    "ageSec": 7976,
    "license": "Posting facts from each source (see `source`, `via` and `url` per posting); Job Bank content © Government of Canada, reproduced for non-commercial information with attribution",
    "attribution": "Each posting’s source, via PG Pulse (princegeorgepulse.ca)",
    "total": 285,
    "count": 5,
    "limit": 5,
    "offset": 0
  },
  "links": {
    "self": "/api/v1/jobs/employers?limit=5",
    "next": "/api/v1/jobs/employers?limit=5&offset=5",
    "docs": "/developers/reference/jobs/#get-jobs-employers"
  }
}
```

## GET /api/v1/jobs/top-employers {#get-jobs-top-employers}

Top employers in Prince George (City of Prince George list) with their current openings here.

The list is the City’s own; it publishes no headcounts. `openings` counts postings in this feed right now, not all of an employer’s vacancies.

- Cache: 1 h
- Source: [City of Prince George, Move Up Prince George: industries and employers](https://www.moveupprincegeorge.ca/working-here/industries-and-employers)
- Licence: Facts from City of Prince George, Move Up Prince George’s published list

Also accepts `fields` (sparse fieldset) and `format` (`json`, `md`).

**Example request**

```bash
curl "https://princegeorgepulse.ca/api/v1/jobs/top-employers"
```

**Example response** (trimmed)

```json
{
  "data": [
    {
      "slug": "northern-health",
      "name": "Northern Health",
      "sector": "Health care",
      "note": "The largest employer in Prince George, per the City",
      "careersUrl": "https://careers.northernhealth.ca/",
      "openings": 136
    },
    {
      "slug": "city-of-prince-george",
      "name": "City of Prince George",
      "sector": "Local government",
      "careersUrl": "https://www.princegeorge.ca/city-hall/careers",
      "openings": 9
    },
    "… 7 more"
  ],
  "meta": {
    "source": "City of Prince George, Move Up Prince George: industries and employers",
    "sourceUrl": "https://www.moveupprincegeorge.ca/working-here/industries-and-employers",
    "updatedAt": "2026-10-16T13:36:24.083Z",
    "ageSec": 7976,
    "license": "Facts from City of Prince George, Move Up Prince George’s published list",
    "attribution": "City of Prince George, Move Up Prince George, via PG Pulse (princegeorgepulse.ca)"
  },
  "links": {
    "self": "/api/v1/jobs/top-employers",
    "next": null,
    "docs": "/developers/reference/jobs/#get-jobs-top-employers"
  }
}
```

## GET /api/v1/jobs/market {#get-jobs-market}

Job market context: latest Labour Force Survey figures for the local economic region and the province (keys `cariboo` and `bc` are kept for compatibility).

- Cache: 24 h
- Source: [Statistics Canada, Labour Force Survey](https://www150.statcan.gc.ca/t1/tbl1/en/tv.action?pid=1410046401)
- Licence: Statistics Canada Open Licence (https://www.statcan.gc.ca/en/terms-conditions/open-licence)

Also accepts `fields` (sparse fieldset) and `format` (`json`, `md`).

**Example request**

```bash
curl "https://princegeorgepulse.ca/api/v1/jobs/market"
```

**Example response** (trimmed)

```json
{
  "data": {
    "region": "Cariboo economic region (includes Prince George, Quesnel, Williams Lake and 100 Mile House)",
    "notes": "The Labour Force Survey does not publish city-level estimates for Prince George; the cariboo economic region is the smallest geography available. Monthly values are three-month moving averages, not seasonally adjusted.",
    "asOf": "2026-09",
    "monthly": {
      "cariboo": {
        "unemploymentRate": {
          "month": "2026-09",
          "value": 6.2
        },
        "employmentThousands": {
          "month": "2026-09",
          "value": 84.8
        }
      },
      "bc": {
        "unemploymentRate": {
          "month": "2026-09",
          "value": 6.7
        },
        "employmentThousands": {
          "month": "2026-09",
          "value": 2949
        }
      }
    },
    "annual": {
      "cariboo": {
        "unemploymentRate": {
          "year": 2025,
          "value": 7.5
        },
        "participationRate": {
          "year": 2025,
          "value": 60.2
        },
        "employmentRate": {
          "year": 2025,
          "value": 55.7
        }
      },
      "bc": {
        "unemploymentRate": {
          "year": 2025,
          "value": 6.2
        },
        "participationRate": {
          "year": 2025,
          "value": 65
        },
        "employmentRate": {
          "year": 2025,
          "value": 60.9
        }
      }
    },
    "postings": {
      "open": 782,
      "updatedAt": "2026-10-16T13:36:24.083Z"
    }
  },
  "meta": {
    "source": "Statistics Canada, Labour Force Survey",
    "sourceUrl": "https://www150.statcan.gc.ca/t1/tbl1/en/tv.action?pid=1410046401",
    "updatedAt": "2026-10-12T13:20:13.809Z",
    "ageSec": 354546,
    "license": "Statistics Canada Open Licence (https://www.statcan.gc.ca/en/terms-conditions/open-licence)",
    "attribution": "Statistics Canada, via PG Pulse (princegeorgepulse.ca)"
  },
  "links": {
    "self": "/api/v1/jobs/market",
    "next": null,
    "docs": "/developers/reference/jobs/#get-jobs-market"
  }
}
```

## GET /api/v1/jobs/stats {#get-jobs-stats}

Job-market stats from the posting history: open, new and closed postings per week, by category and top employers.

Weekly series (weeks ending Sunday, oldest first) computed from every posting this feed has tracked since `trackedSince`. `open` = postings listed at the end of the week, `added` = first seen that week, `closed` = no longer listed. `medianHourly` is the median hourly-equivalent wage of open postings that publish one. Counts reflect the sources this feed covers, not the whole labour market.

- Cache: 30 min
- Source: [PG Pulse jobs, aggregated from public job boards and employer career sites (each posting links its source)](https://princegeorgepulse.ca/jobs/)
- Licence: Posting facts from each source (see `source`, `via` and `url` per posting); Job Bank content © Government of Canada, reproduced for non-commercial information with attribution

| Parameter | In | Type | Description |
| --- | --- | --- | --- |
| `weeks` | query | integer | Weeks of history (4 to 104, default 26). Example: `12`. |

Also accepts `fields` (sparse fieldset) and `format` (`json`, `md`).

**Example request**

```bash
curl "https://princegeorgepulse.ca/api/v1/jobs/stats?weeks=12"
```

**Example response** (trimmed)

```json
{
  "data": {
    "weeks": [
      "2026-10-04",
      "2026-10-11",
      "… 1 more"
    ],
    "trackedSince": "2026-09-30T23:03:55.829Z",
    "open": [
      793,
      779,
      "… 1 more"
    ],
    "added": [
      866,
      161,
      "… 1 more"
    ],
    "closed": [
      73,
      175,
      "… 1 more"
    ],
    "byCategory": [
      {
        "name": "Health care",
        "slug": "health-care",
        "open": [
          200,
          205,
          "… 1 more"
        ],
        "added": [
          228,
          33,
          "… 1 more"
        ]
      },
      {
        "name": "Education & child care",
        "slug": "education-and-child-care",
        "open": [
          90,
          90,
          "… 1 more"
        ],
        "added": [
          92,
          15,
          "… 1 more"
        ]
      },
      "… 13 more"
    ],
    "topEmployers": [
      {
        "slug": "northern-health",
        "name": "Northern Health",
        "openNow": 136,
        "open": [
          131,
          131,
          "… 1 more"
        ],
        "added": [
          155,
          29,
          "… 1 more"
        ]
      },
      {
        "slug": "sd57",
        "name": "School District No. 57 (Prince George)",
        "openNow": 54,
        "open": [
          57,
          55,
          "… 1 more"
        ],
        "added": [
          58,
          10,
          "… 1 more"
        ]
      },
      "… 8 more"
    ],
    "medianHourly": [
      27.52,
      27.52,
      "… 1 more"
    ]
  },
  "meta": {
    "source": "PG Pulse jobs, aggregated from public job boards and employer career sites (each posting links its source)",
    "sourceUrl": "https://princegeorgepulse.ca/jobs/",
    "updatedAt": "2026-10-16T13:36:24.083Z",
    "ageSec": 7976,
    "license": "Posting facts from each source (see `source`, `via` and `url` per posting); Job Bank content © Government of Canada, reproduced for non-commercial information with attribution",
    "attribution": "Each posting’s source, via PG Pulse (princegeorgepulse.ca)"
  },
  "links": {
    "self": "/api/v1/jobs/stats?weeks=12",
    "next": null,
    "docs": "/developers/reference/jobs/#get-jobs-stats"
  }
}
```

## GET /api/v1/jobs/sources {#get-jobs-sources}

Sources the jobs feed is built from, with status and counts.

- Cache: 10 min
- Source: [PG Pulse jobs](https://princegeorgepulse.ca/jobs/)
- Licence: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)

Also accepts `fields` (sparse fieldset) and `format` (`json`, `md`).

**Example request**

```bash
curl "https://princegeorgepulse.ca/api/v1/jobs/sources"
```

**Example response** (trimmed)

```json
{
  "data": [
    {
      "id": "city-pg",
      "name": "City of Prince George careers",
      "url": "https://princegeorgejobs.prevueaps.ca/jobs/",
      "ok": true,
      "count": 6,
      "listed": 6,
      "raw": 6,
      "ms": 2155,
      "kept": false,
      "checkedAt": "2026-10-16T13:35:05.934Z",
      "lastSuccess": "2026-10-16T13:35:05.934Z"
    },
    {
      "id": "rdffg",
      "name": "Regional District of Fraser-Fort George careers",
      "url": "https://rdffg.prevueaps.ca/jobs/",
      "ok": true,
      "count": 1,
      "listed": 1,
      "raw": 1,
      "ms": 2111,
      "kept": false,
      "checkedAt": "2026-10-16T13:35:05.934Z",
      "lastSuccess": "2026-10-16T13:35:05.934Z"
    },
    "… 6 more"
  ],
  "meta": {
    "source": "PG Pulse jobs",
    "sourceUrl": "https://princegeorgepulse.ca/jobs/",
    "updatedAt": "2026-10-16T13:36:24.083Z",
    "ageSec": 7976,
    "license": "CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)",
    "attribution": "PG Pulse (princegeorgepulse.ca)"
  },
  "links": {
    "self": "/api/v1/jobs/sources",
    "next": null,
    "docs": "/developers/reference/jobs/#get-jobs-sources"
  }
}
```

## GET /api/v1/jobs/{id} {#get-jobs-id}

One job posting.

- Cache: 10 min
- Source: [PG Pulse jobs, aggregated from public job boards and employer career sites (each posting links its source)](https://princegeorgepulse.ca/jobs/)
- Licence: Posting facts from each source (see `source`, `via` and `url` per posting); Job Bank content © Government of Canada, reproduced for non-commercial information with attribution

| Parameter | In | Type | Description |
| --- | --- | --- | --- |
| `id` | path | string | Posting id (from /jobs). Required. |

Also accepts `fields` (sparse fieldset) and `format` (`json`, `md`).

**Example request**

```bash
curl "https://princegeorgepulse.ca/api/v1/jobs/_uk2n7RXh1jU"
```

**Example response** (trimmed)

```json
{
  "data": {
    "id": "_uk2n7RXh1jU",
    "title": "Hardware Sales Associate: Full Time - PRINCE GEORGE",
    "employer": "The Home Depot",
    "location": "Prince George, BC",
    "workplace": null,
    "posted": "2026-10-16",
    "closes": null,
    "term": null,
    "hours": "Full time",
    "wage": {
      "min": 39312,
      "max": 41392,
      "unit": "year",
      "hourlyMin": 18.9,
      "text": "$39,312 - $41,392 annually"
    },
    "snippet": "",
    "category": "Sales & service",
    "…": "10 more keys"
  },
  "meta": {
    "source": "PG Pulse jobs, aggregated from public job boards and employer career sites (each posting links its source)",
    "sourceUrl": "https://princegeorgepulse.ca/jobs/",
    "updatedAt": "2026-10-16T13:36:24.083Z",
    "ageSec": 7976,
    "license": "Posting facts from each source (see `source`, `via` and `url` per posting); Job Bank content © Government of Canada, reproduced for non-commercial information with attribution",
    "attribution": "Each posting’s source, via PG Pulse (princegeorgepulse.ca)"
  },
  "links": {
    "self": "/api/v1/jobs/_uk2n7RXh1jU",
    "next": null,
    "docs": "/developers/reference/jobs/#get-jobs-id"
  }
}
```
