API
No key, no signup, no quota. If you would rather not call an HTTP endpoint at all, the same logic is a dependency-free TypeScript module in the repository.
Generate links
GET https://makecalendarlink.com/api/links
?title=Q4 product webinar
&start=2026-09-10T14:00
&end=2026-09-10T15:00
&timeZone=Europe/Brussels
&location=https://meet.example.com/abc Response:
{
"key": "1x9k2mfp0a",
"encoded": "eyJ0IjoiUTQgcHJvZHVjdCB3ZWJpbmFyIiwic...",
"links": {
"google": "https://calendar.google.com/calendar/render?...",
"outlook": "https://outlook.live.com/calendar/0/deeplink/compose?...",
"office365": "https://outlook.office.com/calendar/0/deeplink/compose?...",
"yahoo": "https://calendar.yahoo.com/?...",
"ics": "https://makecalendarlink.com/api/ics?e=eyJ0IjoiUTQg..."
},
"icsUrl": "https://makecalendarlink.com/api/ics?e=eyJ0IjoiUTQg...",
"shareUrl": "https://makecalendarlink.com/e/eyJ0IjoiUTQg..."
} Parameters
| Name | Required | Notes |
|---|---|---|
title | yes | Event title. |
start | yes | YYYY-MM-DDTHH:mm or YYYY-MM-DD. Wall-clock time, not UTC. |
end | no | Defaults to start. |
timeZone | no | IANA zone. Defaults to UTC, so set it. |
allDay | no | true for an all-day event. |
location | no | Address or meeting URL. |
description | no | Event description. |
url | no | Appended to the description. |
rrule | no | Recurrence without the RRULE: prefix. |
track | no | true returns tracked links and a stats URL. |
ics | no | Include the raw .ics text in the response. |
e | no | An existing encoded payload, instead of the fields above. |
POST
Same fields as a JSON body, which avoids encoding headaches with long descriptions:
curl -X POST https://makecalendarlink.com/api/links \
-H 'content-type: application/json' \
-d '{
"title": "Q4 product webinar",
"start": "2026-09-10T14:00",
"end": "2026-09-10T15:00",
"timeZone": "Europe/Brussels"
}' Download an .ics file
GET https://makecalendarlink.com/api/ics?e=<encoded>
Returns text/calendar with a Content-Disposition attachment
header, so it opens natively on iOS, macOS and Windows. The payload fully determines the
file, so it is cached at the edge indefinitely.
Tracked redirect
GET https://makecalendarlink.com/go/:provider?e=<encoded>&k=<key>
Counts the click and forwards to the calendar with Referrer-Policy: no-referrer,
so the page the link sat on is not leaked to Google or Microsoft. View the numbers at
/stats/<key>.
Use the module instead
For a TypeScript or JavaScript project, skip the network entirely. The core has no dependencies and runs in the browser, in Node and on workers:
import { buildLinks, buildIcs } from './lib';
const links = buildLinks({
title: 'Q4 product webinar',
start: '2026-09-10T14:00',
end: '2026-09-10T15:00',
timeZone: 'Europe/Brussels',
});
const ics = buildIcs({ /* same shape */ }); Limits and fair use
There is no rate limit configured, because the endpoints do no work worth protecting: no database read, no third-party call. If you are about to send serious volume, copy the module into your own project or self-host, which is faster for you anyway.
Stability
These endpoints are versionless on purpose and the response shape is additive: new fields may appear, existing ones will not change meaning. If a calendar provider changes their URL format, the fix lands here rather than in your code, which is the main argument for calling the API over hard-coding formats yourself.