[{"data":1,"prerenderedAt":910},["ShallowReactive",2],{"navigation":3,"page:\u002Fquickstart":45},{"title":4,"links":5},"API reference",[6,9,12,15,18,21,24,27,30,33,36,39,42],{"title":7,"href":8},"Accounts","\u002Freference\u002Faccounts",{"title":10,"href":11},"Connect","\u002Freference\u002Fconnect",{"title":13,"href":14},"Calendars","\u002Freference\u002Fcalendars",{"title":16,"href":17},"Events","\u002Freference\u002Fevents",{"title":19,"href":20},"Availability","\u002Freference\u002Favailability",{"title":22,"href":23},"Meetings","\u002Freference\u002Fmeetings",{"title":25,"href":26},"Invitations","\u002Freference\u002Finvitations",{"title":28,"href":29},"Webhooks","\u002Freference\u002Fwebhooks",{"title":31,"href":32},"Metadata","\u002Freference\u002Fmetadata",{"title":34,"href":35},"Keys","\u002Freference\u002Fkeys",{"title":37,"href":38},"Sandbox","\u002Freference\u002Fsandbox",{"title":40,"href":41},"Usage","\u002Freference\u002Fusage",{"title":43,"href":44},"Logs","\u002Freference\u002Flogs",{"kind":46,"title":47,"description":48,"sections":49,"doc":71},"guide","Quickstart","Go from a test key to an event on a calendar in 5 minutes, using your app's sandbox.",[50,53,56,59,62,65,68],{"id":51,"title":52},"get-a-test-key","Get a test key",{"id":54,"title":55},"install-the-sdk","Install the SDK",{"id":57,"title":58},"list-the-connected-accounts","List the connected accounts",{"id":60,"title":61},"read-a-week-of-events","Read a week of events",{"id":63,"title":64},"create-an-event","Create an event",{"id":66,"title":67},"see-it-in-the-dashboard","See it in the dashboard",{"id":69,"title":70},"connect-a-real-calendar","Connect a real calendar",{"id":72,"title":47,"body":73,"description":48,"extension":901,"hero":902,"meta":903,"navigation":211,"path":904,"rawbody":905,"sections":906,"seo":907,"stem":79,"v1":908,"__hash__":909},"docs\u002Fquickstart.md",{"type":74,"value":75,"toc":892},"minimark",[76,80,87,90,111,139,141,153,171,173,180,357,359,376,567,570,606,608,812,826,828,842,844,852,863,888],[77,78,47],"h1",{"id":79},"quickstart",[81,82,83],"lead",{},[84,85,86],"p",{},"In this guide, you send your first requests to your app's sandbox, where sample people already have a week of events. The sandbox doesn't connect to any real calendar. When your integration works, you can connect a real one.",[88,89,52],"h2",{"id":51},[84,91,92,93,100,101,105,106,110],{},"Sign in to the ",[94,95,99],"a",{"href":96,"rel":97},"https:\u002F\u002Fapp.pyas.io",[98],"nofollow","dashboard",", open your app (or create one), and copy a test key from ",[102,103,104],"strong",{},"API keys",". Test keys start with ",[107,108,109],"code",{},"pyas_sk_test_"," and work only in your app's sandbox, so you can test anything without affecting real calendars.",[112,113,118],"pre",{"className":114,"code":115,"language":116,"meta":117,"style":117},"language-bash shiki shiki-themes css-variables","export PYAS_API_KEY=pyas_sk_test_...\n","bash","",[107,119,120],{"__ignoreMap":117},[121,122,125,129,133,136],"span",{"class":123,"line":124},"line",1,[121,126,128],{"class":127},"sag7P","export",[121,130,132],{"class":131},"sqSWz"," PYAS_API_KEY",[121,134,135],{"class":127},"=",[121,137,138],{"class":131},"pyas_sk_test_...\n",[88,140,55],{"id":54},[84,142,143,144,147,148,152],{},"The SDK is optional. Every request is a plain HTTPS request with your key in the ",[107,145,146],{},"x-api-key"," header. Each example on this page shows both the SDK and cURL. To send them from Postman instead, see ",[94,149,151],{"href":150},"\u002Fsdks#postman","Postman",".",[112,154,156],{"className":114,"code":155,"language":116,"meta":117,"style":117},"npm install @pyas\u002Fsdk\n",[107,157,158],{"__ignoreMap":117},[121,159,160,164,168],{"class":123,"line":124},[121,161,163],{"class":162},"s1IGz","npm",[121,165,167],{"class":166},"sTB4W"," install",[121,169,170],{"class":166}," @pyas\u002Fsdk\n",[88,172,58],{"id":57},[84,174,175,176,179],{},"Your sandbox includes sample people, and each one has a connected account with a Pyas calendar. Every request that reads or writes calendar data must include an ",[107,177,178],{},"accountId",", so start by listing the accounts.",[181,182,183,332],"code-group",{},[112,184,189],{"className":185,"code":186,"filename":187,"language":188,"meta":117,"style":117},"language-js shiki shiki-themes css-variables","import { Pyas } from '@pyas\u002Fsdk'\n\nconst pyas = new Pyas({ apiKey: process.env.PYAS_API_KEY })\n\nfor await (const account of pyas.accounts.list()) {\n  console.log(account.accountId, account.name, account.provider)\n}\n","Node.js","js",[107,190,191,206,213,254,259,292,326],{"__ignoreMap":117},[121,192,193,196,199,202],{"class":123,"line":124},[121,194,195],{"class":127},"import",[121,197,198],{"class":131}," { Pyas } ",[121,200,201],{"class":127},"from",[121,203,205],{"class":204},"sk1Au"," '@pyas\u002Fsdk'\n",[121,207,209],{"class":123,"line":208},2,[121,210,212],{"emptyLinePlaceholder":211},true,"\n",[121,214,216,219,223,226,229,232,235,238,241,243,246,248,251],{"class":123,"line":215},3,[121,217,218],{"class":127},"const",[121,220,222],{"class":221},"sXULy"," pyas",[121,224,225],{"class":127}," =",[121,227,228],{"class":127}," new",[121,230,231],{"class":162}," Pyas",[121,233,234],{"class":131},"({ apiKey",[121,236,237],{"class":127},":",[121,239,240],{"class":221}," process",[121,242,152],{"class":131},[121,244,245],{"class":221},"env",[121,247,152],{"class":131},[121,249,250],{"class":221},"PYAS_API_KEY",[121,252,253],{"class":131}," })\n",[121,255,257],{"class":123,"line":256},4,[121,258,212],{"emptyLinePlaceholder":211},[121,260,262,265,268,271,273,276,279,281,283,286,289],{"class":123,"line":261},5,[121,263,264],{"class":127},"for",[121,266,267],{"class":127}," await",[121,269,270],{"class":131}," (",[121,272,218],{"class":127},[121,274,275],{"class":221}," account",[121,277,278],{"class":127}," of",[121,280,222],{"class":221},[121,282,152],{"class":162},[121,284,285],{"class":221},"accounts",[121,287,288],{"class":162},".list",[121,290,291],{"class":131},"()) {\n",[121,293,295,298,301,304,307,310,314,316,319,321,323],{"class":123,"line":294},6,[121,296,297],{"class":221},"  console",[121,299,300],{"class":162},".log",[121,302,303],{"class":131},"(",[121,305,306],{"class":221},"account",[121,308,309],{"class":131},".accountId",[121,311,313],{"class":312},"sEEt9",",",[121,315,275],{"class":221},[121,317,318],{"class":131},".name",[121,320,313],{"class":312},[121,322,275],{"class":221},[121,324,325],{"class":131},".provider)\n",[121,327,329],{"class":123,"line":328},7,[121,330,331],{"class":131},"}\n",[112,333,336],{"className":114,"code":334,"filename":335,"language":116,"meta":117,"style":117},"curl https:\u002F\u002Fapi.pyas.io\u002Fv2\u002Faccounts \\\n  -H \"x-api-key: $PYAS_API_KEY\"\n","cURL",[107,337,338,349],{"__ignoreMap":117},[121,339,340,343,346],{"class":123,"line":124},[121,341,342],{"class":162},"curl",[121,344,345],{"class":166}," https:\u002F\u002Fapi.pyas.io\u002Fv2\u002Faccounts",[121,347,348],{"class":131}," \\\n",[121,350,351,354],{"class":123,"line":208},[121,352,353],{"class":166},"  -H",[121,355,356],{"class":204}," \"x-api-key: $PYAS_API_KEY\"\n",[88,358,61],{"id":60},[84,360,361,362,364,365,367,368,371,372,375],{},"Pass an ",[107,363,178],{}," from the previous step and a time window in ",[107,366,201],{}," and ",[107,369,370],{},"to",". With ",[107,373,374],{},"expand=true",", each occurrence of a recurring event is returned separately.",[181,377,378,547],{},[112,379,381],{"className":185,"code":380,"filename":187,"language":188,"meta":117,"style":117},"const from = new Date()\nconst to = new Date(Date.now() + 7 * 86_400_000)\n\nconst page = await pyas.events.list({ accountId, from: from.toISOString(), to: to.toISOString(), expand: true })\nfor (const event of page.data) {\n  console.log(event.startsAt, event.title)\n}\n",[107,382,383,400,439,443,504,522,543],{"__ignoreMap":117},[121,384,385,387,390,392,394,397],{"class":123,"line":124},[121,386,218],{"class":127},[121,388,389],{"class":221}," from",[121,391,225],{"class":127},[121,393,228],{"class":127},[121,395,396],{"class":162}," Date",[121,398,399],{"class":131},"()\n",[121,401,402,404,407,409,411,413,415,418,421,424,427,430,433,436],{"class":123,"line":208},[121,403,218],{"class":127},[121,405,406],{"class":221}," to",[121,408,225],{"class":127},[121,410,228],{"class":127},[121,412,396],{"class":162},[121,414,303],{"class":131},[121,416,417],{"class":221},"Date",[121,419,420],{"class":162},".now",[121,422,423],{"class":131},"() ",[121,425,426],{"class":127},"+",[121,428,429],{"class":221}," 7",[121,431,432],{"class":127}," *",[121,434,435],{"class":221}," 86_400_000",[121,437,438],{"class":131},")\n",[121,440,441],{"class":123,"line":215},[121,442,212],{"emptyLinePlaceholder":211},[121,444,445,447,450,452,454,456,458,461,463,466,468,470,472,474,477,480,482,484,486,488,490,492,494,497,499,502],{"class":123,"line":256},[121,446,218],{"class":127},[121,448,449],{"class":221}," page",[121,451,225],{"class":127},[121,453,267],{"class":127},[121,455,222],{"class":221},[121,457,152],{"class":162},[121,459,460],{"class":221},"events",[121,462,288],{"class":162},[121,464,465],{"class":131},"({ accountId",[121,467,313],{"class":312},[121,469,389],{"class":131},[121,471,237],{"class":127},[121,473,389],{"class":221},[121,475,476],{"class":162},".toISOString",[121,478,479],{"class":131},"()",[121,481,313],{"class":312},[121,483,406],{"class":131},[121,485,237],{"class":127},[121,487,406],{"class":221},[121,489,476],{"class":162},[121,491,479],{"class":131},[121,493,313],{"class":312},[121,495,496],{"class":131}," expand",[121,498,237],{"class":127},[121,500,501],{"class":221}," true",[121,503,253],{"class":131},[121,505,506,508,510,512,515,517,519],{"class":123,"line":261},[121,507,264],{"class":127},[121,509,270],{"class":131},[121,511,218],{"class":127},[121,513,514],{"class":221}," event",[121,516,278],{"class":127},[121,518,449],{"class":221},[121,520,521],{"class":131},".data) {\n",[121,523,524,526,528,530,533,536,538,540],{"class":123,"line":294},[121,525,297],{"class":221},[121,527,300],{"class":162},[121,529,303],{"class":131},[121,531,532],{"class":221},"event",[121,534,535],{"class":131},".startsAt",[121,537,313],{"class":312},[121,539,514],{"class":221},[121,541,542],{"class":131},".title)\n",[121,544,545],{"class":123,"line":328},[121,546,331],{"class":131},[112,548,550],{"className":114,"code":549,"filename":335,"language":116,"meta":117,"style":117},"curl \"https:\u002F\u002Fapi.pyas.io\u002Fv2\u002Fevents?accountId=$ACCOUNT_ID&from=2026-10-20T00:00:00Z&to=2026-10-27T00:00:00Z&expand=true\" \\\n  -H \"x-api-key: $PYAS_API_KEY\"\n",[107,551,552,561],{"__ignoreMap":117},[121,553,554,556,559],{"class":123,"line":124},[121,555,342],{"class":162},[121,557,558],{"class":204}," \"https:\u002F\u002Fapi.pyas.io\u002Fv2\u002Fevents?accountId=$ACCOUNT_ID&from=2026-10-20T00:00:00Z&to=2026-10-27T00:00:00Z&expand=true\"",[121,560,348],{"class":131},[121,562,563,565],{"class":123,"line":208},[121,564,353],{"class":166},[121,566,356],{"class":204},[84,568,569],{},"Events have the same structure on Google Calendar, Microsoft Outlook and Pyas calendars. Every event includes:",[571,572,573,583,597,600],"ul",{},[574,575,576,367,579,582],"li",{},[107,577,578],{},"startsAt",[107,580,581],{},"endsAt"," in UTC.",[574,584,585,586,589,590,367,593,596],{},"The same times in the calendar's own time zone (",[107,587,588],{},"startsAtLocal",", ",[107,591,592],{},"endsAtLocal",[107,594,595],{},"timezone",").",[574,598,599],{},"Attendees and conferencing details.",[574,601,602,603,152],{},"Your own ",[107,604,605],{},"metadata",[88,607,64],{"id":63},[181,609,610,728],{},[112,611,613],{"className":185,"code":612,"filename":187,"language":188,"meta":117,"style":117},"const event = await pyas.events.create({\n  accountId,\n  title: 'Intro call',\n  startsAt: '2026-10-21T15:00:00Z',\n  endsAt: '2026-10-21T15:30:00Z',\n  attendees: [{ email: 'sam.patel@example.org' }],\n})\nconsole.log(event.id, event.startsAtLocal)\n",[107,614,615,637,645,657,669,681,701,706],{"__ignoreMap":117},[121,616,617,619,621,623,625,627,629,631,634],{"class":123,"line":124},[121,618,218],{"class":127},[121,620,514],{"class":221},[121,622,225],{"class":127},[121,624,267],{"class":127},[121,626,222],{"class":221},[121,628,152],{"class":162},[121,630,460],{"class":221},[121,632,633],{"class":162},".create",[121,635,636],{"class":131},"({\n",[121,638,639,642],{"class":123,"line":208},[121,640,641],{"class":131},"  accountId",[121,643,644],{"class":312},",\n",[121,646,647,650,652,655],{"class":123,"line":215},[121,648,649],{"class":131},"  title",[121,651,237],{"class":127},[121,653,654],{"class":204}," 'Intro call'",[121,656,644],{"class":312},[121,658,659,662,664,667],{"class":123,"line":256},[121,660,661],{"class":131},"  startsAt",[121,663,237],{"class":127},[121,665,666],{"class":204}," '2026-10-21T15:00:00Z'",[121,668,644],{"class":312},[121,670,671,674,676,679],{"class":123,"line":261},[121,672,673],{"class":131},"  endsAt",[121,675,237],{"class":127},[121,677,678],{"class":204}," '2026-10-21T15:30:00Z'",[121,680,644],{"class":312},[121,682,683,686,688,691,693,696,699],{"class":123,"line":294},[121,684,685],{"class":131},"  attendees",[121,687,237],{"class":127},[121,689,690],{"class":131}," [{ email",[121,692,237],{"class":127},[121,694,695],{"class":204}," 'sam.patel@example.org'",[121,697,698],{"class":131}," }]",[121,700,644],{"class":312},[121,702,703],{"class":123,"line":328},[121,704,705],{"class":131},"})\n",[121,707,709,712,714,716,718,721,723,725],{"class":123,"line":708},8,[121,710,711],{"class":221},"console",[121,713,300],{"class":162},[121,715,303],{"class":131},[121,717,532],{"class":221},[121,719,720],{"class":131},".id",[121,722,313],{"class":312},[121,724,514],{"class":221},[121,726,727],{"class":131},".startsAtLocal)\n",[112,729,731],{"className":114,"code":730,"filename":335,"language":116,"meta":117,"style":117},"curl -X POST https:\u002F\u002Fapi.pyas.io\u002Fv2\u002Fevents \\\n  -H \"x-api-key: $PYAS_API_KEY\" \\\n  -H \"content-type: application\u002Fjson\" \\\n  -d '{\n    \"accountId\": \"'$ACCOUNT_ID'\",\n    \"title\": \"Intro call\",\n    \"startsAt\": \"2026-10-21T15:00:00Z\",\n    \"endsAt\": \"2026-10-21T15:30:00Z\",\n    \"attendees\": [{ \"email\": \"sam.patel@example.org\" }]\n  }'\n",[107,732,733,748,757,766,774,785,790,795,800,806],{"__ignoreMap":117},[121,734,735,737,740,743,746],{"class":123,"line":124},[121,736,342],{"class":162},[121,738,739],{"class":166}," -X",[121,741,742],{"class":166}," POST",[121,744,745],{"class":166}," https:\u002F\u002Fapi.pyas.io\u002Fv2\u002Fevents",[121,747,348],{"class":131},[121,749,750,752,755],{"class":123,"line":208},[121,751,353],{"class":166},[121,753,754],{"class":204}," \"x-api-key: $PYAS_API_KEY\"",[121,756,348],{"class":131},[121,758,759,761,764],{"class":123,"line":215},[121,760,353],{"class":166},[121,762,763],{"class":204}," \"content-type: application\u002Fjson\"",[121,765,348],{"class":131},[121,767,768,771],{"class":123,"line":256},[121,769,770],{"class":166},"  -d",[121,772,773],{"class":204}," '{\n",[121,775,776,779,782],{"class":123,"line":261},[121,777,778],{"class":204},"    \"accountId\": \"'",[121,780,781],{"class":131},"$ACCOUNT_ID",[121,783,784],{"class":204},"'\",\n",[121,786,787],{"class":123,"line":294},[121,788,789],{"class":204},"    \"title\": \"Intro call\",\n",[121,791,792],{"class":123,"line":328},[121,793,794],{"class":204},"    \"startsAt\": \"2026-10-21T15:00:00Z\",\n",[121,796,797],{"class":123,"line":708},[121,798,799],{"class":204},"    \"endsAt\": \"2026-10-21T15:30:00Z\",\n",[121,801,803],{"class":123,"line":802},9,[121,804,805],{"class":204},"    \"attendees\": [{ \"email\": \"sam.patel@example.org\" }]\n",[121,807,809],{"class":123,"line":808},10,[121,810,811],{"class":204},"  }'\n",[84,813,814,815,818,819,821,822,152],{},"The SDK sends an ",[107,816,817],{},"Idempotency-Key"," with every request that creates, changes or deletes something. If it retries the request after a dropped connection, the event isn't created twice. If you call the API with plain HTTP, send your own ",[107,820,817],{}," header. See ",[94,823,825],{"href":824},"\u002Fidempotency","Retries and idempotency",[88,827,67],{"id":66},[84,829,830,831,834,835,837,838,841],{},"To see the event you created, switch your app to ",[102,832,833],{},"Test mode"," in the dashboard, open ",[102,836,7],{},", select the person and open their ",[102,839,840],{},"Calendar"," tab. When you select the event, the dashboard shows the request that last updated it.",[88,843,70],{"id":69},[84,845,846,847,851],{},"When your integration works in the sandbox, switch to a live key and let your users connect their own Google, Microsoft Outlook or Zoom accounts with ",[94,848,850],{"href":849},"\u002Fconnect","PyasConnect",". The code you wrote for the sandbox works without changes, because the requests, the event structure and the errors are the same.",[853,854,855],"note",{},[84,856,857,858,862],{},"To receive notifications about changes instead of polling, set up ",[94,859,861],{"href":860},"\u002Fwebhooks","webhooks",". During development, you can forward your sandbox's events to your local handler with the CLI command below.",[112,864,866],{"className":114,"code":865,"language":116,"meta":117,"style":117},"npx @pyas\u002Fcli webhooks listen --forward http:\u002F\u002Flocalhost:3000\u002Fwebhooks\n",[107,867,868],{"__ignoreMap":117},[121,869,870,873,876,879,882,885],{"class":123,"line":124},[121,871,872],{"class":162},"npx",[121,874,875],{"class":166}," @pyas\u002Fcli",[121,877,878],{"class":166}," webhooks",[121,880,881],{"class":166}," listen",[121,883,884],{"class":166}," --forward",[121,886,887],{"class":166}," http:\u002F\u002Flocalhost:3000\u002Fwebhooks\n",[889,890,891],"style",{},"html pre.shiki code .sag7P, html code.shiki .sag7P{--shiki-default:var(--shiki-token-keyword)}html pre.shiki code .sqSWz, html code.shiki .sqSWz{--shiki-default:var(--shiki-foreground)}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .s1IGz, html code.shiki .s1IGz{--shiki-default:var(--shiki-token-function)}html pre.shiki code .sTB4W, html code.shiki .sTB4W{--shiki-default:var(--shiki-token-string)}html pre.shiki code .sk1Au, html code.shiki .sk1Au{--shiki-default:var(--shiki-token-string-expression)}html pre.shiki code .sXULy, html code.shiki .sXULy{--shiki-default:var(--shiki-token-constant)}html pre.shiki code .sEEt9, html code.shiki .sEEt9{--shiki-default:var(--shiki-token-punctuation)}",{"title":117,"searchDepth":215,"depth":215,"links":893},[894,895,896,897,898,899,900],{"id":51,"depth":208,"text":52},{"id":54,"depth":208,"text":55},{"id":57,"depth":208,"text":58},{"id":60,"depth":208,"text":61},{"id":63,"depth":208,"text":64},{"id":66,"depth":208,"text":67},{"id":69,"depth":208,"text":70},"md",false,{},"\u002Fquickstart","---\ntitle: Quickstart\ndescription: Go from a test key to an event on a calendar in 5 minutes, using your app's sandbox.\nv1: \u002Ffundamentals\u002Fgetting-set-up\n---\n\n# Quickstart\n\n::lead\nIn this guide, you send your first requests to your app's sandbox, where sample people already have a week of events. The sandbox doesn't connect to any real calendar. When your integration works, you can connect a real one.\n::\n\n## Get a test key\n\nSign in to the [dashboard](https:\u002F\u002Fapp.pyas.io), open your app (or create one), and copy a test key from **API keys**. Test keys start with `pyas_sk_test_` and work only in your app's sandbox, so you can test anything without affecting real calendars.\n\n```bash\nexport PYAS_API_KEY=pyas_sk_test_...\n```\n\n## Install the SDK\n\nThe SDK is optional. Every request is a plain HTTPS request with your key in the `x-api-key` header. Each example on this page shows both the SDK and cURL. To send them from Postman instead, see [Postman](\u002Fsdks#postman).\n\n```bash\nnpm install @pyas\u002Fsdk\n```\n\n## List the connected accounts\n\nYour sandbox includes sample people, and each one has a connected account with a Pyas calendar. Every request that reads or writes calendar data must include an `accountId`, so start by listing the accounts.\n\n::code-group\n```js [Node.js]\nimport { Pyas } from '@pyas\u002Fsdk'\n\nconst pyas = new Pyas({ apiKey: process.env.PYAS_API_KEY })\n\nfor await (const account of pyas.accounts.list()) {\n  console.log(account.accountId, account.name, account.provider)\n}\n```\n\n```bash [cURL]\ncurl https:\u002F\u002Fapi.pyas.io\u002Fv2\u002Faccounts \\\n  -H \"x-api-key: $PYAS_API_KEY\"\n```\n::\n\n## Read a week of events\n\nPass an `accountId` from the previous step and a time window in `from` and `to`. With `expand=true`, each occurrence of a recurring event is returned separately.\n\n::code-group\n```js [Node.js]\nconst from = new Date()\nconst to = new Date(Date.now() + 7 * 86_400_000)\n\nconst page = await pyas.events.list({ accountId, from: from.toISOString(), to: to.toISOString(), expand: true })\nfor (const event of page.data) {\n  console.log(event.startsAt, event.title)\n}\n```\n\n```bash [cURL]\ncurl \"https:\u002F\u002Fapi.pyas.io\u002Fv2\u002Fevents?accountId=$ACCOUNT_ID&from=2026-10-20T00:00:00Z&to=2026-10-27T00:00:00Z&expand=true\" \\\n  -H \"x-api-key: $PYAS_API_KEY\"\n```\n::\n\nEvents have the same structure on Google Calendar, Microsoft Outlook and Pyas calendars. Every event includes:\n\n- `startsAt` and `endsAt` in UTC.\n- The same times in the calendar's own time zone (`startsAtLocal`, `endsAtLocal` and `timezone`).\n- Attendees and conferencing details.\n- Your own `metadata`.\n\n## Create an event\n\n::code-group\n```js [Node.js]\nconst event = await pyas.events.create({\n  accountId,\n  title: 'Intro call',\n  startsAt: '2026-10-21T15:00:00Z',\n  endsAt: '2026-10-21T15:30:00Z',\n  attendees: [{ email: 'sam.patel@example.org' }],\n})\nconsole.log(event.id, event.startsAtLocal)\n```\n\n```bash [cURL]\ncurl -X POST https:\u002F\u002Fapi.pyas.io\u002Fv2\u002Fevents \\\n  -H \"x-api-key: $PYAS_API_KEY\" \\\n  -H \"content-type: application\u002Fjson\" \\\n  -d '{\n    \"accountId\": \"'$ACCOUNT_ID'\",\n    \"title\": \"Intro call\",\n    \"startsAt\": \"2026-10-21T15:00:00Z\",\n    \"endsAt\": \"2026-10-21T15:30:00Z\",\n    \"attendees\": [{ \"email\": \"sam.patel@example.org\" }]\n  }'\n```\n::\n\nThe SDK sends an `Idempotency-Key` with every request that creates, changes or deletes something. If it retries the request after a dropped connection, the event isn't created twice. If you call the API with plain HTTP, send your own `Idempotency-Key` header. See [Retries and idempotency](\u002Fidempotency).\n\n## See it in the dashboard\n\nTo see the event you created, switch your app to **Test mode** in the dashboard, open **Accounts**, select the person and open their **Calendar** tab. When you select the event, the dashboard shows the request that last updated it.\n\n## Connect a real calendar\n\nWhen your integration works in the sandbox, switch to a live key and let your users connect their own Google, Microsoft Outlook or Zoom accounts with [PyasConnect](\u002Fconnect). The code you wrote for the sandbox works without changes, because the requests, the event structure and the errors are the same.\n\n::note\nTo receive notifications about changes instead of polling, set up [webhooks](\u002Fwebhooks). During development, you can forward your sandbox's events to your local handler with the CLI command below.\n::\n\n```bash\nnpx @pyas\u002Fcli webhooks listen --forward http:\u002F\u002Flocalhost:3000\u002Fwebhooks\n```\n",null,{"title":47,"description":48},"\u002Ffundamentals\u002Fgetting-set-up","HAhc6n2GTgTY1VMZXOsufr59kT1F8ZpyRyh3kOQOlSg",1794697270602]