CalendarConnect/Developer API
v1App

CalendarConnect API

Access academic calendar data for 1,000+ US universities. Get event dates for class schedules, breaks, finals, registration deadlines, and more through a simple REST API.

Getting Started

The CalendarConnect API provides read-only access to academic calendar events across 1,000+ US universities. The API is free for development and personal use.

Quick Start

Make your first API call to list universities:

bash
curl "https://calendarconnect.app/api/v1/universities?limit=5"

All API endpoints are available at /api/v1/. Responses return JSON with a consistent format including data, optional pagination, and meta fields.

json
{
  "data": [ ... ],
  "pagination": {
    "total": 532,
    "page": 1,
    "limit": 20,
    "hasMore": true
  },
  "meta": {
    "requestId": "550e8400-e29b-41d4-a716-446655440000",
    "timestamp": "2026-02-27T12:00:00.000Z"
  }
}

Authentication

API keys provide higher rate limits and are recommended for production use. You can make unauthenticated requests for testing, but they are subject to lower rate limits.

Pass your API key via header (recommended):
bash
curl -H "X-API-Key: your_api_key_here" \
  "https://calendarconnect.app/api/v1/universities"
Or via query parameter:
bash
curl "https://calendarconnect.app/api/v1/universities?api_key=your_api_key_here"
Getting an API key

Contact us to request an API key for production use. Include your use case and expected request volume.

Rate Limits

Rate limits are applied per minute using a sliding window.

TierLimitIdentifier
Authenticated100 req/minPer API key
Unauthenticated20 req/minPer IP address

Rate limit information is included in every response via headers:

HeaderDescription
X-RateLimit-LimitMax requests per window
X-RateLimit-RemainingRemaining requests in current window
X-RateLimit-ResetSeconds until rate limit window resets

When rate limited, you will receive a 429 response:

json
{
  "error": {
    "code": "RATE_LIMIT_EXCEEDED",
    "message": "Rate limit exceeded. Try again in 45 seconds."
  },
  "meta": { "requestId": "...", "timestamp": "..." }
}

API Reference

All endpoints return JSON and support CORS for browser-based requests. The base URL for all API endpoints is /api/v1.

List Universities

GET/api/v1/universities

Returns a paginated list of universities. Supports search and state filtering.

ParameterTypeRequiredDescription
qstringOptionalSearch query (matches name, aliases, domain)
statestringOptionalState abbreviation (e.g., "CA", "NY")
pageintegerOptionalPage number (default: 1)
limitintegerOptionalResults per page, max 100 (default: 20)
offsetintegerOptionalOffset from start (overrides page)
bash
curl "https://calendarconnect.app/api/v1/universities?q=mit&limit=2"
Response
json
{
  "data": [
    {
      "id": "abc-123",
      "name": "Massachusetts Institute of Technology",
      "aliases": ["MIT"],
      "domain": "mit.edu",
      "location": "Cambridge, MA",
      "primaryColor": "#8b0000",
      "secondaryColor": "#54585a",
      "lastIngestedAt": "2026-02-20T10:00:00.000Z",
      "createdAt": "2026-01-15T08:30:00.000Z"
    }
  ],
  "pagination": { "total": 1, "page": 1, "limit": 2, "hasMore": false },
  "meta": { "requestId": "...", "timestamp": "..." }
}

Get University

GET/api/v1/universities/:id

Returns detailed information about a specific university including event count and last ingestion date.

bash
curl "https://calendarconnect.app/api/v1/universities/abc-123"
Response
json
{
  "data": {
    "id": "abc-123",
    "name": "Massachusetts Institute of Technology",
    "aliases": ["MIT"],
    "domain": "mit.edu",
    "location": "Cambridge, MA",
    "primaryColor": "#8b0000",
    "secondaryColor": "#54585a",
    "calendarSourceUrls": [
      "https://registrar.mit.edu/calendar"
    ],
    "extractionStrategy": "general",
    "lastIngestedAt": "2026-02-20T10:00:00.000Z",
    "eventCount": 24,
    "lastIngestionDate": "2026-02-20T10:00:00.000Z",
    "createdAt": "2026-01-15T08:30:00.000Z",
    "updatedAt": "2026-02-20T10:05:00.000Z"
  },
  "meta": { "requestId": "...", "timestamp": "..." }
}
Error: Not Found

Returns 404 if the university ID does not exist.

json
{
  "error": {
    "code": "NOT_FOUND",
    "message": "University with id 'invalid-id' not found"
  },
  "meta": { "requestId": "...", "timestamp": "..." }
}

University Events

GET/api/v1/universities/:id/events

Returns events for a specific university with filtering and pagination.

ParameterTypeRequiredDescription
fromISO dateOptionalStart of date range (e.g., 2026-01-01)
toISO dateOptionalEnd of date range (e.g., 2026-06-30)
categorystringOptionalEvent category filter (comma-separated)
termstringOptionalAcademic term filter (e.g., "Fall", "Spring 2026")
pageintegerOptionalPage number (default: 1)
limitintegerOptionalResults per page, max 100 (default: 20)
bash
curl "https://calendarconnect.app/api/v1/universities/abc-123/events?from=2026-01-01&to=2026-06-30&category=spring_break,final_exams"
Response
json
{
  "data": [
    {
      "id": "evt-456",
      "title": "Spring Break",
      "category": "spring_break",
      "startDate": "2026-03-14T00:00:00.000Z",
      "endDate": "2026-03-22T00:00:00.000Z",
      "allDay": true,
      "term": "Spring 2026",
      "academicYear": "2025-2026",
      "confidence": 0.95,
      "sourceUrl": "https://registrar.mit.edu/calendar"
    }
  ],
  "pagination": { "total": 3, "page": 1, "limit": 20, "hasMore": false },
  "meta": { "requestId": "...", "timestamp": "..." }
}

Search Events

GET/api/v1/events

Search events across multiple universities with full filtering support.

ParameterTypeRequiredDescription
universityIdsstringOptionalComma-separated university IDs
qstringOptionalText search on event titles
fromISO dateOptionalStart of date range
toISO dateOptionalEnd of date range
categorystringOptionalEvent category filter (comma-separated)
termstringOptionalAcademic term filter
pageintegerOptionalPage number (default: 1)
limitintegerOptionalResults per page, max 100 (default: 20)
bash
curl "https://calendarconnect.app/api/v1/events?q=finals&from=2026-05-01&to=2026-06-01&limit=5"
Response
json
{
  "data": [
    {
      "id": "evt-789",
      "title": "Final Examinations Begin",
      "category": "final_exams",
      "startDate": "2026-05-11T00:00:00.000Z",
      "endDate": "2026-05-22T00:00:00.000Z",
      "allDay": true,
      "term": "Spring 2026",
      "academicYear": "2025-2026",
      "confidence": 0.92,
      "sourceUrl": "https://registrar.stanford.edu/academic-calendar",
      "university": {
        "id": "def-456",
        "name": "Stanford University",
        "primaryColor": "#8c1515",
        "secondaryColor": "#2e2d29"
      }
    }
  ],
  "pagination": { "total": 48, "page": 1, "limit": 5, "hasMore": true },
  "meta": { "requestId": "...", "timestamp": "..." }
}

Upcoming Events

GET/api/v1/events/upcoming

Returns events for the next 30 days, grouped by date. Useful for building dashboards and notification systems.

ParameterTypeRequiredDescription
universityIdsstringOptionalComma-separated university IDs to filter
bash
curl "https://calendarconnect.app/api/v1/events/upcoming"
Response
json
{
  "data": [
    {
      "date": "2026-03-02",
      "count": 12,
      "events": [
        {
          "id": "evt-100",
          "title": "Spring Registration Opens",
          "category": "registration",
          "startDate": "2026-03-02T00:00:00.000Z",
          "endDate": null,
          "allDay": true,
          "term": "Spring 2026",
          "academicYear": "2025-2026",
          "university": {
            "id": "ghi-789",
            "name": "University of Michigan",
            "primaryColor": "#00274c",
            "secondaryColor": "#ffcb05"
          }
        }
      ]
    }
  ],
  "meta": { "requestId": "...", "timestamp": "..." }
}

Data Model

Event Categories

Events are classified into 20 categories:

start_of_classesStart of Classes
end_of_classesEnd of Classes
add_drop_deadlineAdd/Drop Deadline
withdrawal_deadlineWithdrawal Deadline
reading_periodReading Period
study_periodStudy Period
final_examsFinal Exams
commencementCommencement
convocationConvocation
orientationOrientation
move_inMove-In
fall_breakFall Break
thanksgiving_breakThanksgiving Break
winter_breakWinter Break
spring_breakSpring Break
summer_breakSummer Break
holidayHoliday
registrationRegistration
advisingAdvising
specialSpecial

University Fields

FieldTypeDescription
idstringUnique identifier (UUID)
namestringFull university name
aliasesstring[]Alternative names (e.g., ["MIT"])
domainstringUniversity website domain
locationstring"City, State" format
primaryColorstringHex color code
secondaryColorstringHex color code
lastIngestedAtISO datetime | nullWhen calendar data was last scraped
createdAtISO datetimeWhen the record was created

Event Fields

FieldTypeDescription
idstringUnique identifier (UUID)
titlestringEvent title
categorystringEvent category (see list above)
startDateISO datetimeEvent start date
endDateISO datetime | nullEvent end date (null for single-day events)
allDaybooleanWhether this is an all-day event
termstring | nullAcademic term (e.g., "Fall 2025")
academicYearstring | nullAcademic year (e.g., "2025-2026")
confidencenumberExtraction confidence score (0-1)
sourceUrlstring | nullURL of the source calendar page

Date Formats

All dates in responses are ISO 8601 format: 2026-03-14T00:00:00.000Z. When providing dates as query parameters, use YYYY-MM-DD format (e.g., 2026-01-15).

Code Examples

cURL

bash
# List universities in California
curl -H "X-API-Key: your_key" \
  "https://calendarconnect.app/api/v1/universities?state=CA&limit=10"

# Get spring break events for a university
curl -H "X-API-Key: your_key" \
  "https://calendarconnect.app/api/v1/universities/UNIVERSITY_ID/events?category=spring_break&from=2026-01-01&to=2026-06-30"

# Search for finals across all universities
curl -H "X-API-Key: your_key" \
  "https://calendarconnect.app/api/v1/events?q=final+exam&from=2026-05-01&to=2026-06-01"

# Get upcoming events for the next 30 days
curl -H "X-API-Key: your_key" \
  "https://calendarconnect.app/api/v1/events/upcoming"

JavaScript (fetch)

javascript
const API_KEY = "your_api_key";
const BASE_URL = "https://calendarconnect.app/api/v1";

async function getUniversities(query) {
  const params = new URLSearchParams({ q: query, limit: "10" });
  const res = await fetch(`${BASE_URL}/universities?${params}`, {
    headers: { "X-API-Key": API_KEY },
  });
  const { data, pagination } = await res.json();
  return { universities: data, pagination };
}

async function getEvents(universityId, options = {}) {
  const params = new URLSearchParams();
  if (options.from) params.set("from", options.from);
  if (options.to) params.set("to", options.to);
  if (options.category) params.set("category", options.category);

  const res = await fetch(
    `${BASE_URL}/universities/${universityId}/events?${params}`,
    { headers: { "X-API-Key": API_KEY } }
  );
  const { data } = await res.json();
  return data;
}

// Usage
const { universities } = await getUniversities("Stanford");
const events = await getEvents(universities[0].id, {
  from: "2026-01-01",
  to: "2026-06-30",
  category: "spring_break,final_exams",
});
console.log(events);

Python (requests)

python
import requests

API_KEY = "your_api_key"
BASE_URL = "https://calendarconnect.app/api/v1"

headers = {"X-API-Key": API_KEY}

# List universities
response = requests.get(
    f"{BASE_URL}/universities",
    headers=headers,
    params={"q": "Stanford", "limit": 5},
)
data = response.json()
universities = data["data"]
print(f"Found {data['pagination']['total']} universities")

# Get events for a university
uni_id = universities[0]["id"]
response = requests.get(
    f"{BASE_URL}/universities/{uni_id}/events",
    headers=headers,
    params={
        "from": "2026-01-01",
        "to": "2026-06-30",
        "category": "spring_break,final_exams",
    },
)
events = response.json()["data"]
for event in events:
    print(f"{event['title']} - {event['startDate'][:10]}")

# Search across all universities
response = requests.get(
    f"{BASE_URL}/events",
    headers=headers,
    params={"q": "commencement", "from": "2026-05-01"},
)
for event in response.json()["data"]:
    print(f"{event['university']['name']}: {event['title']}")

Error Codes

StatusCodeDescription
200SuccessRequest completed successfully
400BAD_REQUESTInvalid parameters (bad date, invalid category)
401UNAUTHORIZEDInvalid API key
404NOT_FOUNDResource not found (university ID does not exist)
429RATE_LIMIT_EXCEEDEDToo many requests, slow down
500INTERNAL_ERRORServer error, please retry

CalendarConnect API v1. Have questions or need a higher rate limit? Get in touch.