API Reference

Base URL: https://api.libraryapi.dev·Current version: v1·Data: IMLS PLS FY 2023

Authentication

Pass your API key via the X-API-Key header on every request. Alternatively, use Authorization: Bearer <key>.

curl "https://api.libraryapi.dev/v1/outlets?address=14901+Dale+Evans+Pkwy,+Apple+Valley,+CA" \
  -H "X-API-Key: sk_live_your_api_key"

Rate Limits

Two limits apply on every request:

PlanPer minutePer month
Free10 req/min500 req
Starter60 req/min10,000 req
Pro120 req/min50,000 req
Growth300 req/min200,000 req

Monthly quotas reset on the 1st of each calendar month. Exceeding the per-minute limit returns 429. Exceeding the monthly quota returns 402.

Endpoints

GET/v1/outlets

Find the nearest public library outlets to an address or coordinate. The killer endpoint — point in, ranked outlets out.

Query Parameters
addressstringoptionalStreet address — geocoded to lat/lng (US Census geocoder).
latnumberoptionalLatitude (use with lng)
lngnumberoptionalLongitude (use with lat)
radius_milesnumberoptionalSearch radius in miles. Min 0.1, max 50, default 10.
limitintegeroptionalMax results. Min 1, max 100, default 10.
Example Response
{
  "data": [
    {
      "outletId": "CA0109-004",
      "fscsId": "CA0109",
      "name": "Newton T. Bass Apple Valley Branch Library",
      "outletType": "branch",
      "parentSystem": { "fscsId": "CA0109", "name": "San Bernardino County Library" },
      "address": { "street": "14901 Dale Evans Parkway", "city": "Apple Valley", "state": "CA", "zip": "92307", "zip4": "3061" },
      "phone": "(760) 247-2022",
      "geo": { "lat": 34.524928, "lng": -117.21587, "geocodeQuality": "high" },
      "service": { "annualHours": 1520, "weeksOpen": 52, "squareFootage": 19412 },
      "status": "no change",
      "dataYear": "FY 2023",
      "distanceMiles": 0.14
    }
  ],
  "meta": { "requestId": "req_d00aa00a7fee", "creditsUsed": 1, "creditsRemaining": 499 },
  "source": { "imlsYear": "FY 2023", "updatedAt": "2025-08-15", "freshnessDays": 273 }
}
GET/v1/outlets/{outlet_id}

Get a single outlet by its compound ID (format: {FSCSKEY}-{seq}, e.g. CA0109-004).

GET/v1/libraries/{fscs_id}

Get the full profile for a library system — service area, collections, usage, programs, technology, finance, staffing.

Example Response
{
  "data": {
    "fscsId": "CA0109",
    "name": "San Bernardino County Library",
    "state": "CA",
    "county": "San Bernardino",
    "address": { "street": "777 East Rialto Ave", "city": "San Bernardino", "state": "CA", "zip": "92415" },
    "phone": "(909) 387-2220",
    "legalBasis": "County/Parish",
    "serviceArea": { "population": 1263869, "centralLibraries": 0, "branches": 32, "bookmobiles": 0 },
    "collections": {
      "printVolumes": 1104531, "ebooks": 414337,
      "audioPhysical": 24111, "audioDownloadable": 33015,
      "videoPhysical": 74792, "videoDownloadable": 0
    },
    "usage": {
      "annualVisits": 1476017, "registeredBorrowers": 223845,
      "totalCirculation": 4512254,
      "programs": { "total": 5273, "kids": 4380, "youngAdult": 234, "attendanceTotal": 166411 },
      "technology": { "publicComputers": 793, "computerSessions": 318909 }
    },
    "finance": {
      "totalRevenue": 28327522,
      "totalExpenditures": 29130766,
      "perCapitaExpenditure": 23.05,
      "staffFte": { "mlsLibrarians": 5.0, "librarians": 39.0, "other": 82.0, "total": 121.0 }
    },
    "outletsCount": 32,
    "dataYear": "FY 2023"
  },
  "meta": { ... },
  "source": { ... }
}
GET/v1/libraries/search

Search library systems by name, state, and/or city. Provide at least one parameter.

Query Parameters
namestringoptionalLibrary system name (full-text search)
statestringoptionalTwo-letter state abbreviation
citystringoptionalCity name (substring match, case-insensitive)
limitintegeroptionalResults per page. Max 100, default 20.
offsetintegeroptionalPagination offset (default 0).
GET/v1/states/{code}/summary

State-level rollup statistics: total systems, total outlets, aggregate visits, total expenditures, per-capita spend.

Example Response
{
  "data": {
    "state": "CA",
    "dataYear": "FY 2023",
    "totals": {
      "librarySystems": 186,
      "outlets": 1192,
      "serviceAreaPopulation": 1109153789,
      "annualVisits": 1822657666,
      "totalCirculation": 5733910183,
      "totalExpenditures": 57571616061
    },
    "averages": {
      "perCapitaExpenditure": 57.66,
      "outletsPerSystem": 6.41
    }
  },
  "meta": { ... },
  "source": { "imlsYear": "FY 2023", "updatedAt": "2025-08-15" }
}
GET/v1/health

Service health check. Returns DB connectivity and data freshness. Does NOT consume a credit and does NOT require an API key.

Response Envelope

Every response is wrapped in a consistent envelope. Field names are camelCase.

{
  "data": { ... },
  "meta": {
    "requestId": "req_d00aa00a7fee",
    "creditsUsed": 1,
    "creditsRemaining": 499
  },
  "source": {
    "imlsYear": "FY 2023",
    "updatedAt": "2025-08-15",
    "freshnessDays": 273
  }
}

Error Codes

All errors return a consistent JSON body:

{
  "detail": {
    "code": "NO_LIBRARIES_NEARBY",
    "message": "No outlets within 10 miles."
  }
}
HTTPCodeDescription
400INVALID_PARAMSRequired parameters are missing or conflicting.
400INVALID_ADDRESSThe provided address could not be geocoded. Try including city and state.
401INVALID_API_KEYThe API key is missing, invalid, or deactivated.
402QUOTA_EXCEEDEDYour monthly request quota has been reached. Upgrade your plan or wait for the monthly reset.
404LIBRARY_NOT_FOUNDNo library system or outlet found for the given ID.
404NO_LIBRARIES_NEARBYNo outlets within the requested radius. Try a larger radius_miles.
429RATE_LIMITEDToo many requests per minute. Slow down and retry after a moment.
500INTERNAL_ERRORAn unexpected server error occurred. If this persists, contact support.
📊

Data source

All records trace back to the IMLS Public Libraries Survey — an annual federal census of every public library system and outlet in the United States. Public domain, commercially usable, no license required.

Current dataset: FY 2023, released August 2025. Coverage: 9,252 library systems and 17,586 outlets across all 50 states, DC, and outlying territories. Response rate: 96-97%.

We add geocoding (US Census + Mapbox), PostGIS spatial indexing, a clean REST API, and an SDK. The federal survey is reloaded once per year.

🤖

SDKs & AI integration

A machine-readable reference covering all endpoints, schemas, and examples lives at:

libraryapi.dev/llms.txt

Typed SDKs are in active development.

Python SDK
v0.2.0

Typed client for Python. Single import, async support, retries built in.

Node SDK
Coming soon

Typed client for Node.js and TypeScript. Works in LangChain tool definitions and Vercel AI SDK.

MCP Server
Planned

Use libraryapi inside Claude, Cursor, and any MCP-compatible assistant. Ask about libraries by address or name — no code required.