Outlook Collection
Outlook Collection Integration with Onna
Overview
This guide explains how to set up and interact with a Microsoft Outlook (eOutlook) collection through the Onna Platform API. You'll learn how to create a workspace and collection, authorize access to Microsoft 365 via OAuth2, list mailboxes and folders, configure sync filters to control exactly which mailboxes and mail folders are synchronized, start the sync, and clean up your environment afterward.
For a full reference of every sync filter field, see the Sync Filters Configuration Guide.
Create a workspace
A workspace is the main container for your project in Onna. Create one with a POST request.
curl --location --request POST 'https://api.onna.com/v1/workspaces' \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{
"name": "My New Workspace",
"description": "This is a workspace for organizing Outlook data in Onna."
}'
Where:
nameis the name of the workspace.descriptionis a brief description of the workspace's purpose.
A successful response (201) will return:
{
"onna_id": "<WORKSPACE_ID>"
}
Create an Outlook Collection
Next, create an Outlook collection within the workspace you created. The collection is the container for the mailboxes and folders you will sync from Microsoft 365.
curl --location --request POST 'https://api.onna.com/v1/collections' \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{
"name": "My Outlook Enterprise Collection",
"onna_parent_id": "<WORKSPACE_ID>",
"type": "office365"
}'
Where:
nameis the name of the collection.onna_parent_idis the ID of the workspace that this collection will belong to.typeis the type of collection being created. For Microsoft Outlook (eOutlook), the type isoffice365.
A successful response (201) will return:
{
"onna_id": "<COLLECTION_ID>",
"type": "office365"
}
You might also want to implement a naming convention (like Collection-{WorkspaceName}-Outlook) for better organization.
Initiate OAuth2 Flow to Get an Authorization Code
To authorize access to the Microsoft 365 tenant, initiate the OAuth2 flow. It will return an authorization URL. Open this URL in your browser to log in and grant the application access.
curl --location --request GET 'https://api.onna.com/v1/collections/authorization_url/OFFICE365?redirect_to=http%3A%2F%2Flocalhost%3A9000%2Fcallback' \
--header 'Authorization: Bearer <token>'
Once you've authorized, you'll be redirected to the provided redirect_to URL with an authorization code.
http://localhost:9000/callback) for easier testing. Be sure to change this to a production-ready URL before going live.Pair the Authorization Code with the Collection (Token Exchange)
After successful authorization, exchange the authorization code for an access token bound to the collection.
curl --location --request POST 'https://api.onna.com/v1/collections/<COLLECTION_ID>/pair_credentials?auth_code=<AUTH_CODE>' \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/x-www-form-urlencoded'
Where:
auth_codeis the authorization code you received during the authorization process.
Retrieve the List of Mailboxes
To retrieve the mailboxes available in the authorized tenant, send a GET request to the collection's /users endpoint. For an Outlook collection, each entry in the response represents a mailbox.
curl --location --request GET 'https://api.onna.com/v1/collections/<COLLECTION_ID>/users' \
--header 'Authorization: Bearer <token>'
Example mailbox response:
{
"entries": [
{
"id": "f8a9c3b1-1234-4abc-9def-0987654321ab",
"display_name": "Lisa Simpson",
"email": "lisa@onnaqa.com",
"mailbox_type": "UserMailbox"
},
{
"id": "d4c7b8e2-5678-4fff-aaaa-1122334455cc",
"display_name": "Bart Simpson",
"email": "bart@onnaqa.com",
"mailbox_type": "UserMailbox"
}
],
"limit": 1000,
"next_marker": "<next_marker>"
}
Where:
idis the unique identifier of the mailbox. Use this value, or theemail, as the filter key when configuring per-user sync filters.emailis the primary SMTP address of the mailbox.mailbox_typedistinguishes user mailboxes from shared or resource mailboxes.
Retrieve the List of Folders for a Mailbox
To retrieve the mail folders (such as Inbox, SentItems, JunkEmail, DeletedItems) for a specific mailbox, send a GET request to the collection's /folders endpoint. Pass the mailbox's user_id as a query parameter.
curl --location --request GET 'https://api.onna.com/v1/collections/<COLLECTION_ID>/folders?user_id=<MAILBOX_ID>' \
--header 'Authorization: Bearer <token>'
Example folder response:
{
"results": [
{
"id": "AAMkADNmZ...Inbox==",
"name": "Inbox",
"parent_folder_id": "AAMkADNmZ...Root==",
"child_folder_count": 2,
"total_item_count": 245,
"unread_item_count": 12
},
{
"id": "AAMkADNmZ...JunkEmail==",
"name": "JunkEmail",
"parent_folder_id": "AAMkADNmZ...Root==",
"child_folder_count": 0,
"total_item_count": 18,
"unread_item_count": 0
}
],
"total_count_label": "2 folders",
"_next": null
}
Where:
idis the folder identifier used inside theexcluded/selectedarrays of amarkersfilter.nameis the folder name (for example,Inbox,SentItems,JunkEmail,DeletedItems).parent_folder_idis the ID of the parent folder, or the root folder ID when at the top level.
Configure Sync Filters
Sync filters control which mailboxes and which mail folders inside those mailboxes get synchronized. Outlook sync filters use two types of keys inside the sync_filters object:
- The
userskey selects which mailboxes to include or exclude from the sync. - A per-mailbox key (the mailbox
idoremail) with amarkersobject selects which mail folders to include or exclude for that mailbox.
Update the collection with the selected configuration by sending a PATCH request.
Sync all mailboxes in the tenant
Use all_selected: true under users to include every mailbox in the authorized tenant.
curl --location --request PATCH 'https://api.onna.com/v1/collections/<COLLECTION_ID>' \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{
"sync_status": "pending",
"sync_filters": {
"users": {
"all_selected": true,
"selected": [],
"excluded": []
}
}
}'
Sync specific mailboxes only
Set all_selected to false and list the mailboxes to include in selected.
curl --location --request PATCH 'https://api.onna.com/v1/collections/<COLLECTION_ID>' \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{
"sync_status": "pending",
"sync_filters": {
"users": {
"all_selected": false,
"selected": [
{ "id": "lisa@onnaqa.com" },
{ "id": "bart@onnaqa.com" }
],
"excluded": []
}
}
}'
Sync specific mailboxes and exclude folders per mailbox
Combine a users entry with per-mailbox markers entries to exclude mail folders such as JunkEmail and DeletedItems on a per-mailbox basis.
curl --location --request PATCH 'https://api.onna.com/v1/collections/<COLLECTION_ID>' \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{
"sync_status": "pending",
"sync_filters": {
"users": {
"all_selected": false,
"selected": [
{ "id": "lisa@onnaqa.com" },
{ "id": "bart@onnaqa.com" }
],
"excluded": []
},
"lisa@onnaqa.com": {
"markers": {
"all_selected": true,
"excluded": [
{ "id": "JunkEmail" },
{ "id": "DeletedItems" }
]
}
},
"bart@onnaqa.com": {
"markers": {
"all_selected": true,
"excluded": [
{ "id": "JunkEmail" },
{ "id": "DeletedItems" }
]
}
}
}
}'
Filter fields
The top-level request fields are the same as any collection update:
| Field | Type | Description |
|---|---|---|
sync_status | String | Sync lifecycle state. Set to "pending" to queue a sync after filters are saved. |
sync_filters | Object | Outlook sync filter configuration (see below). |
type_sync | String | Sync type. Supported values: "one", "arch", "auto". |
The users object inside sync_filters controls mailbox selection:
| Field | Type | Description |
|---|---|---|
all_selected | Boolean | If true, all mailboxes in the tenant are included. When false, the mailboxes listed in selected are included and everything else is skipped. |
selected | Array | Mailboxes to include when all_selected is false. Each entry is { "id": "<mailbox_id_or_email>" }. |
excluded | Array | Mailboxes to exclude when all_selected is true. Each entry is { "id": "<mailbox_id_or_email>" }. |
Each per-mailbox entry uses the mailbox ID (or email) as its key and contains a markers object that controls folder selection for that mailbox:
| Field | Type | Description |
|---|---|---|
markers.all_selected | Boolean | If true, all mail folders are included for the mailbox. |
markers.selected | Array | Folders to include when markers.all_selected is false. Each entry is { "id": "<folder_id_or_name>" }. |
markers.excluded | Array | Folders to exclude when markers.all_selected is true. Common values: JunkEmail, DeletedItems, Drafts. |
A successful PATCH returns 200 OK with no body, indicating the filter configuration was saved.
Update Existing Filters
To change an existing filter configuration (for example, to add a new mailbox or drop an excluded folder),
issue another PATCH to the same collection endpoint with the full updated sync_filters object.
The new value replaces the previous one.
curl --location --request PATCH 'https://api.onna.com/v1/collections/<COLLECTION_ID>' \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{
"sync_status": "pending",
"sync_filters": {
"users": {
"all_selected": false,
"selected": [
{ "id": "lisa@onnaqa.com" },
{ "id": "bart@onnaqa.com" },
{ "id": "homer@onnaqa.com" }
],
"excluded": []
}
}
}'
sync_filters object on update. Fields that are omitted are treated as removed, not merged with the previous value.Start the Sync
Once the filters are saved, initiate the sync process.
curl --location --request POST 'https://api.onna.com/v1/collections/<COLLECTION_ID>/start' \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json'
A successful response (HTTP status code 200) indicates that the sync process has begun. Only the mailboxes and folders allowed by the configured filters are pulled into the collection.
Simulate Token Expiry and Refresh the Token
If the access token expires, you can refresh it by using the refresh token.
curl --location --request POST 'https://api.onna.com/v1/oauth/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'client_id=<client_id>' \
--data-urlencode 'client_secret=<client_secret>' \
--data-urlencode 'grant_type=refresh_token' \
--data-urlencode 'refresh_token=<refresh_token>'
This will return a new access_token and refresh_token.
{
"access_token": "<new_access_token>",
"token_type": "bearer",
"expires_in": 86399
}
Clean Up
Once you are done, you can clean up by deleting both the collection and the workspace.
curl --location --request DELETE 'https://api.onna.com/v1/collections/<COLLECTION_ID>' \
--header 'Authorization: Bearer <token>'
curl --location --request DELETE 'https://api.onna.com/v1/workspaces/<WORKSPACE_ID>' \
--header 'Authorization: Bearer <token>'
Note: Deleting a collection or workspace is permanent and cannot be undone.