Developers

Camp Notice’s camp directory and the live open/full status of watched camps, as a read-only HTTP API and an MCP server. No sign-up, no API key.

Quickstart

Search for a camp by name or town:

curl "https://campnotice.com/api/v1/camps?q=pine+hollow&limit=3"

Each result has an id like california/camp-kennolyn. Fetch one camp — its facts, listed programs and, when parents watch it, each session’s status and when we last read it:

curl "https://campnotice.com/api/v1/camps/california/camp-kennolyn"

Every response is JSON with ok: true on success. The states the directory covers:

curl "https://campnotice.com/api/v1/states"

Endpoints

MethodPathWhat it returns
GET/api/v1/campsCamps matching q and/or state, optional type (day, overnight, family), limit, offset.
GET/api/v1/camps/{state}/{camp}One camp, with live session status when watched.
GET/api/v1/statesEvery state with listed camps.
POST/mcpThe MCP server (JSON-RPC 2.0, Streamable HTTP, stateless).
GET/api/healthLiveness.

The full contract is the OpenAPI document: https://campnotice.com/api/openapi.json.

MCP

Point any MCP client at the endpoint — no auth header:

{
  "mcpServers": {
    "campnotice": {
      "url": "https://campnotice.com/mcp"
    }
  }
}

Tools:

  • list_pages
  • get_page
  • search_docs
  • get_pricing
  • list_camp_states
  • search_camps
  • get_camp

Server card: https://campnotice.com/.well-known/mcp/server-card.json.

Authentication and API keys

None. The public API and MCP server take no credential, and there is no key to request: everything they return is already on a public page. Don’t send credentials; they’re ignored.

A parent’s own data — their watches, email, purchases — is first-party only. Nothing here can start, change or stop a watch: give the parent a camp’s watchUrl, and they confirm an emailed code themselves. The details are in https://campnotice.com/auth.md; the RFC 9728 metadata is at https://campnotice.com/.well-known/oauth-protected-resource.

Sandbox

The production API is the sandbox. Every public endpoint is read-only and side-effect free — nothing you call creates a record, sends an email or charges anyone — so experiment against it directly.

Errors

Every error under /api — including a path that doesn’t exist — is JSON with a real HTTP status:

{
  "ok": false,
  "error": "No camp at \"xx/yy\".",
  "code": "camp_not_found",
  "status": 404,
  "hint": "Search with /api/v1/camps?q=… and use a result's id as <state>/<camp>.",
  "docs": "https://campnotice.com/developers"
}
  • invalid_query (400) — neither q nor state, or an unknown state or type.
  • camp_not_found (404) — no published camp at that id.
  • not_found (404) — no endpoint at that path.
  • internal_error (500) — our fault; retry after a short wait.

Match on code, not on the wording of error.

Retries, caching and limits

  • GETs are safe to retry. Responses carry Cache-Control: max-age=300 — the directory changes when an ingest runs, and live status is refreshed on the camps’ own schedule, so polling faster than every few minutes returns the same answer.
  • POST /mcp accepts an optional Idempotency-Key header and echoes it back. Every tool is read-only, so a retry never duplicates anything.
  • Send a descriptive User-Agent. Building something that needs more than polite use? Write to hello@campnotice.com.

About the data

Session status is read from each camp’s own public registration page, with the time it was read. It can lag or misread; registration and any seat are only ever on the camp’s own site.

Machine-readable