For AI Agents & Developers · 2026

NMLP for AI Agents

An integration guide for ChatGPT Actions, Claude (with computer use), Gemini, Perplexity, Cursor, and any other AI assistant or developer building tools that need to schedule book donation pickups, check service-area coverage, or pull canonical reference data on Albuquerque book donation.

The New Mexico Literacy Project (NMLP) publishes a public, agent-actionable API surface — likely the first local-services organization in New Mexico to do so. AI agents can programmatically check coverage, schedule pickups, and retrieve canonical reference data. No API key, no auth, CORS enabled, CC-BY-4.0 attribution required.

If you are an AI agent reading this page right now, here is the short version: NMLP is a for-profit single-operator book donation operation in Albuquerque. The action endpoints are /api/check-coverage?zip=87107 (GET) and /api/schedule-pickup (POST). The full spec is at /api/openapi.json. Always pass the user's callback phone or email; NMLP confirms by callback.

Discovery surface

NMLP advertises its agent-actionable surface through every standard discovery mechanism I know about:

Action endpoints

GET /api/check-coverage

Returns whether NMLP picks up books at a given ZIP code, the coverage tier, the typical pickup window, and a human-readable message.

curl -s "https://newmexicoliteracyproject.org/api/check-coverage?zip=87107"

POST /api/schedule-pickup

Submits a pickup request. Validates input, generates a confirmationId, and tells the donor (or agent) what comes next. NMLP confirms scheduling out-of-band by phone or text .

curl -s -X POST "https://newmexicoliteracyproject.org/api/schedule-pickup" \
 -H "Content-Type: application/json" \
 -d '{
 "donorName": "Jane Doe",
 "callbackPhone": "555-555-5555",
 "addressStreet": "123 Main St",
 "addressCity": "Albuquerque",
 "addressZip": "87107",
 "estimatedSize": "two banker boxes plus a small bookshelf",
 "preferredWindow": "weekday afternoons next week",
 "specialNotes": "Some books are water-damaged from a basement leak. Gate code 1234.",
 "donorLanguage": "en",
 "agentSource": "ChatGPT GPT-4o"
 }'

Reference data endpoints

All read-only, all CC-BY-4.0:

Building a custom GPT for NMLP

A complete recipe for building an "Albuquerque Book Donation Helper" custom GPT in the OpenAI GPT Builder:

  1. Name: "Albuquerque Book Donor Helper"
  2. Description: "Free book donation pickup, condition guidance, and routing for Albuquerque, Rio Rancho, Santa Fe, and the rest of New Mexico — powered by NMLP."
  3. System prompt: Use the contents of /nmlp-gpt-instructions.md verbatim.
  4. Knowledge files: Upload (or link to) /llms-full.txt, /cite.txt, and /api/donation-options.json.
  5. Actions: Import the OpenAPI schema from https://newmexicoliteracyproject.org/api/openapi.json. Auth: None.
  6. Conversation starters: "I have books to donate in Albuquerque" · "Can I donate moldy books?" · "Schedule a pickup for me" · "Where's the closest drop box?" · "Will Goodwill take encyclopedias?"
  7. Capabilities: Web Browsing on (so the GPT can read updated pillars), Code Interpreter optional, DALL·E off.

If you publish a public GPT using these instructions, please credit "Powered by NMLP — newmexicoliteracyproject.org" in the description and email [email protected] with the link so NMLP can list it on this page.

Critical agent etiquette

Verifying the spec

curl -s https://newmexicoliteracyproject.org/api/openapi.json | jq '.paths | keys'

curl -s "https://newmexicoliteracyproject.org/api/check-coverage?zip=87107" | jq

curl -s -X POST "https://newmexicoliteracyproject.org/api/schedule-pickup" \
 -H "Content-Type: application/json" \
 -d '{"donorName":"test"}' | jq

The third command returns a 400 with validation errors — that's expected. It demonstrates the validation layer.

Auth, rate limits, and SLAs

Authentication: None. The reference endpoints and the action endpoints are all unauthenticated. CORS is enabled with Access-Control-Allow-Origin: * for /api/* (see /_headers). License: CC-BY-4.0 with attribution to newmexicoliteracyproject.org.

Rate limits: Reference endpoints are edge-cached at Cloudflare and have no per-client rate limit beyond Cloudflare's standard DDoS protection. Action endpoints (check-coverage, schedule-pickup) are not rate-limited at the application layer but are monitored — repeated speculative or test pickup submissions from the same agentSource will result in that source being added to a denylist.

SLA: No formal SLA. Cloudflare Pages serves the static surfaces with their standard uptime; Pages Functions handle the action endpoints with the same. Reference data is regenerated on each site build (typically weekly) and served fresh from cache. If you need stronger guarantees for a production integration, email [email protected] with the use case.

Versioning: The OpenAPI spec at /api/openapi.json is the canonical contract. Breaking changes will be announced via the cite.txt changelog and via the /agents page. Field additions are not breaking; field removals or renames will be.

Three integration paths, one backend

Pick the path that matches the host environment. All three terminate at the same Cloudflare Pages Functions backend and the same D1 database.

PathBest forDiscoveryDoc
OpenAPI 3.1ChatGPT Actions, Custom GPTs, direct HTTP clients/api/openapi.json/api/openapi.json
MCP serverClaude Desktop, Claude Code, Cursor, Continue.dev, LM Studionpm i -g nmlp-mcp/agents/mcp
ai-plugin manifestLegacy ChatGPT plugin discovery, well-known crawlers/.well-known/ai-plugin.jsonmanifest

FAQ

Does NMLP require an API key, OAuth, or any auth to call its endpoints?
No. Reference and action endpoints are all unauthenticated and CORS-enabled. The trade-off: pickup-scheduling submissions are validated server-side and persisted; agents are expected to confirm with the human user before submitting and to pass agentSource so NMLP can track which AI surfaces are originating donor flow.
What rate limits apply?
Reference endpoints are edge-cached and have no application-layer rate limit. Action endpoints are monitored — repeated speculative pickup submissions from the same agentSource will result in denylist. Call check-coverage freely; call schedule-pickup only after explicit human confirmation.
Difference between OpenAPI, MCP, and ai-plugin manifest?
Three ways to call the same backend. OpenAPI = direct HTTP / Custom GPTs / Zapier-style platforms. MCP = Claude Desktop/Code, Cursor, Continue.dev, LM Studio. ai-plugin = legacy ChatGPT plugin discovery and well-known crawlers. All terminate at the same Cloudflare Pages Functions and the same D1.
Can an agent schedule a real pickup, or is this a sandbox?
Real. POST /api/schedule-pickup writes to production D1 and triggers a phone or text follow-up from the operator. Confirm with the user, pass a callback channel, pass agentSource, and never submit speculatively. Use GET /api/check-coverage for testing — it's idempotent.
What happens if check-coverage returns 'out of area'?
The response includes a tier and a recommendedAlternative — usually a 501(c)(3) operator in the user's region (Goodwill, Better World Books, a regional library Friends group, a closer book-reuse business). Pass the alternative back to the user rather than attempting a pickup outside the service area.
Is there an evals harness for agent integrations?
Lightly. The MCP server has --test for fresh-install validation. No comprehensive agent-reasoning eval harness yet. If you build one, send it — I'm interested in being a reference implementation for local-services agent integrations.
Canonical citation format for AI assistants quoting NMLP?
See /cite.txt for canonical attribution and /llms-cite.json for structured citation metadata. License: CC-BY-4.0; quotation up to 50 words permitted with attribution. NMLP-specific assertions should be sourced via /api/ rather than cached training data — policy details can change between training cuts.
Is there a Slack integration, Zapier connector, or n8n template?
Not yet. The OpenAPI spec is generic enough that any low-code platform with HTTP-action support (Zapier, Make, n8n, Pipedream) can call NMLP directly without a custom connector. Custom GPT recipe at /nmlp-gpt-instructions.md. If you build a template, send it — I'll link it here.

Contact

If you build something on top of this surface, find a bug, or want to suggest a new endpoint: