API Reference
The BlendedCal REST API lets you build integrations, automate workflows, and manage your calendars programmatically.
Interactive Documentation:
For a full interactive API explorer with live testing, visit:
Open Swagger UI →Authentication
The BlendedCal API supports two authentication methods:
1. Bearer Token (Recommended for Apps & Scripts)
Bearer tokens are API keys you generate from your profile page. They're perfect for mobile apps, scripts, and third-party integrations.
How to create an API key:
- Log into BlendedCal
- Go to Profile → API Keys
- Click Generate API Key
- Give it a name (e.g., "iOS App", "Python Script")
- Select permissions (read-only or read/write for each resource type)
- Optionally set an expiration date
- Click Create and copy the token
Using the token:
curl https://blendedcal.com/api/sources \ -H "Authorization: Bearer YOUR_API_KEY"
Security: Treat API keys like passwords. Don't commit them to version control or share them publicly. If a key is compromised, delete it from your profile page immediately.
2. Session Cookie (For Swagger UI and Web Usage)
When you're logged into the BlendedCal web app, your session cookie automatically authenticates API requests. This is how the Swagger UI works.
Token Permissions
When creating an API key, you can grant specific permissions:
| Permission | What It Allows |
|---|---|
sources:read | List and view calendar sources |
sources:write | Create, update, delete, and sync sources |
calendars:read | List and view blended calendars |
calendars:write | Create, update, and delete blended calendars |
events:read | List and view events |
events:write | Create, update, and delete events |
tags:read | List all tags |
profile:read | View user profile |
profile:write | Update user profile (name, slug) |
Tip: Use read-only permissions for apps that only need to display data. Reserve write permissions for scripts and integrations that need to modify data.
API Endpoints
All endpoints are relative to https://blendedcal.com/api (or your deployment URL).
Sources
| Method | Endpoint | Description |
|---|---|---|
GET | /sources | List all calendar sources |
POST | /sources | Create a new calendar source |
GET | /sources/:id | Get a specific source |
PATCH | /sources/:id | Update a source |
DELETE | /sources/:id | Delete a source |
POST | /sources/:id/sync | Manually trigger sync for a source |
Calendars
| Method | Endpoint | Description |
|---|---|---|
GET | /calendars | List blended calendars with limit/offset pagination |
POST | /calendars | Create a new calendar |
GET | /calendars/:id | Get a specific calendar |
PATCH | /calendars/:id | Update a calendar |
DELETE | /calendars/:id | Delete a calendar |
GET | /calendars/:id/events | Get filtered events with pagination metadata |
Events
| Method | Endpoint | Description |
|---|---|---|
GET | /events | List all events with optional filtering |
POST | /events | Create a new event (direct/virtual) |
GET | /events/:id | Get a single event |
PATCH | /events/:id | Update an event |
DELETE | /events/:id | Delete an event |
Other Endpoints
| Method | Endpoint | Description |
|---|---|---|
GET | /tags | List all unique tags |
GET | /me | Get current user profile |
PATCH | /me | Update profile (name, slug) |
Request and Response Format
Request Body
All POST and PATCH requests should include a JSON body with Content-Type: application/json.
Success Response
{
"data": { ... },
"total": 42 // Only for list endpoints
}Error Response
{
"error": "Error message",
"details": "Additional error details (optional)"
}Error Codes
| Code | Meaning |
|---|---|
400 | Bad Request (validation error, invalid input) |
401 | Unauthorized (missing or invalid token) |
404 | Not Found (resource doesn't exist) |
500 | Internal Server Error (sync failures, etc.) |
Example Requests
List All Sources
curl https://blendedcal.com/api/sources \ -H "Authorization: Bearer YOUR_API_KEY"
Create a Source
curl -X POST https://blendedcal.com/api/sources \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Carter Soccer",
"url": "https://teamsnap.com/calendar/ics/...",
"tags": ["carter", "sports", "soccer"],
"filterText": "game",
"isActive": true
}'Get Filtered Events
curl "https://blendedcal.com/api/events?startAfter=2024-03-01T00:00:00Z&limit=20&search=game" \ -H "Authorization: Bearer YOUR_API_KEY"
Create a Blended Calendar
curl -X POST https://blendedcal.com/api/calendars \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Carter Schedule",
"slug": "carter",
"description": "All of Carter'''s events",
"meta": {
"anyTags": ["carter"],
"filterText": null
}
}'Rate Limiting
Rate limits are enforced per user for authenticated API requests and per IP for unauthenticated requests. Most authenticated API requests allow 100 requests per minute. Higher-impact actions have tighter limits: creating sources or calendars allows 10 requests per minute, fetching events for a calendar allows 30 requests per minute, and manual source syncs allow 5 requests per minute for each source.
Public shared calendar feeds have separate per-IP limits: 100 ICS requests per hour and 300 JSON requests per hour. When a limit is exceeded, BlendedCal returns a 429 response withRetry-After, X-RateLimit-Limit, and X-RateLimit-Remainingheaders so integrations can back off gracefully.
Want More?
For full interactive documentation with live testing:
Open Swagger UI →Or connect AI assistants via MCP:
Learn about MCP Integration →