Calendar API
Save events to Google Calendar, Outlook / Microsoft 365, Apple and Yahoo calendars. Standards-compliant .ics files and email invites (with updates and cancellations), one-click "add to calendar" links, personal subscribe feeds, and automatic sync to users' own Google and Outlook calendars.
Overview
Integrate the Calendar API into your applications with ease. This API offers high performance, reliability, and comprehensive documentation to get you started quickly.
Documentation
Put your events in your users' own calendars. One call gives you "add to Google / Outlook / Office 365 / Yahoo / Apple" links, a standards-compliant .ics invite for your emails, and, for users who connect their Google or Outlook account, an automatic copy in their calendar that moves when you reschedule and disappears when you cancel.
Base URL
https://devapi.autoplannerx.com/api/v1/calendar
Send your key in the X-API-Key header from your server. Links returned by the API never contain your key, and clicks on them are not billed.
Endpoints
| Method | Path | What it does |
|---|---|---|
| POST | /events | Create or update an event by your own external_id. Returns links, sync results and (with include_ics) the .ics text. |
| GET | /events/{external_id} | The stored event, its links and where it is synced. |
| DELETE | /events/{external_id} | Cancel it: removed from connected calendars; links serve a cancelled event. |
| GET | /events/{external_id}/ics?method=request | .ics file (publish, request for email invites, cancel). |
| GET | /events/{external_id}/links | Just the "add to calendar" links. |
| POST | /links, /ics | One-off links or .ics without storing anything. |
| POST | /connect | Start a Google or Outlook sign-in for one of your users; returns authorize_url. |
| GET / DELETE | /connections, /connections/{id} | List or remove a user's connected calendars. |
| POST | /feeds | A personal subscribe (webcal) feed of the user's events. |
/events
Calling it again with the same external_id updates the event (same UID, higher SEQUENCE), so calendars replace it instead of adding a duplicate. Repeating an identical call changes nothing.
curl -X POST "https://devapi.autoplannerx.com/api/v1/calendar/events" \
-H "X-API-Key: YOUR_API_KEY" -H "Content-Type: application/json" \
-d '{
"external_id": "interview:55",
"title": "Interview: Jane Moyo",
"start": "2026-11-02 09:30",
"end": "2026-11-02 10:15",
"timezone": "Africa/Johannesburg",
"location": "Boardroom 2",
"reminders": [15],
"category": "interviews",
"organizer": {"name": "Acme HR", "email": "hr@acme.example"},
"attendees": [{"name": "Jane Moyo", "email": "jane@example.com"}],
"recipients": [{"ref": "user:7", "email": "lerato@acme.example"}],
"sync_to": ["user:7"],
"include_ics": "request"
}'
All-day events: "all_day": true with dates; end is the last day (inclusive).
The full guide, including connecting Google and Outlook accounts and subscribe feeds, is in docs/CALENDAR_API_V2.md. The original / (download) and /url endpoints of the ICS generator still work.
Calendar Compatibility
- Google Calendar (links, invites, auto-sync)
- Outlook.com and Microsoft 365 (links, invites, auto-sync)
- Outlook desktop and Apple Calendar (.ics, invites, feeds)
- Yahoo Calendar (links)
- Any iCalendar (RFC 5545) application
Code Examples
Pick an endpoint and a language. Replace YOUR_API_KEY with a key from your dashboard.
curl -X POST "https://devapi.autoplannerx.com/api/v1/calendar-ics-generator/events" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"external_id":"meeting:1","title":"Team Meeting","start":"2026-12-20 14:00","end":"2026-12-20 15:30","timezone":"Africa/Johannesburg","location":"Conference Room A","reminders":[15]}'
const response = await fetch('https://devapi.autoplannerx.com/api/v1/calendar-ics-generator/events', {
method: 'POST',
headers: {
'X-API-Key': 'YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
"external_id": "meeting:1",
"title": "Team Meeting",
"start": "2026-12-20 14:00",
"end": "2026-12-20 15:30",
"timezone": "Africa/Johannesburg",
"location": "Conference Room A",
"reminders": [
15
]
})
});
if (!response.ok) {
throw new Error(`Request failed: ${response.status}`);
}
const data = await response.json();
console.log(data);
// Node.js 18+ as an ES module (.mjs). Set DEVAPI_KEY in your environment.
const response = await fetch('https://devapi.autoplannerx.com/api/v1/calendar-ics-generator/events', {
method: 'POST',
headers: {
'X-API-Key': process.env.DEVAPI_KEY,
'Content-Type': 'application/json'
},
body: JSON.stringify({
"external_id": "meeting:1",
"title": "Team Meeting",
"start": "2026-12-20 14:00",
"end": "2026-12-20 15:30",
"timezone": "Africa/Johannesburg",
"location": "Conference Room A",
"reminders": [
15
]
})
});
if (!response.ok) {
throw new Error(`Request failed: ${response.status}`);
}
console.log(await response.json());
<?php
$ch = curl_init('https://devapi.autoplannerx.com/api/v1/calendar-ics-generator/events');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => json_encode([
'external_id' => 'meeting:1',
'title' => 'Team Meeting',
'start' => '2026-12-20 14:00',
'end' => '2026-12-20 15:30',
'timezone' => 'Africa/Johannesburg',
'location' => 'Conference Room A',
'reminders' => [
15,
],
]),
CURLOPT_HTTPHEADER => [
'X-API-Key: YOUR_API_KEY',
'Content-Type: application/json',
],
]);
$response = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status !== 200) {
die('Request failed: ' . $response);
}
$data = json_decode($response, true);
print_r($data);
import requests
response = requests.post(
"https://devapi.autoplannerx.com/api/v1/calendar-ics-generator/events",
headers={"X-API-Key": "YOUR_API_KEY"},
json={
"external_id": "meeting:1",
"title": "Team Meeting",
"start": "2026-12-20 14:00",
"end": "2026-12-20 15:30",
"timezone": "Africa/Johannesburg",
"location": "Conference Room A",
"reminders": [
15,
],
},
)
response.raise_for_status()
print(response.json())
curl -X GET "https://devapi.autoplannerx.com/api/v1/calendar-ics-generator/events/meeting%3A1" \
-H "X-API-Key: YOUR_API_KEY"
const response = await fetch('https://devapi.autoplannerx.com/api/v1/calendar-ics-generator/events/meeting%3A1', {
method: 'GET',
headers: {
'X-API-Key': 'YOUR_API_KEY'
}
});
if (!response.ok) {
throw new Error(`Request failed: ${response.status}`);
}
const data = await response.json();
console.log(data);
// Node.js 18+ as an ES module (.mjs). Set DEVAPI_KEY in your environment.
const response = await fetch('https://devapi.autoplannerx.com/api/v1/calendar-ics-generator/events/meeting%3A1', {
method: 'GET',
headers: {
'X-API-Key': process.env.DEVAPI_KEY
}
});
if (!response.ok) {
throw new Error(`Request failed: ${response.status}`);
}
console.log(await response.json());
<?php
$ch = curl_init('https://devapi.autoplannerx.com/api/v1/calendar-ics-generator/events/meeting%3A1');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'X-API-Key: YOUR_API_KEY',
],
]);
$response = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status !== 200) {
die('Request failed: ' . $response);
}
$data = json_decode($response, true);
print_r($data);
import requests
response = requests.get(
"https://devapi.autoplannerx.com/api/v1/calendar-ics-generator/events/meeting%3A1",
headers={"X-API-Key": "YOUR_API_KEY"},
)
response.raise_for_status()
print(response.json())
curl -X GET "https://devapi.autoplannerx.com/api/v1/calendar-ics-generator/events/meeting%3A1/ics?method=publish" \
-H "X-API-Key: YOUR_API_KEY" \
-o event.ics
const response = await fetch('https://devapi.autoplannerx.com/api/v1/calendar-ics-generator/events/meeting%3A1/ics?method=publish', {
method: 'GET',
headers: {
'X-API-Key': 'YOUR_API_KEY'
}
});
if (!response.ok) {
throw new Error(`Request failed: ${response.status}`);
}
// Save the file in the browser
const link = document.createElement('a');
link.href = URL.createObjectURL(await response.blob());
link.download = 'event.ics';
link.click();
// Node.js 18+ as an ES module (.mjs). Set DEVAPI_KEY in your environment.
import { writeFile } from 'node:fs/promises';
const response = await fetch('https://devapi.autoplannerx.com/api/v1/calendar-ics-generator/events/meeting%3A1/ics?method=publish', {
method: 'GET',
headers: {
'X-API-Key': process.env.DEVAPI_KEY
}
});
if (!response.ok) {
throw new Error(`Request failed: ${response.status}`);
}
await writeFile('event.ics', Buffer.from(await response.arrayBuffer()));
<?php
$ch = curl_init('https://devapi.autoplannerx.com/api/v1/calendar-ics-generator/events/meeting%3A1/ics?method=publish');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'X-API-Key: YOUR_API_KEY',
],
]);
$response = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status !== 200) {
die('Request failed: ' . $response);
}
file_put_contents('event.ics', $response);
import requests
response = requests.get(
"https://devapi.autoplannerx.com/api/v1/calendar-ics-generator/events/meeting%3A1/ics?method=publish",
headers={"X-API-Key": "YOUR_API_KEY"},
)
response.raise_for_status()
with open("event.ics", "wb") as f:
f.write(response.content)
curl -X DELETE "https://devapi.autoplannerx.com/api/v1/calendar-ics-generator/events/meeting%3A1" \
-H "X-API-Key: YOUR_API_KEY"
const response = await fetch('https://devapi.autoplannerx.com/api/v1/calendar-ics-generator/events/meeting%3A1', {
method: 'DELETE',
headers: {
'X-API-Key': 'YOUR_API_KEY'
}
});
if (!response.ok) {
throw new Error(`Request failed: ${response.status}`);
}
const data = await response.json();
console.log(data);
// Node.js 18+ as an ES module (.mjs). Set DEVAPI_KEY in your environment.
const response = await fetch('https://devapi.autoplannerx.com/api/v1/calendar-ics-generator/events/meeting%3A1', {
method: 'DELETE',
headers: {
'X-API-Key': process.env.DEVAPI_KEY
}
});
if (!response.ok) {
throw new Error(`Request failed: ${response.status}`);
}
console.log(await response.json());
<?php
$ch = curl_init('https://devapi.autoplannerx.com/api/v1/calendar-ics-generator/events/meeting%3A1');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'DELETE',
CURLOPT_HTTPHEADER => [
'X-API-Key: YOUR_API_KEY',
],
]);
$response = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status !== 200) {
die('Request failed: ' . $response);
}
$data = json_decode($response, true);
print_r($data);
import requests
response = requests.delete(
"https://devapi.autoplannerx.com/api/v1/calendar-ics-generator/events/meeting%3A1",
headers={"X-API-Key": "YOUR_API_KEY"},
)
response.raise_for_status()
print(response.json())
curl -X POST "https://devapi.autoplannerx.com/api/v1/calendar-ics-generator/links" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"title":"Team Meeting","start":"2026-12-20 14:00","end":"2026-12-20 15:30","timezone":"Africa/Johannesburg","location":"Conference Room A"}'
const response = await fetch('https://devapi.autoplannerx.com/api/v1/calendar-ics-generator/links', {
method: 'POST',
headers: {
'X-API-Key': 'YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
"title": "Team Meeting",
"start": "2026-12-20 14:00",
"end": "2026-12-20 15:30",
"timezone": "Africa/Johannesburg",
"location": "Conference Room A"
})
});
if (!response.ok) {
throw new Error(`Request failed: ${response.status}`);
}
const data = await response.json();
console.log(data);
// Node.js 18+ as an ES module (.mjs). Set DEVAPI_KEY in your environment.
const response = await fetch('https://devapi.autoplannerx.com/api/v1/calendar-ics-generator/links', {
method: 'POST',
headers: {
'X-API-Key': process.env.DEVAPI_KEY,
'Content-Type': 'application/json'
},
body: JSON.stringify({
"title": "Team Meeting",
"start": "2026-12-20 14:00",
"end": "2026-12-20 15:30",
"timezone": "Africa/Johannesburg",
"location": "Conference Room A"
})
});
if (!response.ok) {
throw new Error(`Request failed: ${response.status}`);
}
console.log(await response.json());
<?php
$ch = curl_init('https://devapi.autoplannerx.com/api/v1/calendar-ics-generator/links');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => json_encode([
'title' => 'Team Meeting',
'start' => '2026-12-20 14:00',
'end' => '2026-12-20 15:30',
'timezone' => 'Africa/Johannesburg',
'location' => 'Conference Room A',
]),
CURLOPT_HTTPHEADER => [
'X-API-Key: YOUR_API_KEY',
'Content-Type: application/json',
],
]);
$response = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status !== 200) {
die('Request failed: ' . $response);
}
$data = json_decode($response, true);
print_r($data);
import requests
response = requests.post(
"https://devapi.autoplannerx.com/api/v1/calendar-ics-generator/links",
headers={"X-API-Key": "YOUR_API_KEY"},
json={
"title": "Team Meeting",
"start": "2026-12-20 14:00",
"end": "2026-12-20 15:30",
"timezone": "Africa/Johannesburg",
"location": "Conference Room A",
},
)
response.raise_for_status()
print(response.json())
curl -X POST "https://devapi.autoplannerx.com/api/v1/calendar-ics-generator/feeds" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"user_ref":"user:7","name":"My work calendar"}'
const response = await fetch('https://devapi.autoplannerx.com/api/v1/calendar-ics-generator/feeds', {
method: 'POST',
headers: {
'X-API-Key': 'YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
"user_ref": "user:7",
"name": "My work calendar"
})
});
if (!response.ok) {
throw new Error(`Request failed: ${response.status}`);
}
const data = await response.json();
console.log(data);
// Node.js 18+ as an ES module (.mjs). Set DEVAPI_KEY in your environment.
const response = await fetch('https://devapi.autoplannerx.com/api/v1/calendar-ics-generator/feeds', {
method: 'POST',
headers: {
'X-API-Key': process.env.DEVAPI_KEY,
'Content-Type': 'application/json'
},
body: JSON.stringify({
"user_ref": "user:7",
"name": "My work calendar"
})
});
if (!response.ok) {
throw new Error(`Request failed: ${response.status}`);
}
console.log(await response.json());
<?php
$ch = curl_init('https://devapi.autoplannerx.com/api/v1/calendar-ics-generator/feeds');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => json_encode([
'user_ref' => 'user:7',
'name' => 'My work calendar',
]),
CURLOPT_HTTPHEADER => [
'X-API-Key: YOUR_API_KEY',
'Content-Type: application/json',
],
]);
$response = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status !== 200) {
die('Request failed: ' . $response);
}
$data = json_decode($response, true);
print_r($data);
import requests
response = requests.post(
"https://devapi.autoplannerx.com/api/v1/calendar-ics-generator/feeds",
headers={"X-API-Key": "YOUR_API_KEY"},
json={
"user_ref": "user:7",
"name": "My work calendar",
},
)
response.raise_for_status()
print(response.json())
Try It
Requests go to the live gateway with your key. They count toward your rate limit and are billed like any other call ($0.0300 per call before account discounts). Your key is only used for this request and is never saved.