pointmoon · built with

Four shipped products read Pointmoon.

The useful question before you integrate is not what the API returns — the reference answers that. It is whether anyone has actually built on it, and what that looked like. Here are four, each with the surface it powers, the exact response paths it takes, the file in its own repo that proves it, and a payload captured from the live host.

All four are Wyld Way products. That is the whole of the truth: Pointmoon has no outside adopters yet, and nothing here implies otherwise. No logos, no testimonials, no “trusted by”. How outside callers get counted, when they arrive, is in the adoption doc.

At a glance

ProductWhat it isSurface it calls
Nature ClassNext.js web app. Server-side reads, one client, cached ~15 minutes per location./api/moon?audience=facts
Mindful AgentNative Swift. No SDK, no npm — URLComponents and URLSession against the hosted host./api/moon?audience=facts&humanProfile=work
Rewyld — the /outside city and spot pagesNext.js, two different time horizons: an ISR read at one hour for conditions, and a build-time precompute for spots that writes static JSON into the repo./api/moon?audience=facts + /api/spots/bulk
Rewyld — the Nature Intel notification cronNode/Express server-to-server, holding a service token, feeding a language model./api/moon?includeKernelContext=true

nature-class · verified 2026-09-02

Nature Class

A schools product. A class picks a real place, and the day's lesson is grounded in what is actually outside that window — what has been seen there in the last week, what the sky is doing, whether the ground is wet.

Why it is here. Pointmoon is this product's only runtime source of species observations, weather, and sky. It is not one feed among several — delete it and the product has nothing to say about the world outside the window.

The request

GET /api/moon?audience=facts&lat={lat}&lng={lng}[&observationTaxa={taxa}]

Pinned to: field-truth@1.1.0

Surfaces it powers

  • SeenNearby — the photographed sightings recorded near the class this week
  • FieldGuidePlate — a plate for one species, with its photo credit
  • WorldAround — the region, from the OSM-derived outdoor.place.* signals
  • DailyCard — the day's one card: sky, ground, light left
  • TodayDay — the day screen that awaits both the Pointmoon read and the cast

Where the integration is, in that repo

  • lib/outside/pointmoon.ts:558 Builds the request URL from `base + "/api/moon?audience=facts&lat=" + lat + "&lng=" + lng` plus an optional `observationTaxa` scope. The file's own header calls itself "the single Pointmoon client".
  • lib/outside/pointmoon-contract.ts:10 `POINTMOON_SOURCE_SCHEMA_VERSION = "field-truth@1.1.0"` — the consumer pins a schema version, as the contract asks.
  • lib/outside/pointmoon-contract.ts A validated projection at the boundary: "Pointmoon owns a much larger field-truth response. This module deliberately validates only the observation slice Nature Class consumes." Renderers never see the raw response.
  • PRIOR-ART.md:9 "Pointmoon (Apache-2.0), a separate nature-intelligence service. This project consumes it strictly as an external HTTP API; no Pointmoon source is vendored here."
  • lib/observation-tools.ts:128 In the product's own words: iNaturalist "is this product's species record (through Pointmoon)". The entry is a link catalogue for teachers, not a data client.
  • tests/unit/pointmoon-consumer-contract.spec.ts A consumer-side contract suite that fails if the projection stops matching the payload. Six spec files in tests/unit/ are named for this integration (pointmoon-archive-boundary, -cache-isolation, -condition-fixtures, -consumer-contract, -fetch-projection, -valid-until-cache), carrying 26 test cases between them; 45 files under tests/unit/ mention Pointmoon at all.
  • tests/fixtures/pointmoon/london_uk_2026-08-17.json Recorded real Pointmoon responses, committed, and replayed offline by the deterministic suite.

The sole-source claim, checked

Pointmoon is the only nature or weather feed reachable from a shipped surface.

grep -rnE 'api\.inaturalist\.org|api\.gbif\.org|nominatim|open-meteo|api\.weather\.gov|openweathermap|api\.ebird\.org' app/ lib/

Three hits, and none of them is a nature feed the product reads. (1) lib/observation-tools.ts:136 — a host allowlist for teacher-facing links, not a client. (2) lib/outside/gbif.ts:138 — a real GBIF occurrence client, and it does fetch (:151), but nothing on a shipped surface calls it: its only caller is scripts/probe-seasonal.mjs, a probe. It was written for seasonality (#305), which Pointmoon's recency-shaped observations do not answer, and it is not wired in. (3) lib/outside/geocode.ts:60 — Nominatim, live from app/api/geocode/route.ts, but it is a geocoder: it turns a place a teacher typed into a coordinate, and reports nothing about nature or weather. Separately, scripts/build-taxon-reference.mjs queries iNaturalist at build time for reference photographs of a hand-typed species list; it runs at build time, not in the product, and that list is on its way out. So: every species observation, every weather reading and every sky value the product shows comes from Pointmoon.

Response paths it reads

facts.signals
facts.fieldSnapshot.time.timezone
facts.fieldSnapshot.time.timeOfDay
facts.fieldSnapshot.time.daylightChangeMinutes
facts.fieldSnapshot.time.windows.daylightMinutesRemaining
facts.fieldSnapshot.time.windows.isNearSunset
facts.fieldSnapshot.astronomy.sunriseIso
facts.fieldSnapshot.astronomy.sunsetIso
facts.fieldSnapshot.astronomy.moonPhaseLabel
facts.fieldSnapshot.astronomy.moonIlluminationPct
facts.fieldSnapshot.astronomy.daysToNextFullMoon
facts.fieldSnapshot.astronomy.isDay
facts.fieldSnapshot.astronomy.upcomingEvents
facts.fieldSnapshot.ground.state
facts.fieldSnapshot.ground.hoursSinceMeaningfulPrecipitation
facts.fieldSnapshot.weather.current.skyCondition
facts.fieldSnapshot.weather.current.cloudCoverPct
facts.fieldSnapshot.weather.current.windKph
facts.fieldSnapshot.weather.current.precipitationRateMmPerHour
facts.fieldSnapshot.weather.current.felt.apparentC
facts.fieldSnapshot.place.placeName
facts.fieldSnapshot.place.evidence
facts.fieldSnapshot.observations.nearby
facts.fieldSnapshot.observations.birds.notable
facts.fieldSnapshot.observations.absent
facts.fieldSnapshot.observations.recentWindowDays
facts.fieldSnapshot.observations.historical.nearby
facts.fieldSnapshot.observations.historical.resolutionStatus
facts.fieldSnapshot.observations.historical.resolutionReason
facts.fieldSnapshot.observations.validUntil
facts.fieldSnapshot.weather.current.skyCover

Each of those 31 paths is pinned by contract/facts-frozen.json and asserted by src/lib/showcase.test.ts. Rename or drop one and this page goes red.

Real payload

Observations resolved — a real photographed sighting near a coordinate

GET https://pointmoon.vercel.app/api/moon?audience=facts&lat=37.8715&lng=-122.273

Captured 2026-09-02T20:49:16Z · schemaVersion: field-truth@1.1.0Captured with curl against the hosted host. Values are verbatim; arrays marked `truncated` keep their first element only. Nothing here is hand-written.

{
  "facts.fieldSnapshot.observations.provider": "inaturalist",
  "facts.fieldSnapshot.observations.resolutionStatus": "resolved",
  "facts.fieldSnapshot.observations.recentWindowDays": 7,
  "facts.fieldSnapshot.observations.validUntil": "2026-09-03T20:49:16.745Z",
  // first of 15 elements
  "facts.fieldSnapshot.observations.nearby": [
    {
      "scientificName": "Sciurus niger",
      "name": "Eastern Fox Squirrel",
      "count": 11,
      "photoUrl": "https://inaturalist-open-data.s3.amazonaws.com/photos/727191038/large.jpg",
      "presence": {
        "provider": "inaturalist",
        "taxonId": "46020",
        "observationCount": 11,
        "radiusKm": 5,
        "windowStart": "2026-08-26",
        "windowEnd": "2026-09-02"
      },
      "photo": {
        "url": "https://inaturalist-open-data.s3.amazonaws.com/photos/727191038/large.jpg",
        "role": "observation",
        "creator": "reynman",
        "attribution": "(c) reynman, some rights reserved (CC BY-NC)",
        "license": "cc-by-nc",
        "sourceUrl": "https://www.inaturalist.org/photos/727191038",
        "observationId": "396531800",
        "observedAt": "2026-09-02T01:04:13.000Z"
      },
      "iconicTaxon": "Mammalia",
      "emerged": true,
      "historicalAvgCount": 2,
      "yearsObserved": 1,
      "sampledYears": 3,
      "ratioToHistorical": 5.5,
      "epistemicType": "measured_derived",
      "sourceSupport": [
        "observation",
        "seasonal"
      ],
      "baselineDepth": "rich",
      "baselineQuality": 1,
      "anomalyQuality": 1
    }
  ],
  "facts.fieldSnapshot.weather.current.skyCover": "cloudy"
}

Observations unresolved — typed silence, with a reason, on the same shape

GET https://pointmoon.vercel.app/api/moon?audience=facts&lat=51.546&lng=-0.105

Captured 2026-09-02T20:49:16Z · schemaVersion: field-truth@1.1.0The same request shape at a coordinate whose observation fetch timed out on this call. The block is present and says so; it does not guess and it is not an error.

{
  "facts.fieldSnapshot.observations.provider": null,
  "facts.fieldSnapshot.observations.resolutionStatus": "unresolved",
  "facts.fieldSnapshot.observations.resolutionReason": "observation-fetch-timeout",
  "facts.fieldSnapshot.observations.nearby": [],
  "provenance.mode": "live",
  "provenance.sourceConfidence": "partial"
}

What a first integrator can take from it. Validate and project at the boundary. This consumer never hands a raw Pointmoon response to a renderer; it parses the slice it wants into its own versioned type, and everything that fails validation becomes absence, which the surface knows how to show.

rewyld-step-outside · verified 2026-09-02

Mindful Agent

A macOS menu-bar app. It decides whether it is worth interrupting someone to say the sky is doing something, and what to say about it.

Why it is here. It is the proof that the HTTP surface needs nothing but HTTP. The whole client is 270 lines of Swift with no Pointmoon dependency of any kind.

The request

GET /api/moon?audience=facts&humanProfile=work&lat={coarse}&lng={coarse}

Pinned to: hosted default https://pointmoon.vercel.app

Surfaces it powers

  • The mirror panel's "Outside now" row — the one Pointmoon surface a user sees in the shipped build. Fed by refreshSky() (AppController.swift:1632), which is not gated: no location, offline, typed silence or a not-worth-it verdict all resolve to no row rather than an invented one.
  • The nudge tail — the clause about the sky appended to an interruption. GATED IN M1: the shipped default is observeOnly = true (AppConfig.swift:78), so the decider still runs and reaches a fire verdict and no speaking surface renders it (AppController.swift:2178, "observe-only (M1): would fire, held silent"). The read is real today; the interruption is held.
  • The worth-it decision — bad air or clearly bad sky means do not send. Same M1 gate: computed every tick, not currently delivered.

Where the integration is, in that repo

  • Sources/StepOutsideCore/Sky/PointmoonClient.swift:162 `buildURL` composes /api/moon with audience=facts and humanProfile=work, rounding the location to a coarse cell before it leaves the machine.
  • Sources/StepOutsideCore/Sky/PointmoonClient.swift:195 `if (root["silent"] as? Bool) == true { return .unknown }` — typed silence honoured as a first-class shape, not treated as an error.
  • Sources/StepOutsideCore/Sky/PointmoonClient.swift:196 A comment recording a real bug: the client resolves facts.fieldSnapshot explicitly because reading the wrong path "is exactly how the sky signal silently went generic".
  • Sources/StepOutsideCore/Config/AppConfig.swift:66 `pointmoonBaseURL: URL = URL(string: "https://pointmoon.vercel.app")!` — the shipped default is the hosted host.
  • Sources/StepOutsideCore/NudgeEngine.swift:78 The nudge engine holds the client; the sky read is part of the decision to interrupt, not decoration on it.

Response paths it reads

facts.fieldSnapshot.weather.current.skyCondition
facts.fieldSnapshot.weather.current.temperatureC
facts.fieldSnapshot.astronomy.isDay
facts.fieldSnapshot.astronomy.primaryEvent

Each of those 4 paths is pinned by contract/facts-frozen.json and asserted by src/lib/showcase.test.ts. Rename or drop one and this page goes red.

Real payload

The astronomy axis and the current weather block

GET https://pointmoon.vercel.app/api/moon?audience=facts&lat=42.36&lng=-71.06

Captured 2026-09-02T20:49:16Z · schemaVersion: field-truth@1.1.0Captured with curl against the hosted host. Values are verbatim.

{
  "schemaVersion": "field-truth@1.1.0",
  "axes.time.calendar.season": "summer",
  "axes.time.calendar.seasonDay": 73,
  "axes.time.solar.sunsetIso": "2026-09-02T23:16:24.212Z",
  "axes.time.lunar.phase": "waning-gibbous",
  "axes.time.lunar.illuminationFraction": 0.6647718297023698,
  "axes.time.lunar.daysToNextFull": 24,
  "facts.fieldSnapshot.weather.current.skyCondition": "overcast",
  "facts.fieldSnapshot.weather.current.temperatureC": 21,
  "facts.fieldSnapshot.weather.current.felt.apparentC": 21,
  "facts.fieldSnapshot.astronomy.isDay": true,
  "facts.fieldSnapshot.astronomy.primaryEvent": null,
  "facts.fieldSnapshot.time.windows.daylightMinutesRemaining": 151,
  "adapter.meta.adapterMode": "live",
  "provenance.providers": {
    "weather": "open-meteo",
    "place": "osm",
    "hydro": "unresolved",
    "phenology": "pointmoon-weather-proxy"
  }
}

Observations unresolved — typed silence, with a reason, on the same shape

GET https://pointmoon.vercel.app/api/moon?audience=facts&lat=51.546&lng=-0.105

Captured 2026-09-02T20:49:16Z · schemaVersion: field-truth@1.1.0The same request shape at a coordinate whose observation fetch timed out on this call. The block is present and says so; it does not guess and it is not an error.

{
  "facts.fieldSnapshot.observations.provider": null,
  "facts.fieldSnapshot.observations.resolutionStatus": "unresolved",
  "facts.fieldSnapshot.observations.resolutionReason": "observation-fetch-timeout",
  "facts.fieldSnapshot.observations.nearby": [],
  "provenance.mode": "live",
  "provenance.sourceConfidence": "partial"
}

What a first integrator can take from it. Be tolerant in one direction only. Every missing field, the silent shape, and unparseable JSON all collapse to one verdict — `.unknown`, which produces no claim at all. The app would rather say nothing than say something it cannot source.

rewyld · verified 2026-09-02

Rewyld — the /outside city and spot pages

Public city pages that say what the light and the season are doing there, and list real green space nearby.

Why it is here. It shows Pointmoon used for content rather than for a live widget — the output is committed to a repo and served as static HTML.

The request

GET /api/moon?lat={lat}&lng={lng}&place={name}&audience=facts
POST /api/spots/bulk

Pinned to: axes.time (the astronomy axis), all fields optional and guarded

Surfaces it powers

  • The city conditions strip — sunset, day length, moon, season, best light
  • The spot grid — up to eight OSM-derived places per city, with ODbL attribution carried alongside

Where the integration is, in that repo

  • src/app/outside/conditions.ts:61 The conditions request, retried once with a 6s timeout and returning null on any shape surprise.
  • src/app/outside/conditions.ts:76 `const time = json?.axes?.time` — this consumer reads the axes surface, not the field snapshot.
  • scripts/spots/precompute-spots.js:108 A POST to `/api/spots/bulk` at build time, with a quality gate: a city ships only if it clears four spots at fit >= 0.5, otherwise it is skipped rather than stubbed.
  • src/app/outside/spots-data/index.json 21 cities shipped from one precompute run, generatedAt 2026-06-28T11:40:19.371Z.
  • src/app/outside/spots-data/boston.json:5 `"source": "pointmoon /api/spots/bulk"` — the committed artifact names where it came from. Its first spot is identical field for field to what /api/spots/bulk returned for the same coordinate on 2026-09-02, 66 days later.

Response paths it reads

axes.time.calendar.season
axes.time.calendar.seasonDay
axes.time.calendar.weekday
axes.time.solar.sunriseIso
axes.time.solar.sunsetIso
axes.time.solar.solarNoonIso
axes.time.solar.civilTwilightEndIso
axes.time.lunar.phase
axes.time.lunar.illuminationFraction
axes.time.lunar.daysToNextFull

Each of those 10 paths is pinned by contract/facts-frozen.json and asserted by src/lib/showcase.test.ts. Rename or drop one and this page goes red.

From the spots packet

spots[].name
spots[].kind
spots[].distanceKm
spots[].fit
spots[].areaAcres
spots[].water
spots[].badges
spots[].why
spots[].lat
spots[].lng
spots[].attribution
provenance.sourceConfidence

Real payload

The astronomy axis and the current weather block

GET https://pointmoon.vercel.app/api/moon?audience=facts&lat=42.36&lng=-71.06

Captured 2026-09-02T20:49:16Z · schemaVersion: field-truth@1.1.0Captured with curl against the hosted host. Values are verbatim.

{
  "schemaVersion": "field-truth@1.1.0",
  "axes.time.calendar.season": "summer",
  "axes.time.calendar.seasonDay": 73,
  "axes.time.solar.sunsetIso": "2026-09-02T23:16:24.212Z",
  "axes.time.lunar.phase": "waning-gibbous",
  "axes.time.lunar.illuminationFraction": 0.6647718297023698,
  "axes.time.lunar.daysToNextFull": 24,
  "facts.fieldSnapshot.weather.current.skyCondition": "overcast",
  "facts.fieldSnapshot.weather.current.temperatureC": 21,
  "facts.fieldSnapshot.weather.current.felt.apparentC": 21,
  "facts.fieldSnapshot.astronomy.isDay": true,
  "facts.fieldSnapshot.astronomy.primaryEvent": null,
  "facts.fieldSnapshot.time.windows.daylightMinutesRemaining": 151,
  "adapter.meta.adapterMode": "live",
  "provenance.providers": {
    "weather": "open-meteo",
    "place": "osm",
    "hydro": "unresolved",
    "phenology": "pointmoon-weather-proxy"
  }
}

A bulk spots packet — the build-time surface

POST https://pointmoon.vercel.app/api/spots/bulk body: {"requests":[{"id":"boston","lat":42.36,"lng":-71.06,"radiusM":5000,"max":20}]}

Captured 2026-09-02T20:49:16Z · schemaVersion: field-truth@1.1.0The same call rewyld's precompute makes. The first spot below is identical, field for field, to the one committed at rewyld src/app/outside/spots-data/boston.json on 2026-06-28.

{
  "packets[0].id": "boston",
  "packets[0].provenance": {
    "mode": "live",
    "sourceConfidence": "strong",
    "providers": {
      "overpass": "overpass-api.de"
    }
  },
  // first of 20 elements
  "packets[0].spots": [
    {
      "name": "Boston Public Garden",
      "type": "Park",
      "kind": "park",
      "distanceKm": 1.1,
      "fit": 0.87,
      "areaAcres": 23.4,
      "water": true,
      "conifer": false,
      "quiet": null,
      "badges": [
        "Park",
        "~23 acres",
        "Water on site"
      ],
      "why": "Open water to sit beside while everything slows down.",
      "image": null,
      "lat": 42.35394485468751,
      "lng": -71.069980190625,
      "source": "openstreetmap",
      "attribution": "© OpenStreetMap contributors (ODbL)"
    }
  ]
}

What a first integrator can take from it. A read can be a build step. Nothing about Pointmoon requires calling it at render time; this consumer calls it once, gates the result, commits it, and serves static HTML — with the source and the generation timestamp travelling in the file.

outdoorsBackend · verified 2026-09-02

Rewyld — the Nature Intel notification cron

A scheduled job that buckets users by a 0.1-degree grid, reads Pointmoon for each bucket, and grounds an authored notification in what it returns.

Why it is here. This is the LLM-grounding case: Pointmoon's job is to be the part of the prompt that is true. And it is the one consumer that acts on the silence — a silent read cancels the send.

The request

GET /api/moon?adapterMode=live&lat=&lng=&city=&pluginSafety=true&pluginNatureSensing=true&includeKernelContext=true&includeFieldSnapshot=true&humanProfile=&forTime=  (header: x-pointmoon-service-token)

Pinned to: field-truth@1 (major), warned at runtime on mismatch

Surfaces it powers

  • The daily Nature Intel push notification
  • The generated practice, whose factual claims come from the read

Where the integration is, in that repo

  • modules/api/NatureIntel/natureIntel.service.js:517 `const url = new URL('/api/moon', baseUrl)` and the parameter set above, including forTime so the solar geometry matches the listener's delivery moment rather than the server clock.
  • modules/api/NatureIntel/natureIntel.service.js:411 `POINTMOON_EXPECTED_SCHEMA_MAJOR = 'field-truth@1'`, checked on every response by checkPointmoonContract(), which also logs any entry in deprecated.fields that this consumer actually reads.
  • modules/api/NatureIntel/natureIntel.service.js:573 It watches adapter.meta.adapterMode and warns when Pointmoon served anything but live, so a stale-data bug report can be correlated with the mode in the logs.
  • cron/natureIntelCron.js:325 "Pointmoon silence = intentional skip. No fallback: better than inventing." A silent read sends nothing to anyone in that bucket.
  • __tests__/pointmoonCache.test.js Consumer-side tests for the cache and TTL behaviour around this integration; see also modules/api/NatureIntel/pointmoonCacheTtl.test.js.

Response paths it reads

schemaVersion
deprecated.fields
adapter.meta.adapterMode
provenance.mode
provenance.sourceConfidence
provenance.providers

Each of those 6 paths is pinned by contract/facts-frozen.json and asserted by src/lib/showcase.test.ts. Rename or drop one and this page goes red.

Not covered here. This consumer also passes includeKernelContext=true and reads the perception bundle it returns. That request is outside audience=facts, so the facts-contract lock does not cover those paths and they are deliberately not listed in `reads` — nothing here would go red if they changed.

Real payload

The astronomy axis and the current weather block

GET https://pointmoon.vercel.app/api/moon?audience=facts&lat=42.36&lng=-71.06

Captured 2026-09-02T20:49:16Z · schemaVersion: field-truth@1.1.0Captured with curl against the hosted host. Values are verbatim.

{
  "schemaVersion": "field-truth@1.1.0",
  "axes.time.calendar.season": "summer",
  "axes.time.calendar.seasonDay": 73,
  "axes.time.solar.sunsetIso": "2026-09-02T23:16:24.212Z",
  "axes.time.lunar.phase": "waning-gibbous",
  "axes.time.lunar.illuminationFraction": 0.6647718297023698,
  "axes.time.lunar.daysToNextFull": 24,
  "facts.fieldSnapshot.weather.current.skyCondition": "overcast",
  "facts.fieldSnapshot.weather.current.temperatureC": 21,
  "facts.fieldSnapshot.weather.current.felt.apparentC": 21,
  "facts.fieldSnapshot.astronomy.isDay": true,
  "facts.fieldSnapshot.astronomy.primaryEvent": null,
  "facts.fieldSnapshot.time.windows.daylightMinutesRemaining": 151,
  "adapter.meta.adapterMode": "live",
  "provenance.providers": {
    "weather": "open-meteo",
    "place": "osm",
    "hydro": "unresolved",
    "phenology": "pointmoon-weather-proxy"
  }
}

What a first integrator can take from it. Ground the prompt, and honour the silence. The value is not only in the facts that arrive; it is in the read that says it has nothing, which cancels a notification that would otherwise have been invented.

Deliberately not here

What did not make the list.

  • WyldWalk (outdoors, components/wq/quest-detail/QuestPointmoon.tsx, checked 2026-09-02). Not a consumer. The component is named for Pointmoon and types the signal families, but it ships resting-state only: "There are NO live calls and NO sample values in production. The live binding lands separately, when the nature-data endpoint exists." It is listed here so the omission is a recorded finding rather than a gap.

A product that could integrate is not a product that has. Case studies for intentions are how a showcase stops being evidence.

How this page is kept honest

The claims are checked, not asserted.

A showcase whose claims can rot silently is marketing. src/lib/showcase.test.ts runs in npm test and fails if any of this stops being true.

  • Every response path above is still pinned by contract/facts-frozen.json, and that baseline is asserted against the live server by npm run contract. Claims are a subset of the frozen contract, which is a subset of what the live host returns — so the day a field is renamed or dropped, this page goes red at the same moment the consumer breaks.
  • Every quoted value is a real capture whose runtime type still matches the frozen type tag for its path.
  • The repo doc and this page render from the same two data files, so neither can say something the other does not.
  • The README, the sitemap and the MCP server card all still reach this page. A showcase nobody can find is not shipped.

Start your own.

One call, nothing to install.

curl -s "https://pointmoon.vercel.app/api/moon?audience=facts&lat=42.36&lng=-71.06" | jq .

Then the quickstart, the API reference, and the silence contract.