{
  "info": {
    "_postman_id": "25d362d1-c770-4e65-87fa-8b45a4fda562",
    "name": "Mobiscroll Connect API Collection",
    "description": "Explore the collection for the Mobiscroll Connect calendar and scheduling API. For more information see [https://mobiscroll.com/docs/connect](https://mobiscroll.com/docs/connect).\n\nMobiscroll Connect is a unified calendar and scheduling API that provides secure OAuth 2.0 access and a consistent interface for working with events in Google Calendar, Microsoft Outlook, Apple Calendar and CalDAV calendars.\n\nIn this collection you'll find:\n\n- OAuth authorization, token exchange, refresh and revoke, the connection status, and disconnecting a calendar account\n- Calendar discovery (list calendars)\n- Event workflows (list, create, update, delete events)\n- Webhook subscription and unsubscription for change notifications\n- A health check endpoint to validate connectivity\n\nGetting started:\n\n1. Configure your client credentials and redirect URL\n2. Run the OAuth flow to obtain tokens\n3. Call the Events and Calendars endpoints using the acquired access token\n\nDocs: [https://mobiscroll.com/docs/connect](https://mobiscroll.com/docs/connect)",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json",
    "_exporter_id": "48135684"
  },
  "item": [
    {
      "name": "OAuth",
      "item": [
        {
          "name": "Authorize (Browser)",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/oauth/authorize?response_type=code&client_id={{clientId}}&user_id={{userId}}&scope={{scope}}&redirect_uri={{redirectUri}}&lng={{lng}}",
              "host": ["{{baseUrl}}"],
              "path": ["oauth", "authorize"],
              "query": [
                {
                  "key": "response_type",
                  "value": "code"
                },
                {
                  "key": "client_id",
                  "value": "{{clientId}}"
                },
                {
                  "key": "user_id",
                  "value": "{{userId}}"
                },
                {
                  "key": "scope",
                  "value": "{{scope}}"
                },
                {
                  "key": "redirect_uri",
                  "value": "{{redirectUri}}"
                },
                {
                  "key": "lng",
                  "value": "{{lng}}",
                  "description": "Optional. Language of the Connect pages, one of the codes listed at https://mobiscroll.com/docs/connect/localization#supported-languages. Falls back to the Accept-Language header, then English.",
                  "disabled": true
                }
              ]
            },
            "description": "Start OAuth authorization code flow."
          },
          "response": []
        },
        {
          "name": "Exchange Code for Token",
          "request": {
            "auth": {
              "type": "basic",
              "basic": [
                {
                  "key": "username",
                  "value": "{{clientId}}",
                  "type": "string"
                },
                {
                  "key": "password",
                  "value": "{{clientSecret}}",
                  "type": "string"
                }
              ]
            },
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/x-www-form-urlencoded"
              }
            ],
            "body": {
              "mode": "urlencoded",
              "urlencoded": [
                {
                  "key": "grant_type",
                  "value": "authorization_code"
                },
                {
                  "key": "code",
                  "value": "PASTE_AUTH_CODE_HERE"
                },
                {
                  "key": "redirect_uri",
                  "value": "{{redirectUri}}"
                }
              ]
            },
            "url": {
              "raw": "{{baseUrl}}/oauth/token",
              "host": ["{{baseUrl}}"],
              "path": ["oauth", "token"]
            },
            "description": "Exchange authorization code for access + refresh token."
          },
          "response": []
        },
        {
          "name": "Refresh Token",
          "request": {
            "auth": {
              "type": "basic",
              "basic": [
                {
                  "key": "username",
                  "value": "{{clientId}}",
                  "type": "string"
                },
                {
                  "key": "password",
                  "value": "{{clientSecret}}",
                  "type": "string"
                }
              ]
            },
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/x-www-form-urlencoded"
              }
            ],
            "body": {
              "mode": "urlencoded",
              "urlencoded": [
                {
                  "key": "grant_type",
                  "value": "refresh_token"
                },
                {
                  "key": "refresh_token",
                  "value": "{{refreshToken}}"
                }
              ]
            },
            "url": {
              "raw": "{{baseUrl}}/oauth/token",
              "host": ["{{baseUrl}}"],
              "path": ["oauth", "token"]
            },
            "description": "Refresh access token with refresh token."
          },
          "response": []
        },
        {
          "name": "Get Connection Status",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/oauth/connection-status",
              "host": ["{{baseUrl}}"],
              "path": ["oauth", "connection-status"]
            },
            "description": "Connected accounts per provider for the authenticated user.\n\nEach account reports `grantedScopes` — what the provider actually granted — and `calendarPermissionGranted`. The latter is `false` when the account connected but withheld calendar access (Google's consent screen lets the user untick that permission and still sign in), which means it can list no calendars until the user reconnects. It is `null` for Apple and CalDAV, which have no scopes, and for accounts with no scopes recorded.\n\nThe flag is evaluated against the scope of this request, so a grant that satisfies `free-busy` can still report `false` for `read-write`."
          },
          "response": [
            {
              "name": "An account that withheld calendar access",
              "originalRequest": {
                "method": "GET",
                "header": [],
                "url": {
                  "raw": "{{baseUrl}}/oauth/connection-status",
                  "host": ["{{baseUrl}}"],
                  "path": ["oauth", "connection-status"]
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"connections\": {\n    \"google\": [\n      {\n        \"id\": \"granted@gmail.com\",\n        \"display\": \"granted@gmail.com\",\n        \"grantedScopes\": [\n          \"openid\",\n          \"https://www.googleapis.com/auth/userinfo.email\",\n          \"https://www.googleapis.com/auth/calendar\"\n        ],\n        \"calendarPermissionGranted\": true\n      },\n      {\n        \"id\": \"withheld@gmail.com\",\n        \"display\": \"withheld@gmail.com\",\n        \"grantedScopes\": [\n          \"openid\",\n          \"https://www.googleapis.com/auth/userinfo.email\"\n        ],\n        \"calendarPermissionGranted\": false\n      }\n    ],\n    \"microsoft\": [],\n    \"apple\": [\n      {\n        \"id\": \"user@icloud.com\",\n        \"display\": \"user@icloud.com\",\n        \"grantedScopes\": [],\n        \"calendarPermissionGranted\": null\n      }\n    ],\n    \"caldav\": []\n  },\n  \"limitReached\": false,\n  \"limit\": 0\n}"
            }
          ]
        },
        {
          "name": "Disconnect Account",
          "request": {
            "method": "POST",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/oauth/disconnect?provider=google&account=user@gmail.com",
              "host": ["{{baseUrl}}"],
              "path": ["oauth", "disconnect"],
              "query": [
                {
                  "key": "provider",
                  "value": "google",
                  "description": "google, microsoft, apple or caldav"
                },
                {
                  "key": "account",
                  "value": "user@gmail.com",
                  "description": "Optional. The account `id` from Get Connection Status. Disable it to disconnect every account of the provider."
                }
              ]
            },
            "description": "Disconnect one provider account, or every account of a provider when `account` is omitted.\n\nStops the webhook subscriptions of the account's calendars and deletes its stored provider credentials; the account no longer appears in Get Connection Status. Your access and refresh tokens stay valid — use Revoke Token for those. Nothing is revoked at Google or Microsoft.\n\nReturns `200 { \"success\": true }`, also when the account was not connected. A missing or unknown `provider` returns `400`."
          },
          "response": [
            {
              "name": "Disconnected",
              "originalRequest": {
                "method": "POST",
                "header": [],
                "url": {
                  "raw": "{{baseUrl}}/oauth/disconnect?provider=google&account=user@gmail.com",
                  "host": ["{{baseUrl}}"],
                  "path": ["oauth", "disconnect"],
                  "query": [
                    {
                      "key": "provider",
                      "value": "google"
                    },
                    {
                      "key": "account",
                      "value": "user@gmail.com"
                    }
                  ]
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"success\": true\n}"
            },
            {
              "name": "Unknown provider",
              "originalRequest": {
                "method": "POST",
                "header": [],
                "url": {
                  "raw": "{{baseUrl}}/oauth/disconnect?provider=yahoo",
                  "host": ["{{baseUrl}}"],
                  "path": ["oauth", "disconnect"],
                  "query": [
                    {
                      "key": "provider",
                      "value": "yahoo"
                    }
                  ]
                }
              },
              "status": "Bad Request",
              "code": 400,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"error\": \"Missing or invalid provider\"\n}"
            }
          ]
        },
        {
          "name": "Revoke Token",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"token\": \"{{refreshToken}}\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/oauth/revoke",
              "host": ["{{baseUrl}}"],
              "path": ["oauth", "revoke"]
            },
            "description": "Revoke every access and refresh token of the user/client pair (the whole grant). Send the refresh token or an access token — an expired access token works too.\n\nConnected calendar accounts and their webhook subscriptions are not affected — use Disconnect Account for those. Always returns `200 { \"success\": true }`; `400` only when `token` is missing."
          },
          "response": []
        }
      ]
    },
    {
      "name": "Calendars",
      "item": [
        {
          "name": "Get Calendars",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/calendars",
              "host": ["{{baseUrl}}"],
              "path": ["calendars"]
            },
            "description": "Returns all calendars from all connected providers for the authenticated user."
          },
          "response": []
        }
      ]
    },
    {
      "name": "Events",
      "item": [
        {
          "name": "Get Events",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/events?start=2025-01-01T00:00:00Z&end=2025-12-31T23:59:59Z&pageSize=50&singleEvents=true",
              "host": ["{{baseUrl}}"],
              "path": ["events"],
              "query": [
                {
                  "key": "start",
                  "value": "2025-01-01T00:00:00Z"
                },
                {
                  "key": "end",
                  "value": "2025-12-31T23:59:59Z"
                },
                {
                  "key": "pageSize",
                  "value": "50"
                },
                {
                  "key": "singleEvents",
                  "value": "true"
                },
                {
                  "key": "calendarIds",
                  "value": "",
                  "description": "JSON stringified object of calendar IDs per provider, e.g. {\"google\":[\"user@gmail.com\"]}. Omit it to fetch all calendars.",
                  "disabled": true
                },
                {
                  "key": "nextPageToken",
                  "value": "",
                  "description": "Pagination token from previous response",
                  "disabled": true
                }
              ]
            },
            "description": "Get events from all connected providers with pagination and date filtering. `nextPageToken` does not carry the other filters: send the same `start`, `end`, `calendarIds` and `singleEvents` with every page. A `calendarIds` or `nextPageToken` that is not valid JSON returns `400` with `{ \"error\": \"Invalid calendarIds parameter\" }` or `{ \"error\": \"Invalid nextPageToken parameters\" }`."
          },
          "response": []
        },
        {
          "name": "Create Event",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"provider\": \"google\",\n  \"calendarId\": \"primary\",\n  \"title\": \"Test Event\",\n  \"start\": \"2025-10-20T10:00:00Z\",\n  \"end\": \"2025-10-20T11:00:00Z\",\n  \"description\": \"Created via Postman\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/event",
              "host": ["{{baseUrl}}"],
              "path": ["event"]
            },
            "description": "Create event using unified endpoint."
          },
          "response": []
        },
        {
          "name": "Update Event",
          "request": {
            "method": "PUT",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"provider\": \"google\",\n  \"calendarId\": \"primary\",\n  \"eventId\": \"EVENT_ID_HERE\",\n  \"title\": \"Updated Event\",\n  \"start\": \"2025-10-20T10:00:00Z\",\n  \"end\": \"2025-10-20T12:00:00Z\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/event",
              "host": ["{{baseUrl}}"],
              "path": ["event"]
            },
            "description": "Update event using unified endpoint."
          },
          "response": []
        },
        {
          "name": "Delete Event",
          "request": {
            "method": "DELETE",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"provider\": \"google\",\n  \"calendarId\": \"primary\",\n  \"eventId\": \"EVENT_ID_HERE\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/event",
              "host": ["{{baseUrl}}"],
              "path": ["event"]
            },
            "description": "Delete event using unified endpoint."
          },
          "response": []
        }
      ]
    },
    {
      "name": "Webhooks",
      "item": [
        {
          "name": "Subscribe Webhook",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"provider\": \"google\",\n  \"calendarId\": \"primary\",\n  \"expiration\": 1766448000000\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/subscribe-webhook",
              "host": ["{{baseUrl}}"],
              "path": ["subscribe-webhook"]
            },
            "description": "Subscribe to calendar change notifications. Use the calendar's real id from Get Calendars (an alias such as `primary` creates a second subscription). `channelId` is optional; one that belongs to another user's subscription returns `409 { \"error\": \"channelId is already in use\" }`."
          },
          "response": []
        },
        {
          "name": "Unsubscribe Webhook",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"provider\": \"google\",\n  \"channelId\": \"<channelId from Subscribe Webhook>\",\n  \"resourceId\": \"<resourceId from Subscribe Webhook, Google only>\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/unsubscribe-webhook",
              "host": ["{{baseUrl}}"],
              "path": ["unsubscribe-webhook"]
            },
            "description": "Stop a webhook subscription. `provider` and `channelId` are required; `resourceId` is needed for Google."
          },
          "response": []
        }
      ]
    },
    {
      "name": "Health",
      "item": [
        {
          "name": "Health Check",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/health",
              "host": ["{{baseUrl}}"],
              "path": ["health"]
            },
            "description": "Returns { \"status\": \"ok\" }"
          },
          "response": []
        }
      ]
    }
  ],
  "auth": {
    "type": "oauth2",
    "oauth2": [
      {
        "key": "tokenType",
        "value": "Bearer",
        "type": "string"
      },
      {
        "key": "accessToken",
        "value": "{{accessToken}}",
        "type": "string"
      },
      {
        "key": "useBrowser",
        "value": true,
        "type": "boolean"
      },
      {
        "key": "tokenName",
        "value": "Mobiscroll Connect Token",
        "type": "string"
      },
      {
        "key": "callbackUrl",
        "value": "https://oauth.pstmn.io/v1/callback",
        "type": "string"
      },
      {
        "key": "authUrl",
        "value": "{{baseUrl}}/oauth/authorize?user_id={{userId}}&scope={{scope}}&lng={{lng}}",
        "type": "string"
      },
      {
        "key": "accessTokenUrl",
        "value": "{{baseUrl}}/oauth/token",
        "type": "string"
      },
      {
        "key": "clientId",
        "value": "{{clientId}}",
        "type": "string"
      },
      {
        "key": "clientSecret",
        "value": "{{clientSecret}}",
        "type": "string"
      },
      {
        "key": "scope",
        "value": "{{scope}}",
        "type": "string"
      },
      {
        "key": "grant_type",
        "value": "authorization_code",
        "type": "string"
      },
      {
        "key": "client_authentication",
        "value": "body",
        "type": "string"
      },
      {
        "key": "addTokenTo",
        "value": "header",
        "type": "string"
      }
    ]
  }
}
