The Nylas Calendar API lets you schedule meetings with participants, check availability across calendars, and RSVP to events — across Google Calendar, Outlook, Exchange, and iCloud through a single API. Instead of building separate integrations for each provider, you write your code once and Nylas handles the differences.
This quickstart walks you through the things developers actually build with the Calendar API: scheduling meetings, finding available times, and responding to invites.
Before you begin
Section titled “Before you begin”You need two things from Nylas to make API calls:
- An API key — authenticates your application. You’ll pass it as a Bearer token.
- A grant ID — identifies which user’s calendar to act on. You get one when you connect an account to Nylas.
If you don’t have these yet, follow one of the setup guides first:
- Get started with the CLI — run
nylas initto create an account, generate an API key, and connect a test account in one command. - Get started with the Dashboard — do the same steps through the web UI.
Then install the Nylas SDK for your language:
npm install nylaspip install nylasgem install nylasFor Java and Kotlin, see the Kotlin/Java SDK setup guide.
Schedule a meeting with participants
Section titled “Schedule a meeting with participants”The most common use case: create an event on a user’s calendar and invite participants. Nylas sends the invitations automatically. Replace <NYLAS_GRANT_ID>, <NYLAS_API_KEY>, and <CALENDAR_ID> with your values.
curl --request POST \ --url ‘https://api.us.nylas.com/v3/grants/<NYLAS_GRANT_ID>/events?calendar_id=<CALENDAR_ID>’ \ --header ‘Authorization: Bearer <NYLAS_API_KEY>’ \ --header ‘Content-Type: application/json’ \ --data ‘{ "title": "Project kickoff", "description": "Review goals and assign workstreams", "when": { "start_time": 1735689600, "end_time": 1735693200, "start_timezone": "America/New_York", "end_timezone": "America/New_York" }, "participants": [ ], "location": "Conference Room B" }’import Nylas from "nylas";
const nylas = new Nylas({ apiKey: process.env.NYLAS_API_KEY });
const now = Math.floor(Date.now() / 1000);
const event = await nylas.events.create({ identifier: process.env.NYLAS_GRANT_ID, requestBody: { title: "Project kickoff", description: "Review goals and assign workstreams", when: { startTime: now + 3600, endTime: now + 7200, }, participants: [ ], location: "Conference Room B", }, queryParams: { calendarId: "<CALENDAR_ID>", },});
console.log("Created event:", event.data.id);import osimport timefrom nylas import Client
nylas = Client(os.environ["NYLAS_API_KEY"])
now = int(time.time())
event = nylas.events.create( os.environ["NYLAS_GRANT_ID"], request_body={ "title": "Project kickoff", "description": "Review goals and assign workstreams", "when": { "start_time": now + 3600, "end_time": now + 7200, }, "participants": [ ], "location": "Conference Room B", }, query_params={"calendar_id": "<CALENDAR_ID>"},)
print("Created event:", event.data.id)require ‘nylas’
nylas = Nylas::Client.new(api_key: ENV[‘NYLAS_API_KEY’])
now = Time.now.to_i
event, _ = nylas.events.create( identifier: ENV[‘NYLAS_GRANT_ID’], request_body: { title: ‘Project kickoff’, description: ‘Review goals and assign workstreams’, when: { start_time: now + 3600, end_time: now + 7200 }, participants: [ { name: ‘Alice’, email: ‘alice@example.com’ }, { name: ‘Bob’, email: ‘bob@example.com’ } ], location: ‘Conference Room B’ }, query_params: { calendar_id: ‘<CALENDAR_ID>’ })
puts "Created event: #{event[:id]}"import com.nylas.NylasClient;import com.nylas.models.*;import java.time.Instant;import java.util.List;
public class CreateEvent { public static void main(String[] args) throws NylasSdkTimeoutError, NylasApiError { NylasClient nylas = new NylasClient.Builder("<NYLAS_API_KEY>").build();
long now = Instant.now().getEpochSecond();
CreateEventRequest.When.Timespan when = new CreateEventRequest.When.Timespan.Builder( (int) (now + 3600), (int) (now + 7200) ).build();
CreateEventRequest requestBody = new CreateEventRequest.Builder(when) .title("Project kickoff") .description("Review goals and assign workstreams") .participants(List.of( new CreateEventRequest.Participant("[email protected]", ParticipantStatus.NOREPLY, "Alice", "", ""), )) .location("Conference Room B") .build();
CreateEventQueryParams queryParams = new CreateEventQueryParams.Builder("<CALENDAR_ID>").build(); Response<Event> event = nylas.events().create("<NYLAS_GRANT_ID>", requestBody, queryParams);
System.out.println("Created event: " + event.getData().getId()); }}import com.nylas.NylasClientimport com.nylas.models.*import java.time.Instant
fun main() { val nylas = NylasClient(apiKey = "<NYLAS_API_KEY>")
val now = Instant.now().epochSecond
val when = CreateEventRequest.When.Timespan( startTime = (now + 3600).toInt(), endTime = (now + 7200).toInt() )
val requestBody = CreateEventRequest( `when` = `when`, title = "Project kickoff", description = "Review goals and assign workstreams", participants = listOf( ), location = "Conference Room B" )
val queryParams = CreateEventQueryParams("<CALENDAR_ID>") val event = nylas.events().create("<NYLAS_GRANT_ID>", requestBody, queryParams)
println("Created event: ${event.data.id}")}nylas calendar events create \ --title "Project kickoff" \ --start "tomorrow 9am" \ --end "tomorrow 10am" \The event appears on the user’s calendar and invitations go out to participants immediately. That same code works whether the user is on Google Calendar, Outlook, or any other supported provider.
Check availability
Section titled “Check availability”Before scheduling, find times when participants are free. The availability endpoint checks across multiple users’ calendars and returns open time slots.
curl --request POST \ --url ‘https://api.us.nylas.com/v3/calendars/availability’ \ --header ‘Authorization: Bearer <NYLAS_API_KEY>’ \ --header ‘Content-Type: application/json’ \ --data ‘{ "start_time": 1735689600, "end_time": 1735776000, "duration_minutes": 30, "participants": [ ] }’const availability = await nylas.calendars.getAvailability({ requestBody: { startTime: Math.floor(Date.now() / 1000), endTime: Math.floor(Date.now() / 1000) + 86400, durationMinutes: 30, participants: [ ], },});
availability.data.timeslots.forEach((slot) => { console.log(`Available: ${new Date(slot.startTime * 1000).toISOString()}`);});import time
availability = nylas.calendars.get_availability( request_body={ "start_time": int(time.time()), "end_time": int(time.time()) + 86400, "duration_minutes": 30, "participants": [ ], },)
for slot in availability.data.time_slots: print(f"Available: {slot.start_time}")availability, _ = nylas.calendars.get_availability( request_body: { start_time: Time.now.to_i, end_time: Time.now.to_i + 86400, duration_minutes: 30, participants: [ { email: ‘alice@example.com’ }, { email: ‘bob@example.com’ } ] })
availability[:time_slots].each do |slot| puts "Available: #{Time.at(slot[:start_time])}"endimport com.nylas.NylasClient;import com.nylas.models.*;import java.time.Instant;import java.util.List;
NylasClient nylas = new NylasClient.Builder("<NYLAS_API_KEY>").build();
long now = Instant.now().getEpochSecond();
GetAvailabilityRequest request = new GetAvailabilityRequest.Builder( (int) now, (int) (now + 86400), 30, List.of( )).build();
Response<GetAvailabilityResponse> availability = nylas.calendars().getAvailability(request);val now = Instant.now().epochSecond
val request = GetAvailabilityRequest( startTime = now.toInt(), endTime = (now + 86400).toInt(), durationMinutes = 30, participants = listOf( ))
val availability = nylas.calendars().getAvailability(request)nylas calendar schedule ai "Find time for a 30-minute meeting with [email protected] and [email protected] tomorrow"This is the foundation for building scheduling features — find open slots, present them to the user, then create an event in one of the available windows. For a complete scheduling solution with a pre-built UI, see Nylas Scheduler.
RSVP to an event
Section titled “RSVP to an event”Respond to a calendar invitation on behalf of a user. Pass the event ID and calendar ID along with the RSVP status (yes, no, or maybe).
curl --request POST \ --url ‘https://api.us.nylas.com/v3/grants/<NYLAS_GRANT_ID>/events/<EVENT_ID>/send-rsvp?calendar_id=<CALENDAR_ID>’ \ --header ‘Authorization: Bearer <NYLAS_API_KEY>’ \ --header ‘Content-Type: application/json’ \ --data ‘{ "status": "yes" }’await nylas.events.sendRsvp({ identifier: process.env.NYLAS_GRANT_ID, eventId: "<EVENT_ID>", requestBody: { status: "yes" }, queryParams: { calendarId: "<CALENDAR_ID>" },});nylas.events.send_rsvp( os.environ["NYLAS_GRANT_ID"], event_id="<EVENT_ID>", request_body={"status": "yes"}, query_params={"calendar_id": "<CALENDAR_ID>"},)nylas.events.send_rsvp( identifier: ENV[‘NYLAS_GRANT_ID’], event_id: ‘<EVENT_ID>’, request_body: { status: ‘yes’ }, query_params: { calendar_id: ‘<CALENDAR_ID>’ })SendRsvpRequest rsvpRequest = new SendRsvpRequest("yes");SendRsvpQueryParams rsvpParams = new SendRsvpQueryParams.Builder("<CALENDAR_ID>").build();
nylas.events().sendRsvp("<NYLAS_GRANT_ID>", "<EVENT_ID>", rsvpRequest, rsvpParams);val rsvpRequest = SendRsvpRequest(status = "yes")val rsvpParams = SendRsvpQueryParams("<CALENDAR_ID>")
nylas.events().sendRsvp("<NYLAS_GRANT_ID>", "<EVENT_ID>", rsvpRequest, rsvpParams)nylas calendar events rsvp <EVENT_ID> --status yesList a user’s calendars
Section titled “List a user’s calendars”Each user can have multiple calendars (work, personal, shared team calendars). Use this to find the right calendar_id for the operations above.
curl --request GET \ --url ‘https://api.us.nylas.com/v3/grants/<NYLAS_GRANT_ID>/calendars’ \ --header ‘Authorization: Bearer <NYLAS_API_KEY>’const calendars = await nylas.calendars.list({ identifier: process.env.NYLAS_GRANT_ID,});
calendars.data.forEach((cal) => { console.log(`${cal.name} (${cal.id}) -- primary: ${cal.isPrimary}`);});calendars = nylas.calendars.list(os.environ["NYLAS_GRANT_ID"])
for cal in calendars.data: print(f"{cal.name} ({cal.id}) -- primary: {cal.is_primary}")calendars, _ = nylas.calendars.list(identifier: ENV[‘NYLAS_GRANT_ID’])
calendars.each do |cal| puts "#{cal[:name]} (#{cal[:id]}) -- primary: #{cal[:is_primary]}"endListResponse<Calendar> calendars = nylas.calendars().list("<NYLAS_GRANT_ID>");
for (Calendar cal : calendars.getData()) { System.out.println(cal.getName() + " (" + cal.getId() + ") -- primary: " + cal.getIsPrimary());}val calendars = nylas.calendars().list("<NYLAS_GRANT_ID>").data
for (cal in calendars) { println("${cal.name} (${cal.id}) -- primary: ${cal.isPrimary}")}nylas calendar listWhat’s next
Section titled “What’s next”- Authentication — set up OAuth so your users can connect their accounts
- Availability deep dive — open hours, buffers, round-robin, and collective availability
- Scheduler — drop-in scheduling UI your users can share
- Webhooks — get notified when events are created, updated, or deleted
- Events API reference — full endpoint documentation
- Manage calendars from the terminal — quick testing with the Nylas CLI