Skip to content
PG Pulse
PG Pulse

Try searching for

Local knowledge for your AI tools

Connect Cursor, VS Code, Codex or Claude Code. Free MCP access, no key needed.

Connect your AI assistant
View as MarkdownFree, no key needed

Quickstart

No key and no sign-up: every public data endpoint is a plain GET on https://princegeorgepulse.ca/api/v1. These examples use discovery endpoints available on every city instance. Use the reference for enabled local datasets.

curl #

bash
# Public pages and local search
curl --fail-with-body "https://princegeorgepulse.ca/api/v1/pages?limit=5"
curl --fail-with-body "https://princegeorgepulse.ca/api/v1/search?q=parks&per=3"

# A compact result, or readable Markdown
curl --fail-with-body "https://princegeorgepulse.ca/api/v1/pages?limit=5&fields=title,url"
curl --fail-with-body -H "Accept: text/markdown" "https://princegeorgepulse.ca/api/v1/pages?limit=5"

# Read the ETag, then send it back to check for changes
curl -I "https://princegeorgepulse.ca/api/v1/pages?limit=5"
curl -i -H 'If-None-Match: W/"replace-with-etag-from-above"' "https://princegeorgepulse.ca/api/v1/pages?limit=5"

A conditional request can return 304 with no body; reuse the response you already cached. Missing or stale data is not zero: check meta.stale, meta.updatedAt and each source's status.

JavaScript #

This example reads a paginated collection with a deadline per request, at most three attempts per page, and a page cap. It follows only this API's pagination links. A rate limit that exceeds the retry budget is returned to your application rather than retried forever.

js
const BASE = 'https://princegeorgepulse.ca/api/v1'

async function all(path, maxPages = 100) {
  const out = [], seen = new Set()
  let next = new URL(path, BASE + '/')
  for (let page = 0; next && page < maxPages; page++) {
    if (next.origin !== new URL(BASE).origin || !next.pathname.startsWith('/api/v1/')) {
      throw new Error('Unexpected pagination destination')
    }
    if (seen.has(next.href)) throw new Error('Repeated pagination link')
    seen.add(next.href)
    let response
    for (let attempt = 0; attempt < 3; attempt++) {
      response = await fetch(next, { signal: AbortSignal.timeout(15000), redirect: 'error' })
      if (![429, 503].includes(response.status) || attempt === 2) break
      const delay = Number(response.headers.get('Retry-After') || 5)
      if (!Number.isFinite(delay) || delay < 1 || delay > 60) break
      await response.body?.cancel()
      await new Promise(resolve => setTimeout(resolve, delay * 1000))
    }
    if (!response.ok) throw new Error(`API returned HTTP ${response.status}`)
    const body = await response.json()
    if (!Array.isArray(body.data)) throw new Error('Expected a list endpoint')
    if (body.meta?.stale) console.warn('Using stale data:', body.meta.attribution)
    out.push(...body.data)
    next = body.links?.next ? new URL(body.links.next, BASE + '/') : null
  }
  if (next) throw new Error('Page cap reached; narrow the filters or resume explicitly')
  return out
}

const pages = await all('pages?limit=100')
console.log(pages.length, 'public pages')

Python #

python
import requests

BASE = "https://princegeorgepulse.ca/api/v1"
response = requests.get(BASE + "/pages", params={"limit": 5}, timeout=15)
response.raise_for_status()
body = response.json()
print("Source:", body["meta"]["attribution"])
for page in body["data"]:
    print(page.get("title"), page.get("url"))
print("Next page:", body["links"].get("next"))

Keep the source credit and licence when storing or displaying results. Cache successful responses for the advertised lifetime; honour Retry-After when you receive 429 or 503.

For AI agents #

  • Connect through MCP: install links and configuration for Cursor, VS Code, Codex and Claude Code.
  • Start at llms.txt for discovery.
  • Read any public page as Markdown by adding .md, for example https://princegeorgepulse.ca/about.md.
  • Use format=md on a public data API call for readable output.
  • Use the OpenAPI document for parameter and response schemas. Prefer targeted MCP discovery over loading the entire specification into a prompt.

Add PG Pulse to your home screen

Your browser installs apps from its Share menu.

  1. Tap Share in the browser toolbar (at the bottom of the screen on iPhone, at the top on iPad).
  2. Scroll down and tap Add to Home Screen.
  3. Tap Add. PG Pulse opens from its icon like any other app.