# What is Unified Mailbox API?

The Aurinko Unified Mailbox API enables seamless integration with email, calendar, contacts, and task providers like Google and Office 365.

**The Aurinko unified mailbox API** allows developers to quickly build integrations with many mailbox providers and services like Google, Office 365, Outlook.com, MS Exchange. **The unified API** abstracts away differences between many email, calendar, contact, task APIs to make it easy to connect and sync the mailbox data.

**The Aurinko API's** focus is convenient and reliable data synchronization for all supported data categories (email, calendar, contacts, tasks) so the API provides methods to receive changes/deltas and be notified of the changes (through webhooks) in a unified manner. The API's sync/deltas model should allow developers to build reliable event based solutions easily.

**The Aurinko API** is mainly a pass-through platform, proxying all requests directly to data providers, using smart query techniques where necessary (i.e. when providing the same sync/delta model for recurring events or for a hierarchy of email folders). Some control data may be cached on the API servers to provide reliable sync/deltas but the data are limited to Ids, master-instance, thread-message relations and contents of processed emails, events, contacts, tasks are never stored on the Aurinko servers.

When you authenticate an account to Aurinko you get an account access token and can start using the API. Aurinko takes care of keeping its provider connections authorized so you don't have to worry about refreshing tokens.

Also when you start using the sync/deltas methods the Aurinko platform provisions necessary event notification subscriptions to monitor any changes to data in the remote account. Aurinko takes care of renewing the subscriptions and re-creating them when they're lost so the developers don't have to worry about that.

### Quickstart guides

***

* [Email API](/unified-apis/email-api) - Learn how to read data from email inboxes, create and send emails, attach files.
* [Calendar API](/unified-apis/calendar-api) - Learn how to read data from calendars and events, create and modify events, send event notifications.
* [Contacts API](/unified-apis/contacts-api) - Learn how to read data from address books, create and modify contacts.
* [Tasks API](/unified-apis/tasks-api) - Learn how to read data from task lists and manage todos.
* [Webhooks API](/unified-apis/webhooks-api) - Learn how to subscribe to Aurinko push events.


# Getting started with Aurinko

Aurinko enables product teams to quickly build and manage mailbox data sync solutions and integrations through a secure and reliable API platform.

Welcome to Aurinko!

﻿The Aurinko platform aims to help product teams (CRM, ATS, SEP, PM, PRM,...) build mailbox data sync solutions quickly and easily, without the need for specialized API expertise.

With Aurinko developers can accelerate the development of various mailbox (emails, calendars, contacts, tasks) and in-app (Office add-ins, Gmail add-ons, Teams/Slack/Zoom/WebEx apps, ...) integrations as well as create virtual data/api models on top of supported CRM/ERP,PM connectors.

The Aurinko API platform is secure, reliable, and easy to use and maintain.

### Aurinko account setup

***

First, create your account in the [Aurinko portal](https://app.aurinko.io/), then follow the guide to [get your developer API keys](/getting-started/get-your-developer-api-keys).

### Unified Mailbox API

***

Follow our quickstart guides for the Aurinko email, calendar, and contacts APIs.

* [What is Unified Mailbox API?](/)
* [Email API](https://docs.aurinko.io/unified-apis/email-api) - Learn how to read data from email inboxes, create and send emails, and attach files.
* [Calendar API](https://docs.aurinko.io/unified-apis/calendar-api) - Learn how to read data from calendars and events, create and modify events, book appointments, and send event notifications.
* [Contacts API ](https://docs.aurinko.io/unified-apis/contacts-api)- Learn how to read data from address books, and create and modify contacts.
* [Tasks API](https://docs.aurinko.io/unified-apis/tasks-api) - Learn how to work with task lists and tasks.
* [Webhooks API](https://docs.aurinko.io/unified-apis/webhooks-api) - Learn how to subscribe to Aurinko push events.

### Pre-built CRM and PM Sync Logic

***

Aurinko’s prebuilt CRM Sync logic is powered by the [Unified Mailbox API](#unified-mailbox-api) and many years of providing [Yoxel Sync](https://www.yoxel.com/salesforce-sync/) to Salesforce users and white-labeling it to other CRM and PM platforms. With Aurinko’s prebuilt CRM sync logic, businesses can enable their CRM, ATS, and Project Management platforms to sync email, calendars, contacts, and tasks from Outlook and Gmail automatically.﻿

* [What is BrightSync?](https://docs.aurinko.io/brightsync)
* [CRM connector requirements](https://docs.aurinko.io/v/brightsync/readme-1)

{% hint style="info" icon="envelope-open-text" %}
Please contact us at <support@aurinko.io> regarding the white-labeling options.
{% endhint %}

### Workspace Add-Ons

***

Aurinko can serve as a backend API for your Outlook/Gmail addon and Teams/Slack/Zoom/Webex app. Follow our quickstart guides for using Aurinko to accelerate your workplace addon development.

* [Outlook add-ins](https://docs.aurinko.io/v/workspace-addons) - Learn how to use Aurinko as a backend API for these add-ins.
* [Microsoft Teams apps](https://docs.aurinko.io/v/workspace-addons/microsoft-teams-apps) - Learn how to use Aurinko as a backend API for Teams apps with bot functionality.

{% hint style="info" icon="file-lines" %}
You can also white-label our prebuilt addons that, just like the sync logic, are being used by thousands of Salesforce and other CRM users (see [Yoxel Salesforce Addons](https://www.yoxel.com/salesforce-addons/)).&#x20;
{% endhint %}

{% hint style="info" icon="envelope-open-text" %}
Please contact us at <support@aurinko.io> regarding the white-labeling options.
{% endhint %}

#### **Next steps**

[What is Unified Mailbox API ](/)- Learn more details about the Aurinko API platform.

[API Reference](https://apirefs.aurinko.io/) - Our API reference provides all the details you need to know to use Aurinko API.


# Get your developer API keys

Set up your Aurinko developer account, obtain API keys, authenticate a test account, and make your first API request.

Welcome to Aurinko! This step-by-step guide covers how to set up a developer account in the Aurinko portal so that you can make your first request to the Aurinko API.

If you haven't already done so, please sign up or log into the [Aurinko portal](https://app.aurinko.io/) to access your account.

This guide covers the following steps:

1. Get your application API keys
2. Authenticate your first account
3. Make your first request to the Aurinko API

### Get your application API keys

***

One Aurinko application is automatically created for a new user. We recommend using different Aurinko applications to separate users across your development, staging, and production environments, but for the purposes of this guide use the automatically created one.

On the new application's dashboard page you will find the Client ID and secret. These values will be necessary when you're ready to work with accounts that are authenticated to your app.The client ID and secret are highlighted.

<figure><img src="/files/CjYaQSYECIFLZ0DjDP28" alt=""><figcaption></figcaption></figure>

### Authenticate your test account

***

For production use have to complete the todo's listed on your dashboard page but for now you can open the 'Add a test account' todo and click a link there. You will be presented wit the following dialog:

<figure><img src="/files/wLfydYOE9KAqu8adLRIE" alt=""><figcaption></figcaption></figure>

Select an account type (Google, Office 365, MS Exchange) and scopes for Calendar, Mail, Contacts. Then click AUTH.

{% hint style="info" %}
**Note:** that until you have configured your own Google and Office 365 authentication flows (see dashboard todo's) Aurinko's default app registrations with limited permissions are used (i.e. Google email is not available).
{% endhint %}

Once you have authenticated, you will see the Accounts page for your app. The new account record should be opened for you. Copy the provided token (click the little eye icon) and store it somewhere safe; you will need it to make your first requests to the [Aurinko API](https://apirefs.aurinko.io/).

<div data-full-width="true"><figure><img src="/files/9LUHc1GLjcTdwlZtmcTT" alt=""><figcaption></figcaption></figure></div>

{% hint style="info" %}
**Note:** this token should only be used for development purposes.&#x20;
{% endhint %}

### Make Your First Request

***

Now that you have your first account connected, it's time to make your very first request to the [Aurinko API](https://apirefs.aurinko.io/)! Open the nearest terminal and type in the following command, replacing  <mark style="color:red;">`{access_token}`</mark> with the token you saved from the previous section.

```bash
curl -X GET -H 'Authorization: Bearer {access_token}'
    https:/api.aurinko.io/v1/account
```

If everything is setup properly, you should see a response similar to the following example.

```json
{
    "id":33,
    "serviceType":"Google",
    "status":"active",
    "daemon":false,
    "loginString":"",
    "email":"",
    "name":"Demo User",
    "authUserId":"...",
    "authOrgId":"yoxel.com",
    "authScopes":["Calendar.ReadWrite"],
    "tokenIssuedAt":"2019-12-27T19:43:14.187630Z",
    "authObtainedAt":"2019-12-27T19:43:14.187639Z",
    "authExpiresAt":"2019-12-27T20:43:14.179830Z"
}
```

**Congrats! You're now connected to the Aurinko APIs!**


# Adding Aurinko to Google Workspace allowlist

Add Aurinko to your Google Workspace allowlist to trial the Email API.

This setup is for new Aurinko users planning to trial the [Email API](https://docs.aurinko.io/unified-mailbox-api/email-api) using their Google Workspace accounts.

If you already have your Google-verified app you don't have to follow these instructions; simply enter your client id and secret in the Aurinko app settings:<br>

<div data-full-width="true"><figure><img src="/files/7tDcvXHULOTuE8Vq22nA" alt=""><figcaption></figcaption></figure></div>

For trials with the default Aurinko app id please follow the following steps:

1. **Login to the Admin Console of your Google Workspace**

You must be signed in as a [super administrator](https://support.google.com/a/answer/2405986#super_admin) of your Google Workspace to complete the actions listed below.

<div data-full-width="true"><figure><img src="/files/vs4Ky66nOaC6VSdxcT5C" alt=""><figcaption></figcaption></figure></div>

2. **Navigate to the API controls in Security Settings**

From the Admin console home, go to **Security > API Controls**. This might be located at the bottom of the page.

<div data-full-width="true"><figure><img src="/files/ZVRtgiGzEOcAH6ZIT6zx" alt=""><figcaption></figcaption></figure></div>

3. **Navigate to Manager Third-Party App Access**

<div data-full-width="true"><figure><img src="/files/fg2Fz8Fkqt9gn7hzOGva" alt=""><figcaption></figcaption></figure></div>

4. **Select "Add app" and "OAuth App Name Or Client ID" in the dropdown.**

<div data-full-width="true"><figure><img src="/files/5Dh7jPc9weIoGPoodb74" alt=""><figcaption></figcaption></figure></div>

5. **Fill in the OAuth 2.0 Client ID for the Aurinko app:**

```
52020407124-5htuk1bfpsddj5k8eaa679kaa7vo0fm6.apps.googleusercontent.com
```

select the Aurinko app:

<div data-full-width="true"><figure><img src="/files/wDtYTxClD0DT0hRMnt7n" alt=""><figcaption></figcaption></figure></div>

and the available OAuth client ID:

<div data-full-width="true"><figure><img src="/files/XRQWmJnrYa5ljZsmuVIe" alt=""><figcaption></figcaption></figure></div>

Then, select scope '**All users'**

<div data-full-width="true"><figure><img src="/files/qDG54fwrjvzHWwWar29O" alt=""><figcaption></figcaption></figure></div>

then, **"Trusted"** option for app access.

<div data-full-width="true"><figure><img src="/files/6RvmtTWI1zuz0fEo8GDt" alt=""><figcaption></figcaption></figure></div>

**Confirm!**

**Now, you can start adding accounts of your Google Workspace domain in Aurinko.**


# Bubble.io plugin

Integrate your Bubble apps with users' email accounts through Aurinko's Unified Mailbox API to access their email and calendars.

\
Integrate your Bubble apps with users' Gmail, Office 365, Outlook.com, hosted MS Exchange, Zoho Mail, and IMAP accounts through Aurinko's Unified Mailbox API.\
\
[The Aurinko plugin](https://bubble.io/plugin/aurinko---unified-mailbox-api-1692218886639x102948326219710460) allows your app to access users' email and calendars. Future versions can add access to contacts, tasks, and a number of CRM APIs.

### Setting up

***

\
1\. Signup for an Aurinko account, to get your **APP\_CLIENT\_ID** and **APP\_CLIENT\_SECRET**\
[Get your developer API keys](/getting-started/get-your-developer-api-keys)

\
2\. Add the [Aurinko API plugin](https://bubble.io/plugin/aurinko---unified-mailbox-api-1692218886639x102948326219710460) to your Bubble application. Enter your **APP\_CLIENT\_ID** and **APP\_CLIENT\_SECRET** keys. For APP\_API\_DOMAIN specify 'api.aurinko.io'. (Ask us about configuring a custom domain alias.)

<div data-full-width="true"><figure><img src="/files/AsTiZZy6TBNBu0oybnS6" alt=""><figcaption></figcaption></figure></div>

### OAuth Flow

***

3\. You need to have OAuth clientId and clientSecret from Google, Microsoft, Zoho to be able to use Aurinko's [OAuth Flow](/authentication/oauth-flow) in production. See how to register your apps: [Google OAuth setup](/authentication/google-oauth-setup), [Office 365 OAuth setup](/authentication/office-365-oauth-setup).\
But for testing during your trial you can use Aurinko's OAuth clientId and clientSecret. For Gmail you'll have to allow-list Aurinko: [Adding Aurinko to Google Workspace allowlist](https://docs.aurinko.io/getting-started/adding-aurinko-to-google-workspace-allowlist).

#### **Redirect URI: Redirect page vs. Custom domain alias**

Google app registrations allow only authorized redirect URIs under a domain you own so the default Aurinko's Redirect URI <https://api.aurinko.io/v1/auth/callback> won't work for you in production.

<div data-full-width="true"><figure><img src="/files/onGmdB2jbJohg6SshPp7" alt=""><figcaption></figcaption></figure></div>

You have two options:

* Contact us about provisioning a domain alias for your Aurinko app so your could use a url like <https://aurinko.mydomain/v1/auth/callback>
* Provision an aurinko\_redirect page in Bubble and use it for redirecting all calls to Aurinko's <https://api.aurinko.io/v1/auth/callback> with the url parameters <mark style="color:red;">`state`</mark>, <mark style="color:red;">`code`</mark>, and <mark style="color:red;">`scope`</mark>.

<div data-full-width="true"><figure><img src="/files/fvqBv9ofeyTYhsfDiQWm" alt=""><figcaption></figcaption></figure></div>

In your Aurinko app settings insert the url of your aurinko\_redirect page, and specify the url as an Authorized redirect URI in your Google app registration.

\
4\. To start accessing email or calendar data you need to get a user authorization to access a remote account. Use the plugin's **'Get OAuth Url (Mailbox)'** action to generate a required OAuth request url and the **'Open External Website'** action with it.

<div data-full-width="true"><figure><img src="/files/yCBoaxUvXHn2KI0LOrd9" alt=""><figcaption></figcaption></figure></div>

#### **Callback page (return\_url)**

Provision a callback page that will receive an Aurinko account token. All API calls require **Bearer Auth** with the account token.

* For *'response\_type=code' -* Use the plugin's **'Get Token for Code'** action to exchange the auth code for an account token. If you Save the token in your database.
* For *'response\_type=token'* - Extract the token from the url parameter 'token' and remove it from the URL fragment with JavaScript.

<div data-full-width="true"><figure><img src="/files/uW8od3usHhDmfECvFNHb" alt=""><figcaption></figcaption></figure></div>

\
5\. Once your app has obtained account tokens it can start calling the API actions, or attaching the API as a data source, just insert the token (prefixed with 'Bearer ') into the **'Authorization:'** header.

<div data-full-width="true"><figure><img src="/files/ImQ98yNpO3g4ClcuqoVD" alt=""><figcaption></figcaption></figure></div>

\
6\. The following API methods have been defined in the plugin. Also see the full [API reference](https://apirefs.aurinko.io/).

<div data-full-width="true"><figure><img src="/files/3UOaBAPTXX6KGMeVEjs9" alt=""><figcaption></figcaption></figure></div>


# Subscribe to Aurinko

When your **14-day trial** expires, your API access is automatically disabled. To continue using Aurinko, you'll need to subscribe to a paid plan.

### Open Billing

***

1. Sign in to the Aurinko Portal.
2. Open your **Team Settings**, then click **Billing** in the left navigation menu.
3. Click **Add new card**.

<figure><img src="/files/FX9rWQM5qgLkktG0oLSn" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/Iepp66BppXTVcCzDo6Uv" alt=""><figcaption></figcaption></figure>

If your trial has expired, the Portal displays a **Payment required** message in your team. Click **Add credit card** in your application to go directly to the **Billing** page.

<figure><img src="/files/mRRvBqkVZ7yl8D0qGr8V" alt=""><figcaption></figcaption></figure>

### Add your payment method

***

Enter your payment card details and save the payment method.

<figure><img src="/files/KvH1lOXsirjB0V6jDv3G" alt=""><figcaption></figcaption></figure>

Once you've added a payment method, your subscription becomes active and billing is based on the APIs your team uses.

<figure><img src="/files/5aIDAtmmWpsm7Rda2pWZ" alt=""><figcaption></figcaption></figure>

### What happens when your trial ends?

***

Aurinko includes a **14-day free trial**. During this period, you have full access to the API.

If you do not subscribe before the trial expires:

* API requests are blocked.
* Existing integrations stop working.
* The Portal displays a **Subscription Required** message until a subscription is activated.

To help you avoid service interruption, Aurinko sends reminder emails:

* **3 days** before your trial expires.
* **1 day** before your trial expires.
* **On the day** your trial expires.

Once you activate a subscription, API access is restored automatically.


# Sign up for the Aurinko Portal

To start using Aurinko, sign up for the Aurinko Portal. You can register with your email address or use your Google account.

### Sign up with your email

***

1. Open the Aurinko Portal.
2. On the Log in page, click **Don't have an account?**
3. On the **Sign up** page, enter your name, email address, and password.
4. Complete the CAPTCHA verification.
5. Click **Sign Up**.

<figure><img src="/files/r1uLCU21QefoSP1dlGRY" alt=""><figcaption></figcaption></figure>

### Verify your email address

***

After signing up, Aurinko sends a verification email to the email address you provided.

1. Open the email.
2. Click the verification link.

<figure><img src="/files/YaQYCEZpxhCySMU4KAsN" alt=""><figcaption></figcaption></figure>

You can sign in before verifying your email, but some Portal features remain unavailable until your email address has been verified.

### Sign up with Google

***

Instead of creating an account with an email address and password, you can click **Sign up with Google** and complete the Google sign-in flow.

After signing in with Google, you'll be taken to the **Confirm Registration** page. Your **Name** and **Email** are filled in automatically. Enter a **Team Name**, then click **Confirm** to complete your registration.

{% hint style="info" %}
**Note:** If you've already registered with Google, continue signing in with **Sign in with Google**.
{% endhint %}

<figure><img src="/files/77UESe2bxuCNMCipXguJ" alt=""><figcaption></figcaption></figure>

### Verify your app configuration

***

Before using Aurinko in production, make sure your app is fully configured:

* **Fill out app description and brand details**: This includes your logo and color scheme.
* **Enter your own OAuth app registration details**: This will make sure your OAuth flows open appropriate consent screens.
* **Specify trusted domains**: This will allow your frontend applications to access the Aurinko API securely.

These settings are available in your **app's Settings**.

Your app includes a **14-day free trial**. After the trial expires, an active subscription is required to continue using the API. See [**Subscribe to Aurinko**](https://docs.aurinko.io/getting-started/subscribe-to-aurinko) for instructions on adding a payment method and activating your subscription.

<figure><img src="/files/QXeA1vwFAlOaD2pGOrE0" alt=""><figcaption></figcaption></figure>


# Team members and roles in applications

The Aurinko portal offers four distinct roles for team members, each with specific permissions. The following roles are available for Team members:

* **Collaborator**
* **Developer**
* **Administrator**
* **Owner**

### Collaborator

***

**The collaborator has read-only access to all basic entities of the applications available to him, such as:**

* client id;
* accounts;
* end users;
* organizations.

### Developer

***

**The developer has read-write access to all entities listed in the collaborator’s permissions. In addition, the developer can:**

* view information about the “client secret” and the “signing secret” of the applications;
* view and edit Virtual API entities provided in the Aurinko portal;
* view and edit configurations required for the development of integrations, provided on the Settings page, such as trusted domains, callbacks, and app registrations.

### Administrator

***

**The administrator has all permissions listed in the developer’s role description. In addition, the administrator can:**

* always access all team applications;
* deny/allow collaborators’ and developers’ access to the team applications;
* invite team members, see and delete pending invitations;
* change members’ roles and remove them from the team;
* update team details (e.g. name);
* create and delete applications, edit applications’ details (e. g. name, description, logo);
* re-generate application’s “signing secret”;
* view and edit all billing related information.

### Owner

***

**The owner has all the same permissions as the administrator and can transfer his role to any other team member.**

#### To transfer ownership:

***

1. Go to the **Team** page in the Aurinko portal.
2. Locate the team member you want to assign as the new owner.
3. Use the role or actions menu next to that member.
4. Select the option to transfer ownership and confirm the change.

{% hint style="info" %}
**Note:** Only the current owner can transfer ownership, and the new owner must already be a member of the team.
{% endhint %}

<figure><img src="/files/ubRazP2PR8tWQnXH1yoP" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/448oBGCyqZJehD6tG3iL" alt=""><figcaption></figcaption></figure>


# Delete your profile and cancel your subscription

This article explains how to permanently delete your profile from the Aurinko Portal. Before you can delete your profile, you must first delete or transfer ownership of any teams you own. Deleting a team permanently removes all associated applications, connected accounts, and the team's subscription.

### Step 1. Delete or transfer ownership of your teams

***

If you own one or more teams, you must either:

* Delete the team, or
* Transfer ownership to another user.

{% hint style="info" %}
**Note:** You can read more here: [To transfer ownership](https://docs.aurinko.io/team-members-and-roles-in-applications#owner).
{% endhint %}

To delete a team:

1. Open your team **Settings**.
2. Click **Delete team**.
3. Type **delete** to confirm.
4. Click **Delete**.

<figure><img src="/files/pEF028JIb6RzDDMczM1U" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/ksHNTSxLbQ0ewzBZHpGb" alt=""><figcaption></figcaption></figure>

{% hint style="warning" %}
**Note:** Deleting a team is irreversible. All connected applications, linked accounts, subscriptions, and other associated resources are permanently deleted.
{% endhint %}

Repeat these steps until you no longer own any teams.

After all teams are deleted or transferred, your subscription is automatically cancelled. All associated billing information, including saved payment methods, is also removed.

### Step 2. Delete your profile

***

Once you no longer own any teams:

1. Open your **Profile**.
2. Click **Delete profile**.
3. Confirm the deletion:
   * If you signed up with an email address and password, enter your password.
   * If you signed up with Google, type **delete** to confirm.
4. Click **Delete**.

<figure><img src="/files/4l563ZWEA1au74BXeWZ9" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/EZQ5yvJstazgiQOOO9oo" alt=""><figcaption></figcaption></figure>

{% hint style="warning" %}
**Note:** Deleting your profile is irreversible. If you delete this profile, you will be logged out and removed from all connected teams.
{% endhint %}


# Email API

Aurinko's Email API provides a RESTful interface for accessing and syncing email messages across popular providers like Gmail, Office 365, iCloud, etc.

## Aurinko Email API

***

The Aurinko Email API abstracts away differences between popular email APIs (Gmail, Office 365, Outlook.com, MS Exchange, Zoho Mail, iCloud, IMAP) to make it easy to develop email integrations.

### Functionality

***

The Aurinko Email API provides a REST interface that focuses on accessing and syncing email messages in a uniform manner.

* Access data for email messages, such as email content, sender and recipient information, subject lines, dates, and more.
* Search email inboxes for specific content.
* Update the unread and flagged status of email messages.
* Manage and download file attachments.
* Create drafts and send emails.
* Incremental synchronization.

### Aurinko account setup

***

First, create your account in the [Aurinko portal](https://app.aurinko.io/), then follow the guide to [get your developer API keys](https://docs.aurinko.io/getting-started/get-your-developer-api-keys). To test with Google Workspace accounts review this article: [Adding Aurinko to Google Workspace allowlist](https://docs.aurinko.io/getting-started/adding-aurinko-to-google-workspace-allowlist).

### Email API Endpoints

***

#### **Email messages**

[Email messages](https://apirefs.aurinko.io/#tag/Messages) are the core building block for most email applications. They contain several pieces of information, such as when a message was sent, the sender's address, to whom it was sent, and the message body. They can also contain file attachments, calendar event invitations, and more.

#### **Synchronization**

[Email sync](https://apirefs.aurinko.io/#tag/EmailSync) methods allow developers to implement incremental synchronization of email messages in a uniform manner across different email providers. Aurinko supports requesting updated as well as deleted messages.

#### **Draft messages**

[Draft messages](https://apirefs.aurinko.io/#tag/Drafts) methods allow developers to create new drafts, read existing drafts, and send drafts.

#### **Email tracking**

[Email tracking](https://apirefs.aurinko.io/#tag/EmailTracking) methods allow developers to access and manage open and reply/bounce tracking data.

### Email sync quickstart

***

#### **Start a new sync**

A new sync needs to be provisioned by calling the "sync start" method <mark style="color:red;">`/messages/sync`</mark>. The sync covers all email folders (i.e. Inbox, Sent Mail, and sub folders). <mark style="color:red;">`daysWithin`</mark> limits the initial scan to emails received in the past <mark style="color:red;">`daysWithin`</mark> days.

```bash
curl -X POST -H 'Authorization: Bearer <account\_access\_token>'
    -G https:/api.aurinko.io/v1/email/sync[?awaitReady=false]
    -d daysWithin=10"
```

The Aurinko platform will initialize all necessary internal resources and let you know when it's ready to serve data. The response should look like this:

```json
{
    "syncUpdatedToken": "asdfghjklpoiuytrew",
    "syncDeletedToken": "zxcvbnmlkjhgfdsaq",
    "ready": true
}
```

If the response shows <mark style="color:red;">`ready: false`</mark> call the "sync start" method again. Once the sync is ready you will get delta tokens <mark style="color:red;">`syncUpdatedToken`</mark>, <mark style="color:red;">`syncDeletedToken`</mark> and can start loading updated and deleted email messages.

#### **Initial full sync**

Initial requests <mark style="color:red;">`/messages/sync/updated`</mark> and <mark style="color:red;">`/messages/sync/deleted`</mark> are equivalent to a full sync in the specified <mark style="color:red;">`timeMin`</mark>,<mark style="color:red;">`NOW`</mark> range, plus loading all updated messages (deleted messages) since the sync start.

```bash
curl -X GET -H 'Authorization: Bearer <access token>'
    -G https:/api.aurinko.io/v1/email/sync/updated
    -d deltaToken='{syncUpdatedToken}'
```

*Response:*

```json
{   
    "nextPageToken": "string",
    "nextDeltaToken": "string",
    "records": [{...}]
}
```

Continue loading pages using provided 'nextPageToken' until you find another 'nextDeltaToken'.

```bash
curl -X GET -H 'Authorization: Bearer <access token>'
    -G https:/api.aurinko.io/v1/email/sync/updated
    -d pageToken='{nextPageToken}'
```

#### **Incremental sync**

A new deltaToken (nextDeltaToken in a response) is provided for loading email messages that have been modified/deleted since the last sync-updated/sync-deleted request. In cases where a large number of messages have changed since the last incremental sync request, you may find a <mark style="color:red;">`nextPageToken`</mark> instead of the <mark style="color:red;">`nextDeltaToken`</mark> in the response. Continue loading pages using the provided <mark style="color:red;">`nextPageToken`</mark> until you find another <mark style="color:red;">`nextDeltaToken`</mark>.

### Other examples

***

#### Email Messages <a href="#email-messages" id="email-messages"></a>

To get a list of messages from, to, or cc'ing an email address, make a request to the <mark style="color:red;">`/email/messages`</mark> endpoint.

```bash
curl -X GET -H 'Authorization: Bearer <access token>'
    -G https:/api.aurinko.io/v1/email/messages
    -d q="text from:alexey"
```

To get an email message by id make a request to the <mark style="color:red;">`/email/messages/{id}`</mark> endpoint.

```bash
curl -X GET -H 'Authorization: Bearer <access token>'
    https:/api.aurinko.io/v1/email/messages/{id}
```

#### Email Tracking Options <a href="#email-tracking-options" id="email-tracking-options"></a>

***

To enable email tracking, include the <mark style="color:red;">`tracking`</mark> object in the request body when sending a message via the <mark style="color:red;">`/email/messages`</mark> endpoint.

Tracking supports:

* **opens** — tracks when the recipient opens the email
* **threadReplies** — tracks replies within the same email thread
* **trackOpensAfterSendDelay** — delay in seconds before enabling opens tracking (default: 5)
* **context** — optional custom string returned in tracking events, useful for correlating emails with external entities
* **customDomainAlias** — optional custom domain for the tracking pixel URL (default: Aurinko’s domain)

When sending an email with HTML content and requiring returned message IDs, use the following endpoint and query parameters:

```
POST https://api.aurinko.io/v1/email/messages?bodyType=html
```

Example request with tracking enabled:

```bash
curl -H 'Authorization: Bearer <access token>'
    -X POST https:/api.aurinko.io/v1/email/messages?bodyType=html
    -d '{
      "subject": "re: product proposal",
      "tracking": {
          "opens": true,
          "threadReplies": true,
          "trackOpensAfterSendDelay": 10,
          "context": "Something I want to associate with this email",
          "customDomainAlias": "tracking.company.com"
      },
      "body": "Hello there!",
      "to": [
           {
               "address": "demo@aurinko.io"
           }
      ]
    }'
```

#### Search Email Messages using q <a href="#search-email-messages" id="search-email-messages"></a>

***

In the Aurinko API, you can filter email messages using the <mark style="color:red;">`q`</mark> query parameter. This parameter supports various search operators, allowing you to find messages by sender, recipient, subject, date, and other criteria. To use it, make a request to the <mark style="color:red;">`/email/messages`</mark> endpoint.\
Support may vary depending on the account type (Office365, Gmail, IMAP or EWS).

**Example request:**

```
GET https://asti.aurinko.io/v1/email/messages?q=from:user
```

The following query operators are supported in Aurinko:

| Operator        | Example                             | Description                                                       | Comments                                                                      |
| --------------- | ----------------------------------- | ----------------------------------------------------------------- | ----------------------------------------------------------------------------- |
| `from:`         | `from:user`                         | Messages from a specific sender.                                  |                                                                               |
| `to:`           | `to:demo@aurinko.io`                | Messages sent to a recipient.                                     |                                                                               |
| `cc:`           | `cc:user@aurinko.io`                | Messages where recipient is in CC.                                |                                                                               |
| `bcc:`          | `bcc:user@aurinko.io`               | Messages where recipient is in BCC.                               |                                                                               |
| `subject:`      | `subject:test`                      | Search by subject text.                                           |                                                                               |
| text search     | `test email`                        | Search for messages containing specific words in subject or body. |                                                                               |
| `after:`        | `after:2025/06/15`                  | Messages sent after a specific date.                              | Partially supported — may depend on server type; IMAP/EWS support is limited. |
| `before:`       | `before:2025/06/15`                 | Messages sent before a specific date.                             | Partially supported — may depend on server type; IMAP/EWS support is limited. |
| `label:`        | `label:inbox`                       | Search by label.                                                  | Gmail only; not supported for IMAP/EWS.                                       |
| `rfc822msgid:`  | `rfc822msgid:200503292@example.com` | Search by internet message ID.                                    | Fully supported where message ID is available.                                |
| `recipients:`   | `recipients:demo@aurinko.io`        | Search by any recipient (To/Cc/Bcc).                              |                                                                               |
| `participants:` | `participants:user@aurinko.io`      | Search messages involving a participant.                          |                                                                               |
| `classifier:`   | `classifier:important`              | Custom message classifier.                                        | Supported where classifier is applied.                                        |
| `has:`          | `has:attachment`                    | Filter messages that have attachments or other elements.          | Fully supported where metadata is available.                                  |
| `is:`           | `is:read` / `is:unread`             | Filter by message status.                                         | Fully supported; in Office365 and EWS, use `-is:read` for unread messages.    |
| `larger:`       | `larger:10M`                        | Messages larger than specified size.                              | Supported; requires numeric value with optional unit.                         |
| `smaller:`      | `smaller:1M`                        | Messages smaller than specified size.                             | Supported; requires numeric value with optional unit.                         |


# Calendar API

Aurinko's Calendar API offers a unified REST interface for managing calendars across Google, Outlook, iCloud, etc. Access events, data sync, and simplify scheduling workflows.

## Aurinko Calendar API

***

The Aurinko Calendar API is part of the Aurinko Unified API platform, enabling developers to integrate calendar functionalities effortlessly into their applications. This API abstracts the differences between calendar management services such as Google, Outlook, iCloud Calendar, offering a consistent interface for calendar-related operations.

### Functionality

***

The Aurinko Calendar API provides a REST interface that focuses on accessing and syncing calendars uniformly.

* Access data for calendars and events, such as event titles, location, description, dates, ...
* Full CRUD (create, read, update, delete) capabilities.
* Incremental synchronization

### Aurinko account setup

***

First, create your account in the [Aurinko portal](https://app.aurinko.io/), then follow the guide to [get your developer API keys](https://docs.aurinko.io/getting-started/get-your-developer-api-keys).

### Calendar API Endpoints

***

#### Calendars

Each account connected to Aurinko can have zero or more [calendars](https://apirefs.aurinko.io/#tag/Calendars), and each calendar contains a collection of individual events. Accounts can have many calendars including a primary calendar, secondary calendars, read access calendars, and shared team calendars.

#### Events

[Events](https://apirefs.aurinko.io/#tag/Events) are objects within a calendar that generally support all features and attributes of modern scheduling apps like event names, list of participants, descriptions, location, time, etc. Aurinko supports key event functionality, including sending email invites, response status checks and notifications, creating and modifying events, and recurring events.

#### Synchronization

[Calendar sync](https://apirefs.aurinko.io/#tag/CalSync) methods allow developers to implement incremental synchronization of calendar data in a uniform manner across different calendar providers. Aurinko supports requesting updated as well as deleted calendar events, reporting series master and exceptions, auto-expanding a sync range.

#### Free/busy schedule

[Free/busy schedule](https://apirefs.aurinko.io/#tag/FreeBusySchedule) methods allow developers to check free/busy status for a calendar or available time slots for a meeting.

#### **Booking profiles**

[Booking profiles](https://apirefs.aurinko.io/#tag/Booking) methods allow developers to build calendar availability and meeting scheduling apps. List, create, update, and delete booking profiles associated with a user calendar. See meeting time availability according to a booking profile configuration.

### Calendar sync quickstart

***

**Start a new sync**

A new sync needs to be provisioned by calling the *sync-start* method <mark style="color:red;">`/calendars/{calendarId}/sync`</mark> The sync is available per calendar, hence {calendarId} or *primary*. <mark style="color:red;">`timeMin`</mark> and <mark style="color:red;">`timeMax`</mark> specify a time range for the initial full load.

```bash
curl -X POST -H 'Authorization: Bearer <account_access_token>'
    -G https:/api.aurinko.io/v1/calendars/primary/sync[?awaitReady=false]
        -d timeMin=2019-06-03T10:00:00-07:00
        -d timeMax=2020-06-03T10:00:00-07:00
```

The Aurinko platform will initialize all necessary internal resources and let you know when it's ready to serve data. The response should look like this:

```json
{
    "syncUpdatedToken": "asdfghjklpoiuytrew",
    "syncDeletedToken": "zxcvbnmlkjhgfdsaq",
    "ready": true
}
```

If the response shows <mark style="color:red;">`ready: false`</mark> call the *sync-start* method again. Once the sync is ready you will get delta tokens <mark style="color:red;">`syncUpdatedToken`</mark>, <mark style="color:red;">`syncDeletedToken`</mark> and can start loading updated and deleted events.

#### Initial full sync

Initial requests <mark style="color:red;">`/calendars/{calendarId}/sync/updated`</mark> and <mark style="color:red;">`/calendars/{calendarId}/sync/deleted`</mark> are equivalent to a full sync in the specified <mark style="color:red;">`timeMin`</mark>, <mark style="color:red;">`timeMax`</mark> range, plus loading all updated events (deleted events) since the sync start.

```bash
curl -X GET -H 'Authorization: Bearer <access_token>'
    -G https:/api.aurinko.io/v1/calendars/primary/sync/updated
    -d deltaToken='{syncUpdatedToken}'
```

*Response:*

```json
{
    "nextPageToken": "string",
    "nextDeltaToken": "string",
    "records": [{...}]
}
```

Continue loading pages using provided <mark style="color:red;">`nextPageToken`</mark> until you find another <mark style="color:red;">`nextDeltaToken`</mark>.

```bash
curl -X GET -H 'Authorization: Bearer <access_token>'
    -G https:/api.aurinko.io/v1/calendars/primary/sync/updated
    -d pageToken='{nextPageToken}'
```

#### Incremental sync

A new deltaToken (nextDeltaToken in response) is provided for loading calendar events that have been modified/deleted since the last *sync-updated/sync-deleted* request. In cases where a large number of events have changed since the last incremental sync request, you may find a <mark style="color:red;">`nextPageToken`</mark> instead of the <mark style="color:red;">`nextDeltaToken`</mark> in the response. Continue loading pages using the provided <mark style="color:red;">`nextPageToken`</mark> until you find another <mark style="color:red;">`nextDeltaToken`</mark>.

### Other examples

***

#### Calendars

To view a list of all calendars a user has access to, make a request to the <mark style="color:red;">`/calendars`</mark> endpoint.

```bash
curl -H 'Authorization: Bearer <access_token>'
    -X GET https:/api.aurinko.io/v1/calendars
```

You can get information for a single calendar by providing the appropriate calendar id, <mark style="color:red;">`/calendars/{id}`</mark>. You can use *primary* as an ID to get your primary calendar.

```bash
curl -H 'Authorization: Bearer <access_token>'
    -X GET https:/api.aurinko.io/v1/calendars/primary
```

#### Calendar events

To get a list of events from a calendar, make a request to the <mark style="color:red;">`/calendars/{id}/events`</mark> endpoint.

```bash
curl -X POST -H 'Authorization: Bearer <access_token>'
    -G https:/api.aurinko.io/v1/calendars/primary/events/range
    -d timeMin=2019-06-03T10:00:00-07:00
    -d timeMax=2020-06-03T10:00:00-07:00
```

To create a new meeting POST json payload to <mark style="color:red;">`/calendars/{id}/events`</mark> endpoint:

```bash
curl -H 'Authorization: Bearer <access_token>'
    -X POST https:/api.aurinko.io/v1/calendars/primary/events
    -d '{
    "subject": "Business lunch",
    "location": "Our favorite cafe",
    "start": {
        "dateTime": "2020-02-04T10:00:00Z",
        "timezone": "America/Los_Angeles"
    },
    "end": {
        "dateTime": "2020-02-04T11:00:00Z",
        "timezone": "America/Los_Angeles"
    },
    "meetingInfo": {
        "attendees": [
            {
                "emailAddress": {"address": "[partner@example.com],
                "type": "required"
            }
        ]
    }
}'
```

Use PATCH request to update existing events and notify meeting attendees of changes:

```bash
curl -X POST -H 'Authorization: Bearer <access_token>'
    https:/api.aurinko.io/v1/calendars/primary/events/{eventId}?notifyAttendees=true
    -d '{
    "subject": "Business lunch",
    "location": "Another cool place",
    "start": {
        "dateTime": "2020-02-05T10:00:00Z",
        "timezone": "America/Los_Angeles"
    },
    "end": {
        "dateTime": "2020-02-05T11:00:00Z",
        "timezone": "America/Los_Angeles"
    },
    "meetingInfo": {
        "attendees": [
            {
                "emailAddress": {"address": "[partner@example.com],
                "type": "required"
            }
        ]
    }
}'
```

#### Query parameters

<table><thead><tr><th width="156.5078125">Name</th><th width="95.5703125">Type</th><th width="101.9296875">Default</th><th>Description</th></tr></thead><tbody><tr><td><code>notifyAttendees</code></td><td><code>boolean</code></td><td><code>true</code></td><td><p>Indicates whether to send event invitations or updates to attendees. Set to <code>false</code> to create or update an event silently, without sending notifications.</p><p><strong>Supported by:</strong> Google, Clio.</p></td></tr><tr><td><code>bodyType</code></td><td><code>string</code></td><td>—</td><td><p>Defines the format of the event description. Possible values:</p><p>- <code>html</code> — event description is formatted as HTML.</p><p>- <code>text</code> — event description is plain text.</p></td></tr><tr><td><code>returnRecord</code></td><td><code>boolean</code></td><td><code>true</code></td><td>Determines whether the response should include the full event record after creation. If <code>false</code>, the API will return only the event ID. Setting this to <code>true</code> may result in an additional request to the provider API to fetch the full record.</td></tr></tbody></table>


# Contacts API

Aurinko's Contacts API offers a RESTful interface for syncing contacts from Google, Office 365, etc., with features like CRUD operations, incremental sync, and detailed access.

## Aurinko Contacts API

***

The Aurinko Contacts API abstracts away differences between popular contacts APIs (Google, Office 365, Outlook.com, MS Exchange) to make it easy to develop calendar integrations.

### Functionality

***

The Aurinko Contacts API provides a REST interface that focuses on accessing and address books in a uniform manner.

* Access data for contacts, such as event titles, location, description, dates, ...
* Full CRUD (create, read, update, delete) capabilities.
* Incremental synchronization
* Read data for a user’s contacts including name, email, phone number, notes, and more.
* Create new contacts and modify existing contacts.

### Aurinko account setup

***

First, create your account in the [Aurinko portal](https://app.aurinko.io/), then follow the guide to [get Your Developer API Keys](https://docs.aurinko.io/getting-started/get-your-developer-api-keys).

### Contacts API Endpoints

***

#### **Contacts**

[Contacts](https://apirefs.aurinko.io/#tag/Contacts) are objects within an address. Aurinko supports key contacts functionality, making it easy to add address book integrations.

#### **Synchronization**

[Contacts sync](https://apirefs.aurinko.io/#tag/ContSync) methods allow developers to implement incremental synchronization of contacts data in a uniform manner across different address providers. Aurinko supports requesting updated as well as deleted calendar events, reporting series master and exceptions, auto expanding a sync range.

### Contacts sync quickstart

***

#### **Start a new sync**

A new sync needs to be provisioned by calling the "sync start" method <mark style="color:red;">`/contacts/sync`</mark>.

<pre class="language-bash"><code class="lang-bash">curl -X POST -H 'Authorization: Bearer &#x3C;account\_access\_token>'
<strong>    -G https:/api.aurinko.io/v1/contacts/sync[?awaitReady=false]
</strong></code></pre>

The Aurinko platform will initialize all necessary internal resources and let you know when it's ready to serve data. The response should look like this:

```json
{
    "syncUpdatedToken": "asdfghjklpoiuytrew",
    "syncDeletedToken": "zxcvbnmlkjhgfdsaq",
    "ready": true
}
```

If the response shows <mark style="color:red;">`ready: false`</mark> call the "sync start" method again. Once the sync is ready you will get delta tokens <mark style="color:red;">`syncUpdatedToken`</mark>, <mark style="color:red;">`syncDeletedToken`</mark> and can start loading updated and deleted contacts.

#### **Initial full sync**

Initial requests <mark style="color:red;">`/contacts/sync/update`</mark>`d` and <mark style="color:red;">`/contacts/sync/deleted`</mark> are equivalent to a full sync, plus loading all updated contacts (deleted contacts) since the sync start.

```bash
curl -X GET -H 'Authorization: Bearer <access token>'
    -G https:/api.aurinko.io/v1/contacts/sync/updated
    -d deltaToken='{syncUpdatedToken}'
```

*Response:*

```json
{
    "nextPageToken": "string",
    "nextDeltaToken": "string",
    "records":  [{...}]
}
```

Continue loading pages using provided <mark style="color:red;">`nextPageToken`</mark> until you find another <mark style="color:red;">`nextDeltaToken`</mark>.

```bash
curl -X GET -H 'Authorization: Bearer <access token>'
    -G https:/api.aurinko.io/v1/contacts/sync/updated
    -d pageToken='{nextPageToken}'
```

#### **Incremental sync**

A new deltaToken (nextDeltaToken in a response) is provided for loading contacts that have been modified/deleted since the last sync-updated/sync-deleted request. In cases where a large number of contacts have changed since the last incremental sync request, you may find a <mark style="color:red;">`nextPageToken`</mark> instead of the <mark style="color:red;">`nextDeltaToken`</mark> in the response. Continue loading pages using the provided <mark style="color:red;">`nextPageToken`</mark> until you find another <mark style="color:red;">`nextDeltaToken`</mark>.

### Other examples

***

To create a new contact POST json payload to <mark style="color:red;">`/contacts`</mark> endpoint:

```bash
curl -H 'Authorization: Bearer <access token>'
    -X POST https:/api.aurinko.io/v1/contacts
    -d '{
    "name": {
        "givenName": "John",
        "familyName": "Smith"
    },
    "company": {
        "companyName": "ABC Corp",
        "officeLocation": "Florida",
        "department": "R&D",
        "jobTitle": "Manager"
    },
    "notes": "some background",
    "birthday": "2000-09-01",
    "keywords": ["Blue"],
    "emailAddresses": [
        {"address": "john@abccorp.co", "type": "work"}
    ],
    "phoneNumbers": [
        {"number": "1234567", "type": "work"},
        {"number": "7654321", "type": "mobile"}
    ],
    "addresses": [
        {
            "street": "300 Lemon Ave #100",
            "city": "Walnut",
            "state": "CA",
            "postalCode": '91789',
            "country": "USA",
            "type": "work"
        }
    ],
    "urls": [
       {
           "value": "[www.abccorp.co](http://www.abccorp.co)", 
           "type": "work"
       }
    ]
}'
```

Use PATCH request to [update](https://apirefs.aurinko.io/#operation/updateContact) existing contacts. List only those high level fields that are being updated, and specify <mark style="color:red;">`If-Match`</mark> header with the <mark style="color:red;">`Etag`</mark> value that was received when you loaded the contact.

```bash
curl -X PATCH -H 'Authorization: Bearer <access token>' -H 'If-Match: <etag>'
    https:/api.aurinko.io/v1/contacts/{contId}
    -d '{
    "name": {
        "givenName": "John",
        "middleName": "Peter",
        "familyName": "Smith"
    }
}'
```


# Tasks API

Aurinko's Tasks API integrates task management into your apps, abstracting Google Tasks, Microsoft To Do, and Outlook Tasks. Perform CRUD tasks while managing lists.

## Aurinko Tasks API

***

The Aurinko Tasks API is part of the Aurinko Unified API platform, enabling developers to integrate task management functionalities effortlessly into their applications. This API abstracts the differences between task management services such as Google Tasks, Microsoft To Do, and Outlook Tasks, offering a consistent interface for task-related operations.

### Functionality

***

The Aurinko Tasks API offers robust functionalities for managing tasks:

* **Create Tasks:** Create new tasks with various attributes like titles, descriptions, due dates, priorities, and custom fields, depending on the capabilities of the underlying service.
* **Read Tasks:** Retrieve details of existing tasks, including titles, statuses, due dates, and completion status.
* **Update Tasks:** Modify existing tasks by updating attributes like titles, descriptions, due dates, and priorities, or by marking tasks as completed or uncompleted.
* **Delete Tasks:** Permanently remove tasks from the user’s account.
* **Lists:** Manage task lists, including creating, reading, updating, and deleting lists, subject to the capabilities of the underlying service.

### Aurinko account setup

***

First, create your account in the [Aurinko portal](https://app.aurinko.io/), then follow the guide to [get your developer API keys](https://docs.aurinko.io/getting-started/get-your-developer-api-keys).

### Tasks API Endpoints

***

#### Task lists

Each account connected to Aurinko can have zero or more [task lists](https://apirefs.aurinko.io/#tag/TaskLists), and each task list contains a collection of individual tasks.

#### Tasks

[Tasks](https://apirefs.aurinko.io/#tag/Tasks) are objects within a task list that generally support all features and attributes of modern task management apps like task subject, description, priority, due date, status, etc. Aurinko supports key task functionality: creating and modifying tasks.

#### **Synchronization**

[Tasks sync](https://apirefs.aurinko.io/#tag/TaskSync) methods allow developers to implement incremental synchronization of task list data in a uniform manner across different providers. Aurinko supports requesting updated as well as deleted tasks.

### Tasks sync quickstart

***

#### **Start a new sync**

A new sync needs to be provisioned by calling the *sync-start* method <mark style="color:red;">`/calendars/{calendarId}/sync`</mark> The sync is available per task list, hence {taskListId} or *default*. <mark style="color:red;">`skipCompletedBeforeDate`</mark> applies for the initial full load.

```bash
curl -X POST -H 'Authorization: Bearer <access token>' 
    -G https://api.aurinko.io/v1/tasklists/default/sync[?awaitReady=false]
    -d skipCompletedBeforeDate='2023-05-29T10:58:27Z'
```

The Aurinko platform will initialize all necessary internal resources and let you know when it's ready to serve data. The response should look like this:

```json
{
    "syncUpdatedToken": "asdfghjklpoiuytrew",
    "syncDeletedToken": "zxcvbnmlkjhgfdsaq",
    "ready": true
}
```

If the response shows <mark style="color:red;">`ready: false`</mark> call the *sync-start* method again. Once the sync is ready you will get delta tokens <mark style="color:red;">`syncUpdatedToken`</mark>, <mark style="color:red;">`syncDeletedToken`</mark> and can start loading updated and deleted events.

#### **Initial full sync**

Initial requests <mark style="color:red;">`/tasklists/{taskListId}/sync/updated`</mark> and <mark style="color:red;">`/tasklists/{taskListId}/sync/deleted`</mark> are equivalent to a full sync with the <mark style="color:red;">`skipCompletedBeforeDate`</mark> filter, plus loading all updated tasks (deleted tasks) since the sync start.

```bash
curl -X GET -H 'Authorization: Bearer <access_token>'
    -G https:/api.aurinko.io/v1/tasklists/default/sync/updated
    -d deltaToken='{syncUpdatedToken}'
```

*Response:*

```json
{
    "nextPageToken": "string",
    "nextDeltaToken": "string",
    "records": [{...}]
}
```

Continue loading pages using provided <mark style="color:red;">`nextPageToken`</mark> until you find another <mark style="color:red;">`nextDeltaToken`</mark>.

```bash
curl -X GET -H 'Authorization: Bearer <access_token>'
    -G https:/api.aurinko.io/v1/tasklists/default/sync/updated
    -d pageToken='{nextPageToken}'
```

#### **Incremental sync**

A new deltaToken (nextDeltaToken in response) is provided for loading tasks that have been modified/deleted since the last *sync-updated/sync-deleted* request. In cases where a large number of tasks have changed since the last incremental sync request, you may find a <mark style="color:red;">`nextPageToken`</mark> instead of the <mark style="color:red;">`nextDeltaToken`</mark> in the response. Continue loading pages using the provided <mark style="color:red;">`nextPageToken`</mark> until you find another <mark style="color:red;">`nextDeltaToken`</mark>.

### Other examples

***

#### Task lists

To view a list of all task lists a user has access to, make a request to the <mark style="color:red;">`/tasklists`</mark> endpoint.

```bash
curl -H 'Authorization: Bearer <access_token>'
    -X GET https:/api.aurinko.io/v1/tasklists
```

You can get information for a single task list by providing the appropriate list id, <mark style="color:red;">`/tasklists/{id}`</mark>. You can use *default* as an ID to get your default list.

```bash
curl -H 'Authorization: Bearer <access_token>'
    -X GET https:/api.aurinko.io/v1/tasklists/default
```

#### Tasks

To get a list of tasks from a list, make a request to the <mark style="color:red;">`/tasklists/{id}/tasks`</mark> endpoint.

```bash
curl -X POST -H 'Authorization: Bearer <access_token>'
    -G https:/api.aurinko.io/v1/tasklists/default/tasks
```

To create a new task POST json payload to <mark style="color:red;">`/tasklists/{id}/tasks`</mark> endpoint:

```bash
curl -H 'Authorization: Bearer <access_token>'
    -X POST https:/api.aurinko.io/v1/tasklists/default/tasks
    -d '{
    "title": "My Task",
    "parentId": "string",
    "notes": "Task description...",
    "status": "notStarted",
    "importance": "low",
    "due": "2024-10-24T14:00:00Z",
    "startDateTime": "2024-10-23T14:00:00Z",
}'
```

Use PATCH request to update existing tasks:

```bash
curl -X POST -H 'Authorization: Bearer <access_token>'
    https:/api.aurinko.io/v1/tasklists/default/tasks/{taskId}
    -d '{
    -d '{
    "title": "My Task (updated)",
    "parentId": "string",
    "notes": "Task description...",
    "status": "notStarted",
    "importance": "high",
    "due": "2024-10-24T14:00:00Z",
    "startDateTime": "2024-10-23T14:00:00Z",
}'
```


# Webhooks API

Aurinko's Webhooks API enables real-time event notifications for email, calendar, contacts, and task updates by subscribing to specific resources and handling webhook payloads efficiently.

## Aurinko Webhooks API

Webhooks allow your apps to receive real-time updates from the Aurinko platform. By registering a webhook URL, you can get notified when specific events happen.

Aurinko retrieves data by either subscribing to provider resources or using a poller for periodic updates. For certain resources, such as [Google Pub/Sub](/unified-apis/webhooks-api/configuring-pub-sub-for-gmail-api-webhooks), manual configuration is required to ensure the provider’s data is successfully delivered to Aurinko.

### Aurinko account setup

***

First, create your account in the [Aurinko portal](https://app.aurinko.io/), then follow the guide to [get Your Developer API Keys](https://docs.aurinko.io/getting-started/get-your-developer-api-keys).

### Setting up a Webhook

***

1. Prepare an endpoint URL on your server.
2. Ensure your endpoint can handle POST requests with [authentication](/unified-apis/webhooks-api/authentication) and supports the initial [url verification step.](#notification-url-verification)
3. Provide your endpoint to our system through the [event subscription](https://apirefs.aurinko.io/#tag/Webhooks/operation/subscribe) process.

### Authentication

***

Webhooks are secured using a shared secret that is used to generate a signature. The signature is sent in the HTTP header of each request, allowing you to verify the authenticity. The signing secret can be found on your app's dashboard page.

For more details, see the documentation: [Authentication](https://app.gitbook.com/o/4jzD0cdc8TPZbg83hQxP/s/0ua36KLVlbUN5bA2bgiq/~/edit/~/changes/zleGiPK3UvcThb1dxgK7/unified-apis/webhooks-api/authentication).

### Notification URL Verification

***

When you register a new webhook subscription with Aurinko, the platform performs a Notification URL Verification to ensure that your server is ready to receive and process events. Validate this request as any other requests by [authentication](#authentication). See the documentation for more details: [Notification URL Verification](https://app.gitbook.com/o/4jzD0cdc8TPZbg83hQxP/s/0ua36KLVlbUN5bA2bgiq/~/edit/~/changes/zleGiPK3UvcThb1dxgK7/unified-apis/webhooks-api/notification-url-verification).

### API Resources

***

The Aurinko webhook events are associated with API resources (parts of the API) and subscriptions are created for those resources. Here is the list of available API resources:

* */email/messages* - events representing mailbox changes.
* */email/tracking* - events representing email tracking changes.
* */calendars/primary/events, /calendars/{calId}/events* - events representing calendar changes.
* */contacts* - events representing address book changes.
* */tasklists/default/tasks, /tasklists/{tlId}/tasks* - events representing todo item changes.
* */booking/{bookingId}* - events representing booking lifecycle changes.

### Subscribing

***

To create a new subscription POST a resource and a notification url to \
the [subscriptions endpoint](https://apirefs.aurinko.io/#tag/Webhooks/operation/subscribe):

#### Email messages

```bash
curl -H 'Authorization: Bearer <access token>'
    -X POST https://api.aurinko.io/v1/subscriptions
    -d '{
        "resource": "/email/messages",
        "notificationUrl": "https://myserver/pushEvents"
}'  
```

*Response:*

```json
{
    "id": "87665448354",
    "resource": "/email/messages", 
    "notificationUrl": "https://myserver/pushEvents" 
}  
```

#### Email tracking

```bash
curl -H 'Authorization: Bearer <access token>'
    -X POST https://api.aurinko.io/v1/subscriptions
    -d '{
        "resource": "/email/tracking",
        "notificationUrl": "https://myserver/pushEvents"
}'
```

{% hint style="info" %}
For more details on the email tracking fields (<mark style="color:red;">`opens`</mark>, <mark style="color:red;">`threadReplies`</mark>, <mark style="color:red;">`trackOpensAfterSendDelay`</mark>, <mark style="color:red;">`context`</mark>, <mark style="color:red;">`customDomainAlias`</mark>) and how to include them when sending messages, see the Email Tracking Options section in the [Email API documentation.](https://docs.aurinko.io/unified-apis/email-api#email-tracking-options)
{% endhint %}

#### Calendar events

```bash
curl -H 'Authorization: Bearer <access token>'
    -X POST https://api.aurinko.io/v1/subscriptions
    -d '{
        "resource": "/calendars/primary/events",
        "notificationUrl": "https://myserver/pushEvents"
}'
```

or for a specific calendar:

```bash
curl -H 'Authorization: Bearer <access token>'
    -X POST https://api.aurinko.io/v1/subscriptions
    -d '{
        "resource": "/calendars/{calId}/events",
        "notificationUrl": "https://myserver/pushEvents"
}'
```

#### Contacts

```bash
curl -H 'Authorization: Bearer <access token>'
    -X POST https://api.aurinko.io/v1/subscriptions
    -d '{
        "resource": "/contacts",
        "notificationUrl": "https://myserver/pushEvents"
}'
```

#### Tasks

```bash
curl -H 'Authorization: Bearer <access token>'
    -X POST https://api.aurinko.io/v1/subscriptions
    -d '{
        "resource": "/tasklists/default/tasks",
        "notificationUrl": "https://myserver/pushEvents"
}'
```

or for a specific task list:

```bash
curl -H 'Authorization: Bearer <access token>'
    -X POST https://api.aurinko.io/v1/subscriptions
    -d '{
        "resource": "/tasklists/{tlId}/tasks",
        "notificationUrl": "https://myserver/pushEvents"
}'
```

#### Booking

```bash
curl -H 'Authorization: Bearer <access token>'
    -X POST https://api.aurinko.io/v1/subscriptions
    -d '{
        "resource": "/booking/{bookingId}",
        "notificationUrl": "https://myserver/pushEvents"
}'
```

### Payloads

***

Each API resource may have its own payload format. Below is a sample payload that is common for <mark style="color:red;">`email/messages`</mark>, <mark style="color:red;">`/contacts`</mark>, <mark style="color:red;">`/calendars/{id}/events`</mark>, <mark style="color:red;">`/tasklists/{id}/tasks`</mark>:

```json
{
    "subscription" : 1217,
    "resource" : "/email/messages",
    "accountId" : 1532,
    "payloads" : [
        {
            "id" : "AQMkAGY0ZTQyM2ZlLTM5N2UtNGZkYy1hZmQ2LTJkNDdmNTlmMGZlNgBGAAADhXGu-
                   WVhvEKOWPBUZKnvPwcAAAAUsezTfrRCmmimIKi3ETUAAAIBDAAAARSx7NN\_tEKaaKY
                   gqLcRNQAGD3-S2QAAAA==",
            "changeType" : "created"
        }
        {
            "id" : "AQMkAGY0ZTQyM2ZlLTM5N2UtNGZkYy1hZmQ2LTJkNDdmNTlmMGZlNgBGAAADhXGu-
                   WVhvEKOWPBUZKnvPwcAAAAUsezTfrRCmmimIKi3ETUAAAIBDAAAARSx7NN\_tEKaaKY
                   gqLcRNQAGD3-S2QAAAA==",
            "changeType" : "updated"
        },
        {
            "id" : "AQMkAGY0ZTQyM2ZlLTM5N2UtNGZkYy1hZmQ2LTJkNDdmNTlmMGZlNgBGAAADhXGu-
                   WVhvEKOWPBUZKnvPwcAAAAUsezTfrRCmmimIKi3ETUAAAIBDAAAARSx7NN\_tEKaaKY
                   gqLcRNQAGD3-S2QAAAA==",
            "changeType" : "deleted"
        }
    ]
}
```

Booking have their own payload format. The <mark style="color:red;">`/booking/{bookingId}`</mark> webhook delivers a JSON payload only when a booking (meeting) is created.

```json
{
  "subscription" : 4880,
  "resource" : "/booking/935",
  "accountId" : 1535,
  "payloads" : [
    {
      "bookingId" : 935,
      "calendarId" : "primary",
      "eventId" : "AQMkAGEwZWM2OTY0LWQ4M2UtNGIwYi05M2RmLWJhMDc5OGUxYzQ2ZQBGAAADvqWN9e2g-0SLB0ron1CplQcA6AyjjUD5nUarse36ZjN3XQAAAgENAAAA6AyjjUD5nUarse36ZjN3XQAC5jFyywAAAA=="
    }
  ]
}
```

Next, an example of the <mark style="color:red;">`email/tracking`</mark> events (eventType can be open, reply, or replyBounce).

{% hint style="info" %}
For more details on the email tracking fields (<mark style="color:red;">`opens`</mark>, <mark style="color:red;">`threadReplies`</mark>, <mark style="color:red;">`trackOpensAfterSendDelay`</mark>, <mark style="color:red;">`context`</mark>, <mark style="color:red;">`customDomainAlias`</mark>) and how to include them when sending messages, see the Email Tracking Options section in the [Email API documentation](https://docs.aurinko.io/unified-apis/email-api#email-tracking-options).
{% endhint %}

```json
{
    "subscription": 1271,
    "resource": "/email/tracking",
    "accountId": 1626,
    "payloads": [
        {
            "id": 1670,
            "createdAt": "2023-09-29T09:13:44Z",
            "eventType": "reply",
            "threadId": "",
            "messageId": "",
            "internetMessageId": "<...@mail.gmail.com>",
            "trackingId": 1614,
            "context" : "",
            "trackingCode": "5c59753a-3e4f-4c2c-a2f7-1e5c4fc538d2"
        },
        {
            "id": 1687,
            "createdAt": "2023-09-29T10:59:20.236665Z",
            "eventType": "open",
            "location" : "",
            "userAgent": "Mozilla/4.0 (compatible; ms-office; MSOffice 16)",
            "remoteAddr": "176.116.84.4",
            "trackingId": 1617,
            "context" : "",
            "trackingCode": "fce4d887-1aea-4b2f-93fc-5e02147f9c3d"
        }
    ]
}

{
    "subscription" : 3223,
    "resource" : "/email/tracking",
    "accountId" : 1464,
    "payloads" : [
        {
            "id" : 5973,
            "createdAt" : "2024-10-23T17:15:57Z",
            "eventType" : "replyBounce",
            "threadId" : "",
            "messageId" : "",
            "internetMessageId" : "<...@mail.gmail.com>",
            "trackingId" : 3230,
            "context" : "",
            "trackingCode" : "bce0e37e-9f90-4171-9f76-926c77b2c9b1"
        }
    ]
}
```

\
When an email is first processed for tracking, an ‘Initial’ event is triggered. This event occurs only once when tracking begins, typically upon sending the email, and is not included in subsequent tracking updates:

<pre class="language-json"><code class="lang-json">{ 
    "subscription" : 3190, 
    "resource" : "/email/tracking", 
    "accountId" : 1535, 
    "payloads" : [ 
        { 
            "id" : 5822, 
<strong>            "createdAt" : "2024-10-17T13:35:04Z", 
</strong>            "eventType" : "initial", 
            "threadId" : "", 
            "messageId" : "", 
            "internetMessageId" : "&#x3C;...@mail.gmail.com>", 
            "trackingId" : 3159, 
            "context" : "", 
            "trackingCode" : "e2d9e1fb-e1b2-4a57-96d9-5bc0fe10b129" 
        } 
    ] 
}

</code></pre>

### Handling Webhooks

***

When you receive a webhook:

1. Validate the signature to ensure it's from the Aurinko platform.
2. Respond with a <mark style="color:red;">`200 OK`</mark> as quickly as possible.
3. Process the event data asynchronously.

### Retries

***

If your endpoint responds with any HTTP status other than <mark style="color:red;">`200 OK`</mark> or <mark style="color:red;">`422 Unprocessable`</mark>, Aurinko will attempt to resend the webhook 1, 2, 4, 8 ... etc seconds (the interval won't increase beyond 10mins). Responding with the 422 HTTP status results in removing the subscription.

### Lifecycle events

***

If for some reason your webhook subscription becomes problematic (i.e. because account credentials have expired), Aurinko will send a lifecycle event like this:

```json
{
    "subscription" : 1217,
    "resource" : "/email/messages",
    "accountId" : 1532,
    "lifecycleEvent": "error",
    "error": "Error message"
}
```

When the subscription comes back to life, Aurinko will send:

```json
{
    "subscription" : 1217,
    "resource" : "/email/messages",
    "accountId" : 1532,
    "lifecycleEvent": "active"
}
```

### Deleting a webhook

***

```bash
curl -H 'Authorization: Bearer <access token>'
    -X DELETE https:/api.aurinko.io/v1/subscriptions/{id}
```


# Authentication

### Aurinko Signature Validation Steps

To verify that a request truly came from Aurinko, follow these four steps:

#### 1. Extract the Components

You will need three specific pieces of information from the incoming HTTP request:

* **Timestamp:** The value of the <mark style="color:red;">X-Aurinko-Request-Timestamp</mark> header.
* **Signature:** The value of the <mark style="color:red;">X-Aurinko-Signature</mark> header (this is your target for comparison).
* **Raw Body:** The exact, unparsed byte array of the request body.&#x20;

{% hint style="info" %}
**Note:** Do not use a JSON-deserialized object, as whitespace differences will cause the hash to fail.
{% endhint %}

#### 2. Create the Base String

Concatenate the version, the timestamp, and the raw body using <mark style="color:red;">a colon (:)</mark> as a delimiter.

* **Current Version:** v0
* **Format:** v0:{timestamp}:{raw\_body}

#### 3. Compute the HMAC SHA256 Hash

Using your <mark style="color:red;">Aurinko Signing Secret</mark> as the key, sign the base string created in Step 2.<br>

**Java Example:**

```java
final byte[] signData = org.apache.commons.lang3.ArrayUtils.addAll(
    ("v0:" + timestampSeconds + ":").getBytes(StandardCharsets.UTF_8),
    payloadBytes
);
```

{% hint style="info" %}
**Note:** Then hash signData using HMAC SHA256 and your Signing Secret.
{% endhint %}

#### 4. Compare and Verify

Compare your computed hash against the X-Aurinko-Signature header.

* **Match:** The request is authentic; proceed with processing.
* **Mismatch:** The request is invalid and should be discarded (return a 401 or 403 status).

#### Quick Reference Table

| <h4><strong>Element</strong></h4> | <h4><strong>Source</strong></h4>       |
| --------------------------------- | -------------------------------------- |
| **Version**                       | Static string v0                       |
| **Key**                           | Your unique **Aurinko Signing Secret** |
| **Algorithm**                     | HMAC SHA256                            |
| **Delimiter**                     | Colon :                                |

**Java example:**

```java
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.lang3.ArrayUtils;

public class AurinkoValidator {

    private static final String HMAC_ALGO = "HmacSHA256";
    private static final String VERSION = "v0";

    public boolean isValidRequest(String signingSecret, String timestamp, String headerSignature, byte[] rawBody) {
        try {
            // 1. Prepare the prefix: "v0:timestamp:"
            String prefix = VERSION + ":" + timestamp + ":";
            byte[] prefixBytes = prefix.getBytes(StandardCharsets.UTF_8);

            // 2. Concatenate prefix bytes with raw body bytes
            byte[] dataToSign = ArrayUtils.addAll(prefixBytes, rawBody);

            // 3. Initialize HMAC SHA256 with your Secret
            SecretKeySpec secretKeySpec = new SecretKeySpec(
                signingSecret.getBytes(StandardCharsets.UTF_8), 
                HMAC_ALGO
            );
            Mac mac = Mac.getInstance(HMAC_ALGO);
            mac.init(secretKeySpec);

            // 4. Compute the hash
            byte[] computedHashBytes = mac.doFinal(dataToSign);
            String computedSignature = Hex.encodeHexString(computedHashBytes);

            // 5. Compare computed signature with the header
            // Use MessageDigest.isEqual for a time-constant comparison (prevents timing attacks)
            return java.security.MessageDigest.isEqual(
                computedSignature.getBytes(StandardCharsets.UTF_8),
                headerSignature.getBytes(StandardCharsets.UTF_8)
            );

        } catch (Exception e) {
            // Log the error and reject the request
            return false;
        }
    }
}
```


# Notification URL Verification

To ensure endpoint availability, Aurinko performs a validation handshake when a subscription is created.<br>

1. **The Verification Request**\
   When you call the <mark style="color:red;">POST</mark> <mark style="color:red;"></mark><mark style="color:red;">`/v1/subscriptions`</mark> endpoint, Aurinko immediately sends a POST request to your provided notificationUrl. \
   \
   **Request Details:**

   * **Method:** <mark style="color:red;">POST</mark>
   * **Query Parameter:** <mark style="color:red;">validationToken</mark> (a random string generated by Aurinko)

   \
   **Example Request:**

   ```
   Content-Type: text/plain; charset=utf-8
   POST https://{notificationUrl}?validationToken={challenge}
   ```

2. **Your Server’s Response**\
   Verify request see Authentication. Your endpoint must respond to this POST request to prove it is active and authorized to receive notifications.

* **Status Code:** <mark style="color:red;">200 OK</mark>
* **Content-Type:** <mark style="color:red;">text/plain</mark>
* **Response Body:** Must contain only the value of the [<mark style="color:red;">validationToken</mark>](#user-content-fn-1)[^1] parameter received in the request.\
  \
  **Example Response:**

  ```
  HTTP/1.1 200 OK Content-Type: text/plain
  679732f7-8775-4340-a33d-713217277682
  ```

3. **Critical Requirements**

* **Timeout:** Your server must respond within 30 seconds. If the request times out or returns an error (e.g., 4xx or 5xx), the subscription creation will fail.
* **Plain Text:** Ensure your framework does not wrap the token in JSON or HTML. It must be a raw string response.\
  \
  **Subscription Workflow Summary**
  1. **Register:** Your app calls <mark style="color:red;">POST</mark> <mark style="color:red;"></mark><mark style="color:red;">`/v1/subscriptions`</mark>.
  2. **Verify:** Aurinko calls your URL via <mark style="color:red;">POST</mark> with a <mark style="color:red;">validationToken</mark>.
  3. **Confirm:** Your server returns the token.
  4. **Activate:** Aurinko returns a <mark style="color:red;">200 Success</mark> to your original registration call and begins sending <mark style="color:red;">POST</mark> notifications.

[^1]:


# Configuring Pub/Sub for Gmail API Webhooks

Set up Google Cloud Pub/Sub for Aurinko to receive Gmail API push notifications, eliminating constant polling and enhancing efficiency.

This guide explains how to set up Google Cloud Pub/Sub (Pub/Sub) for Aurinko to receive push notifications from the Gmail API. Using Pub/Sub eliminates the need for constant polling of your Gmail inbox for updates, improving efficiency.

To get started, head over to [https://console.developers.google.com](https://console.developers.google.com/). You will be prompted to log in with a Google account if you're not already logged in with one.

Select your project, or create a new one. Refer to [this article](/authentication/google-oauth-setup) if creating a new project, the Gmail API needs to be enabled!

### Pub/Sub topic setup

***

1. Head over to the Pub/Sub page

<div data-full-width="true"><figure><img src="/files/w61wScyaJsA3KhAUyS6O" alt=""><figcaption></figcaption></figure></div>

2. Create a new topic. The default options will do:

<div data-full-width="true"><figure><img src="/files/LbuzVyVtY5C6N3qehpZZ" alt=""><figcaption></figcaption></figure></div>

3. Copy the topic name and enter it in your Aurinko app settings:

<div data-full-width="true"><figure><img src="/files/K1eSo5VLTFGh3Q4OaPjj" alt=""><figcaption></figcaption></figure></div>

4. Back in the Google Developer console, edit the default subscription that was created for your new topic. Make it a Push subscription with the following 'Endpoint URL': <mark style="color:red;">`https://api.aurinko.io/push/google/email/{clientId}`</mark>

<div data-full-width="true"><figure><img src="/files/bkAPT0mvID6G9bg1NBM1" alt=""><figcaption></figcaption></figure></div>

Also, change the retry policy and save:

<div data-full-width="true"><figure><img src="/files/7ZCKRmbZcioqkNXKEre2" alt=""><figcaption></figcaption></figure></div>

5. Go back to the **'Topics'** menu and click **'View permissions'** for your new topic.

<div data-full-width="true"><figure><img src="/files/rulRyX40eGBeBm4P2iUk" alt=""><figcaption></figcaption></figure></div>

6. Now, let's grant Gmail privileges to publish notifications to your topic.

Click '**ADD PRINCIPLE'** and grant publish privileges to <mark style="color:red;">`gmail-api-push@system.gserviceaccount.com`</mark>:

<div data-full-width="true"><figure><img src="/files/c8zOkblKBIFnvyxbJHvh" alt=""><figcaption></figcaption></figure></div>

**You are done!**


# Direct API

A direct pass-through API for native communications with underlying provider APIs using Aurinko's unified OAuth flow.

## Aurinko /direct API

***

The Aurinko /direct API endpoint enables applications to request native provider payloads directly, leveraging Aurinko's OAuth Flow and secure access token storage. It is a valuable alternative to data unification, offering flexibility and control for complex integrations while still benefiting from Aurinko's core security and authentication features.

**The Aurinko /direct API offers significant advantages in specific scenarios:**

* **Circumventing Data Unification:** When data unification isn't necessary or feasible (due to complexity or specific integration requirements), the /direct API allows for direct interaction with the provider's native API. This provides the flexibility needed for intricate or unique integrations.
* **Debugging and Troubleshooting:** The /direct API serves as an invaluable tool for debugging and troubleshooting. By directly interacting with the provider's API within the context of Aurinko's authentication framework, developers can isolate and pinpoint issues related to specific API calls or provider responses.
* **Leveraging Aurinko's Authentication:** While bypassing data unification, the /direct API still leverages Aurinko's robust authentication and authorization mechanisms. This ensures secure and controlled access to provider APIs, maintaining a consistent security posture across all integrations.

### **Examples**

***

#### **Gmail API**

Get a list of Gmail messages for a Gmail Aurinko account:

```bash
curl -X GET -H 'Authorization: Bearer <access token>'
    -G https://api.aurinko.io/v1/direct/gmail/v1/users/me/messages
```

/gmail/v1/users/me/messages is the path of the [Gmail API endpoint](https://developers.google.com/gmail/api/reference/rest/v1/users.messages/list).

#### **Graph API**

Get list of Office 365 messages for an Office 365 Aurinko account:

```bash
curl -X GET -H 'Authorization: Bearer <access token>'
    -G https://api.aurinko.io/v1/direct/me/messages
```

/me/messages is the path of the [Graph API endpoint](https://learn.microsoft.com/en-us/graph/api/user-list-messages?view=graph-rest-1.0\&tabs=http#http-request).

#### **Salesforce API**

Get a description of a Salesforce Contact object for a Salesforce Aurinko account:

```bash
curl -X GET -H 'Authorization: Bearer <access token>'
    -G https://api.aurinko.io/v1/direct/services/data/v51.0/sobjects/Contact/describe/
```

/sobjects/Contact/describe/ is the path of the [Salesforce API endpoint](https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/resources_sobject_describe.htm).


# Follow-up Rules API

The Follow-up Rules API simplifies managing follow-up actions and configurations for effective workflow automation. This API allows users to create, retrieve, update, and delete follow-up rules, as well as manage configurations such as email aliases and time zones.<br>

For more detailed reference, visit the [FollowUpRobot API documentation](https://apirefs.aurinko.io/#tag/FollowUpRobot).

#### Creating a Follow-up Rule

***

To add a new follow-up rule, send a **`POST`** request to the <mark style="color:red;">`/v1/followup/rules`</mark> endpoint with a JSON payload containing the rule details.

**Request Example:**

```bash
curl -X POST https://api.yourdomain.com/v1/followup/rules 
-H "Authorization: Bearer <Access-Token>" 
-H "Content-Type: application/json" 
-d '{
    "name": "Follow-up for Leads",
    "expectThreadResponse": true,
    "templateBody": "Thank you for reaching out. We will follow up shortly.",
    "templateSubject": "Follow-up Confirmation",
    "actions": [
        {
            "intervalDays": 3,
            "message": "Reminder to respond to client."
        }
    ]
}'
```

#### Updating a Follow-up Rule

***

To update an existing follow-up rule, send a **`PUT`** request to the <mark style="color:red;">`/v1/followup/rules/{id}`</mark> endpoint, where <mark style="color:red;">`{id}`</mark> is the ID of the rule you want to update.

**Request Example:**

```bash
curl -X PUT https://api.yourdomain.com/v1/followup/rules/{id} 
-H "Authorization: Bearer <Access-Token>" 
-H "Content-Type: application/json" 
-d '{
    "name": "Updated Follow-up for Leads",
    "expectThreadResponse": false,
    "templateBody": "We appreciate your response. We will follow up shortly.",
    "templateSubject": "Follow-up Reminder",
    "actions": [
        {
            "intervalDays": 5,
            "message": "Final reminder to respond to client."
        }
    ]
}'
```

#### Getting Follow-up Rules

***

To retrieve all follow-up rules, send a **`GET`** request to the <mark style="color:red;">`/v1/followup/rules`</mark> endpoint.

**Request Example:**

```bash
curl -X GET https://api.yourdomain.com/v1/followup/rules 
-H "Authorization: Bearer <Access-Token>"
```

#### Deleting a Follow-up Rule

***

To delete an existing follow-up rule, send a **`DELETE`** request to the <mark style="color:red;">`/v1/followup/rules/{id}`</mark> endpoint, where <mark style="color:red;">`{id}`</mark> is the ID of the rule you wish to delete.

**Request Example:**

```bash
curl -X DELETE https://api.yourdomain.com/v1/followup/rules/{id} 
-H "Authorization: Bearer <Access-Token>"
```

#### Getting Follow-up Configuration

***

To retrieve the current follow-up configuration, send a **`GET`** request to the <mark style="color:red;">`/v1/followup/config`</mark> endpoint.

**Request Example:**

```bash
curl -X GET https://api.yourdomain.com/v1/followup/config 
-H "Authorization: Bearer <Access-Token>"
```

#### Updating Follow-up Configuration

***

To update the follow-up configuration, send a **`PUT`** request to the <mark style="color:red;">`/v1/followup/config`</mark> endpoint.

**Request Example:**

```bash
curl -X PUT https://api.yourdomain.com/v1/followup/config 
-H "Authorization: Bearer <Access-Token>" 
-H "Content-Type: application/json" 
-d '{
    "timezone": "America/New_York",
    "emailAliases": ["support@yourdomain.com", "info@yourdomain.com"]
}'
```


# OAuth Flow

Aurinko's Unified OAuth Flow simplifies user authentication, supporting various account types including: Account, Service Account, User Session.

Aurinko provides a Unified OAuth Flow that is backed by providers' OAuth2 (i.e. Google, Office 365, Zoho Mail, Salesforce, HubSpot, SugarCRM) or by secure password-based authentication (i.e. MS Exchange, IMAP accounts).

There OAuth flows are available:

1. [Account](/authentication/oauth-flow/account-oauth-flow) - User delegated authorization that produces an Aurinko account and an access token.
2. [Service Account](/authentication/service-accounts) - Admin/Org-level authorization that produces an Aurinko service account and an access token.
3. [User Session](/authentication/oauth-flow/user-oauth-flow) - User delegated authorization that produces an Aurinko User, its primary account, and a user session token or cookie.


# Account OAuth Flow

Aurinko's Account OAuth Flow is a user-delegated authorization flow, producing an Aurinko account and an access token for secure API access.

## Account OAuth Flow

***

This is a standard flow for getting access to a remote account. To enable Google and Office 365 OAuth flow for production, please see the following instructions [Office365 OAuth Setup](/authentication/office-365-oauth-setup) and [Google OAuth Setup](/authentication/google-oauth-setup).

This flow uses user-delegated authorization and produces an Aurinko account and an access token.

Some key terms you'll encounter while integrating with Aurinko's OAuth2 flow:

#### **Final Callback URL (returnUrl)**

The final callback URL, also known as <mark style="color:red;">`returnUrl`</mark>, is the URL provided by your application and specified when calling the <mark style="color:red;">`/authorize`</mark> API method within Aurinko. This is where Aurinko will redirect the user after successful authorization. It's crucial to register this URL within the Aurinko settings for your application.

#### Intermediate Redirect URL

The intermediate redirect URL is a temporary landing page used during the OAuth2 flow. By default, Aurinko uses <mark style="color:red;">`https://api.aurinko.io/v1/auth/callback`</mark> for this purpose. However, developers have the flexibility to customize this URL within the Aurinko settings for their application.

The following diagram shows a custom OAuth flow with your own intermediate redirect URL.&#x20;

<figure><img src="/files/wZOTmjrD9VEtHDc9hfLz" alt=""><figcaption></figcaption></figure>

We recommend this flow because Google app registrations allow only authorized redirect URIs under a domain you own so Aurinko's default Redirect URI <mark style="color:red;">`https://api.aurinko.io/v1/auth/callback`</mark> won't work for you in production.

Create a dedicated **intermediate redirect** page that will be redirecting all callback requests to Aurinko's <mark style="color:red;">`https://api.aurinko.io/v1/auth/callback`</mark> with the URL parameters <mark style="color:red;">`state`</mark>, <mark style="color:red;">`code`</mark>, and <mark style="color:red;">`scope`</mark>. \
\
Specify the page url in the Aurinko app settings (override the default url).

<div align="left" data-full-width="true"><figure><img src="/files/WbYMBAvMciBMdnkUSpMi" alt=""><figcaption></figcaption></figure></div>

1. **Authorization request**

From your application, redirect users to <mark style="color:red;">`https://api.aurinko.io/v1/auth/authorize`</mark>, with the query parameters detailed in [/auth/authorize](https://apirefs.aurinko.io/#tag/Auth/operation/authorize). You'll need to set the <mark style="color:red;">`responseType=code`</mark>.

{% hint style="info" %}
**Note:** <mark style="color:red;">`responseType=token`</mark> for client-side flows (corresponding to the OAuth's implicit grant) is supported but is not recommended!
{% endhint %}

You'll also need to determine what permissions your application will request from users, and update the <mark style="color:red;">`scopes`</mark> query parameter accordingly. Aurinko provides granular authentication scopes that empower users with control over what level of access your application has to their data. See supported [Authentication scopes](/authentication/authentication-scopes) for details.

Here's an example of what this URL might look like once you've included all the correct query parameters:

```html
https://api.aurinko.io/v1/auth/authorize?clientId={appClientId}&
      &serviceType=Google
      &scopes=Mail.Read%20Mail.Send
      &responseType=code
      &returnUrl=...
      &state={myCustomState}
```

2. **User Consent**

Aurinko will present your user with the correct sign-in form based on the requested service type (Google, Office365, EWS). For Exchange users, the user has to enter a login name and an Exchange server URL.

3. **Getting the token**

Once the user has signed in and authorized your app's access, their browser will be redirected to the <mark style="color:red;">`returnUrl`</mark> you provided.

* **Implicit Grant** (<mark style="color:red;">`responseType=token`</mark>)

  If the authentication is successful Aurinko will include the hash fragment <mark style="color:red;">`#accessToken={accessToken}`</mark> with the account access token. That's it!

  *Example redirect URL*: <mark style="color:red;">`https://your-app.com/callback?#accessToken={token}&state={state}&status=success`</mark>

  We recommend storing the `accessToken` and then removing it from the hash fragment with JavaScript. This is the token you will provide as an <mark style="color:red;">`HTTP Bearer Auth`</mark> to make API calls on behalf of the user.
* **Authorization Code Grant** (<mark style="color:red;">`responseType=code`</mark>)

  If the authentication is successful Aurinko will include the `code` parameter in the query string.

  ﻿*Example redirect URL*: <mark style="color:red;">`https://your-app.com/callback?code={code}&state={state}&status=success`</mark>

  Make an HTTP POST call to <mark style="color:red;">`https://api.aurinko.io/v1/auth/token/{code}`</mark> to exchange the <mark style="color:red;">`code`</mark> for an <mark style="color:red;">`access_token`</mark>.

```bash
    curl -u ClientId:Secret -X POST https://api.aurinko.io/v1/auth/token/{code}
```

*Response:*

```json
{
	"accountId": 123,
	"accessToken": "aurinko-account-token",
}
```

\
See [/auth/token](https://apirefs.aurinko.io/#tag/Auth/operation/getAccessTokenByCode) for details. Make sure to securely store the <mark style="color:red;">`accessToken`</mark> and provide it as the <mark style="color:red;">`HTTP Bearer Auth`</mark> token to make API calls on behalf of the user (see [Authentication](https://apirefs.aurinko.io/#section/Authentication) details).


# User ОАuth Flow

Aurinko's User OAuth Flow enables user-delegated authorization, producing a user session token or httpOnly cookie for managing application user sessions.

Aurinko provides multiple Unified OAuth Flows that аre backed by providers' OAuth2 (i.e. Google, Office 365, Zoho Mail, Salesforce, HubSpot, SugarCRM) or by secure password-based authentication (i.e. MS Exchange, IMAP accounts).

## User OAuth Flow

***

This flow uses a user-delegated authorization and produces an Aurinko User with a user session token or httpOnly cookie. This flow is designed for managing application users (user sessions).

The user session token <mark style="color:red;">`userSession`</mark> or the httpOnly cookie is used to access the app user session and all its linked accounts. Two main operations are supported:

* Authorizing a primary account and initializing a user session (use <mark style="color:red;">`&accountRole=primary`</mark> parameter)
* Authorizing a secondary account for an existing user (use <mark style="color:red;">`&accountRole=secondary`</mark> parameter)

Some key terms you'll encounter while integrating with Aurinko's OAuth2 flow:

#### **Final Callback URL (returnUrl)**

The final callback URL, also known as <mark style="color:red;">`returnUrl`</mark>, is the URL provided by your application and specified when calling the <mark style="color:red;">`/authorize`</mark> API method within Aurinko. This is where Aurinko will redirect the user after successful authorization. It's crucial to register this URL within the Aurinko settings for your application.

#### Intermediate Redirect URL

The intermediate redirect URL is a temporary landing page used during the OAuth2 flow. By default, Aurinko uses <mark style="color:red;">`https://api.aurinko.io/v1/auth/callback`</mark> for this purpose. However, developers have the flexibility to customize this URL within the Aurinko settings for their application.

The following diagram shows a custom OAuth flow with your own intermediate redirect URL.&#x20;

<figure><img src="/files/wZOTmjrD9VEtHDc9hfLz" alt=""><figcaption></figcaption></figure>

1. **Authorization request**

From your application, redirect users to <mark style="color:red;">`https://api.aurinko.io/v1/auth/authorizeUser`</mark>, with the query parameters used by the Account OAuth and specify the additional <mark style="color:red;">`&accountRole=primary`</mark> parameter. Set <mark style="color:red;">`responseType`</mark> to <mark style="color:red;">`code`</mark> or <mark style="color:red;">`cookie`</mark> (default value if not set).

*Here's an example authorization request for creating a user* :

```html
https://api.aurinko.io/v1/auth/authorizeUser?clientId={appClientId}
    &accountRole=primary
    &serviceType=Google
    &scopes=Mail.Read%20Mail.Send
    &returnUrl=...
    &state={state} 
```

*Adding a secondary account (assuming the user session cookie is already set):*

```html
https://api.aurinko.io/v1/auth/authorizeUser?clientId={appClientId}
    &accountRole=secondary
    &serviceType=Hubspot
    &returnUrl=...
    &state={state} 
```

2. **User Consent**

Aurinko will present your user with the correct sign-in form based on the requested service type (Google, Office365, EWS). For Exchange users, the user has to enter a login name and an Exchange server url.

3. **Getting the user session**

Once the user has signed in and authorized your app's access, their browser will be redirected to the <mark style="color:red;">`returnUrl`</mark> you provided.

* **Cookie Mode** (<mark style="color:red;">`responseType=cookie`</mark>)

  If your authentication was successful Aurinko will set a secure httpOnly session cookie before redirecting to you returnUrl.

  *Example redirect URL*: <mark style="color:red;">`https://your-app.com/callback?state={state}&status=success`</mark>
* **Authorization Code Mode** (<mark style="color:red;">`responseType=code`</mark>)

  If your authentication was successful Aurinko will include the `code` parameter in the query string.

  *Example redirect URL*: <mark style="color:red;">`https://your-app.com/callback?code={code}&state={state}&status=success`</mark>

  Make an HTTP POST call to <mark style="color:red;">`https://api.aurinko.io/v1/auth/token/{code)}`</mark> to exchange the <mark style="color:red;">`code`</mark> for a <mark style="color:red;">`userSession`</mark> and <mark style="color:red;">`userId`</mark>.

```bash
    curl -u ClientId:Secret -X POST https://api.aurinko.io/v1/auth/token/{code}
```

*Response:*

```json
{
    "accountId": 123,
    "accessToken": "aurinko-access-token",
    "userId": "user-id-xyz",
    "userSession": "user-session-token"
 }
```

See [/auth/token](https://apirefs.aurinko.io/#tag/Auth/operation/getAccessTokenByCode) for details. Make sure to securely store the <mark style="color:red;">`userSession`</mark> and provide it as an API Key in the <mark style="color:red;">`X-Aurinko-Session`</mark> header to make API calls on behalf of the user (see [Authentication](https://apirefs.aurinko.io/#section/Authentication) details).


# Service Account OAuth Flow

Aurinko's Service Account OAuth Flow provides admin-level access via OAuth2, generating a service account and access token for secure API interactions.

Aurinko provides multiple Unified OAuth Flows backed by providers’ OAuth2 (i.e. Google, Office 365, Zoho Mail, Salesforce, HubSpot, SugarCRM) or by secure password-based authentication (i.e. MS Exchange, IMAP accounts).

## Service Account OAuth Flow

***

This flow is for gaining admin/app-level access, usually requiring a Google/Office 365 admin authorization. See the following instructions related to service accounts: [Service accounts](/authentication/service-accounts), [Setting up G Suite service account](http://helpdocs.yoxel.com/salesforce/setting-up-g-suite-service-account), and [Setting up Office 365 daemon app registration](/authentication/service-accounts/setting-up-office-365-daemon-app-registration).

The flow produces an Aurinko <mark style="color:red;">`service account`</mark> and an access token.

Some key terms you'll encounter while integrating with Aurinko's OAuth2 flow:

#### **Final Callback URL (returnUrl)**

The final callback URL, also known as <mark style="color:red;">`returnUrl`</mark>, is the URL provided by your application and specified when calling the <mark style="color:red;">`/authorize`</mark> API method within Aurinko. This is where Aurinko will redirect the user after successful authorization. It's crucial to register this URL within the Aurinko settings for your application.

#### Intermediate Redirect URL

The intermediate redirect URL is a temporary landing page used during the OAuth2 flow. By default, Aurinko uses <mark style="color:red;">`https://api.aurinko.io/v1/auth/callback`</mark> for this purpose. However, developers have the flexibility to customize this URL within the Aurinko settings for their application.

The following diagram shows a custom OAuth flow with your own intermediate redirect URL.&#x20;

<figure><img src="/files/wZOTmjrD9VEtHDc9hfLz" alt=""><figcaption></figcaption></figure>

1. **Authorization request**

From your application, redirect users to <mark style="color:red;">`https://api.aurinko.io/v1/auth/authorizeDaemon`</mark>, with the query parameters detailed in [/auth/authorizeDaemon](https://apirefs.aurinko.io/#tag/Auth/operation/authorizeDaemon). You'll have to set <mark style="color:red;">`responseType=code`</mark>.

You'll also need to determine what permissions your application will request from users, and update the <mark style="color:red;">`scopes`</mark> query parameter accordingly. Aurinko provides granular authentication scopes that empower users with control over what level of access your application has to their data. See supported [Authentication scopes](/authentication/authentication-scopes) for details.

Here's an example of what this URL might look like once you've included all the correct query parameters:

```html
https://api.aurinko.io/v1/auth/authorizeDaemon?clientId={appClientId}&
    &serviceType=Google
    &scopes=Mail.Read%20Mail.Send
    &responseType=token
    &returnUrl=...
    &state={myCustomState}
```

***Redirect URI: Redirect page vs. Custom domain alias***

In case your Microsoft app registration requires redirect URIs to be under a domain you own the default Aurinko's Redirect URI <https://api.aurinko.io/v1/auth/callback> may not work for you in production.

<div data-full-width="true"><figure><img src="/files/7YXqxNofltV05kq6jEWs" alt=""><figcaption></figcaption></figure></div>

You have two options:

* Contact us about provisioning a domain alias for your Aurinko app so you can use a URL like <mark style="color:red;">`https://aurinko.mydomain/v1/auth/callback`</mark>
* Create your **intermediate redirect** page to use for redirecting all calls to Aurinko's <mark style="color:red;">`https://api.aurinko.io/v1/auth/callback`</mark> with the URL parameters <mark style="color:red;">`state`</mark>, <mark style="color:red;">`code`</mark>, and <mark style="color:red;">`scope`</mark>. See the corresponding OAuth flow in the following diagram:

<figure><img src="/files/a7SGeBOR97RniQCfSqGu" alt=""><figcaption></figcaption></figure>

2. **User Consent**

Aurinko will present your user with the correct sign-in form based on the requested service type (Google, Office365, EWS). For Exchange users, the user has to enter a login name and an Exchange server URL.

3. **Getting the token**

Once the user has signed in and authorized your app's access, their browser will be redirected to the <mark style="color:red;">`returnUrl`</mark> you provided.

* **Authorization Code Grant** (<mark style="color:red;">`responseType=code`</mark>)

  If your authentication was successful Aurinko will include the `code` parameter in the query string.

  *Example redirect URL*: <mark style="color:red;">`https://your-app.com/callback?code={code}&state={state}&status=success`</mark>

  Make an HTTP POST call to <mark style="color:red;">`https://api.aurinko.io/v1/auth/token/{code}`</mark> to exchange the <mark style="color:red;">`code`</mark> for an <mark style="color:red;">`access_token`</mark>.

```bash
curl -u ClientId:Secret -X POST https://api.aurinko.io/v1/auth/token/{code}
```

*Response:*

```json
{
    "accountId": 123,
    "accessToken": "aurinko-account-token",
}
```

See [/auth/token](https://apirefs.aurinko.io/#tag/Auth/operation/getAccessTokenByCode) for details. Make sure to securely store the <mark style="color:red;">`accessToken`</mark> and provide it as the <mark style="color:red;">`HTTP Bearer Auth`</mark> token to make API calls on behalf of the account (see [Authentication](https://apirefs.aurinko.io/#section/Authentication) details).


# Authentication scopes

Aurinko's authentication scopes enhance security by allowing granular permission control. Limit access by using the scopes parameter during authentication.

Aurinko supports granular authentication scopes to improve security for your end-users. You can limit the permissions and data Aurinko requests during authentication by using the  <mark style="color:red;">`scopes`</mark> parameter with the <mark style="color:red;">`/auth/authorize`</mark> endpoint.

To remain secure, Aurinko strongly recommends passing only the scopes that your application needs when authenticating a user. Please reference the table below when updating your authentication code to make sure your application requests the minimal amount of access necessary for your app's functionality.

<table><thead><tr><th width="242">Aurinko scope</th><th>Description</th></tr></thead><tbody><tr><td><code>Mail.ReadWrite</code></td><td>Read and modify all messages, threads, file attachments, and read email metadata like headers. Does not include send.</td></tr><tr><td><code>Mail.Read</code></td><td>Read all messages, threads, file attachments, drafts, and email metadata like headers - no write operations.</td></tr><tr><td><code>Mail.Send</code></td><td>Send messages only. No read or modify privileges on users' emails.</td></tr><tr><td><code>Mail.Drafts</code></td><td>Create, read, update, and delete drafts. Send messages and drafts.</td></tr><tr><td><code>Calendar.ReadWrite</code></td><td>Read and modify calendars and events.</td></tr><tr><td><code>Calendar.Read</code></td><td>Read calendars and events.</td></tr><tr><td><code>Contacts.ReadWrite</code></td><td>Read and modify contacts.</td></tr><tr><td><code>Contacts.Read</code></td><td>Read contacts.</td></tr><tr><td><code>Tasks.ReadWrite</code></td><td>Read and modify tasks.</td></tr><tr><td><code>Tasks.Read</code></td><td>Read tasks.</td></tr></tbody></table>

### Example

***

To give an example, if your app has functionality for users to send and read messages, but not modify messages, you would use the following scopes:  <mark style="color:red;">`Mail.ReadOnly`</mark>, <mark style="color:red;">`Mail.Send`</mark>.

Here is an example request showing how your app might pass these scopes:

```bash
curl -X GET https:/api.aurinko.io/v1/auth/authorize
    -d clientId='a8b7c6d5e4f3g2h1'
    -d serviceType='Office365'
    -d scopes='Mail.Read,Mail.Send'
    -d returnUrl='https://yourapp.com/aurinko-redirect'
    -d state='CustomStateString'
```

Any tokens obtained this way have a limited scope, so you won't be able to access out-of-scope endpoints with them.


# Authorized return URLs

Specify authorized redirect URLs for Google or Azure OAuth apps to enable Aurinko's authorization flow. Use Aurinko's or your domain URL for callbacks.

One of required inputs for your Google or Azure OAuth app registration is the authorized redirect or return URIs. Here is an example from a Google developer console:

<div data-full-width="true"><figure><img src="https://s3.amazonaws.com/helpscout.net/docs/assets/5dd72e4d2c7d3a7e9ae44753/images/5f3724c32c7d3a352e90dcb5/file-m2K6SjbM0Z.jpg" alt=""><figcaption></figcaption></figure></div>

For Aurinko to be able to initiate and complete your app's authorization flow an Aurinko hosted url has to be specified in your Google or Azure AD app registration. Office 365 /  Azure AD users could simply use <mark style="color:red;">`https://api.aurinko.io/v1/auth/callback`</mark> but Google would not allow urls from unverified domains and you can't verify aurinko.io domain as you don't own it. Office 365 user may also want to use an url from  domain they own as in certain scenarios that domain is shown in the app's consent window.\ <br>

#### Callback configuration

***

Provision your own URL and make your server redirect all callback requests to Aurinko at <mark style="color:red;">`https://api.aurinko.io/v1/auth/callback`</mark>. It's important to clone all query parameters in a redirect, like `code`, `state`, `error`, ...\
When choosing this approach you also need to tell Aurinko your own return URL, which is done on the app settings page, in the Google OAuth or Office 365 OAuth sections.


# Google OAuth setup

Set up Google OAuth by creating a project and client ID in the Developer Console. Enable required APIs and configure your app for Aurinko.

In order to connect Google accounts to Aurinko through OAuth2 authentication you'll need to create your own Google Project and OAuth client ID. You will configure Aurinko to use this client ID. If you have any trouble creating a Google Project and OAuth client ID, get in touch with  [support@aurinko.io](mailto:mailto:support@aurinko.io) and we'd be happy to help you out!

### **Create a Google Project**

***

To get started, head over to <https://console.developers.google.com/>. You will be prompted to log in with a Google account if you're not already logged in with one. If you don't have a Google account, you can create one at <https://accounts.google.com/signup/>.

Use the selector at the top (next to the Google logo) and click the 'NEW PROJECT' button in the popup window that opens.

<div data-full-width="true"><figure><img src="https://s3.amazonaws.com/helpscout.net/docs/assets/5dd72e4d2c7d3a7e9ae44753/images/5e08105204286364bc934af3/file-0Ff0FtVciY.jpg" alt=""><figcaption></figcaption></figure></div>

Name your project and click **"CREATE"**.

<div data-full-width="true"><figure><img src="https://s3.amazonaws.com/helpscout.net/docs/assets/5dd72e4d2c7d3a7e9ae44753/images/5e0810f02c7d3a7e9ae59382/file-4apQyUobao.jpg" alt=""><figcaption></figcaption></figure></div>

It may take up to a minute or two for Google to finish creating the project.

### **Enable APIs**

***

Click the **"ENABLE APIS AND SERVICES"** button.

<div data-full-width="true"><figure><img src="https://s3.amazonaws.com/helpscout.net/docs/assets/5dd72e4d2c7d3a7e9ae44753/images/5e0812162c7d3a7e9ae59385/file-ezce8mtGJd.jpg" alt=""><figcaption></figcaption></figure></div>

You'll be presented with the following search box:

<div data-full-width="true"><figure><img src="https://s3.amazonaws.com/helpscout.net/docs/assets/5dd72e4d2c7d3a7e9ae44753/images/5e08129904286364bc934af4/file-5YTx5IteAr.jpg" alt=""><figcaption></figcaption></figure></div>

Type "gmail" into the search box and click on the **"Gmail API"** card once it appears.

<div data-full-width="true"><figure><img src="https://s3.amazonaws.com/helpscout.net/docs/assets/5dd72e4d2c7d3a7e9ae44753/images/5e0812ff2c7d3a7e9ae59386/file-9W6gMAt3TU.jpg" alt=""><figcaption></figcaption></figure></div>

Click the large blue "**ENABLE"** button next to the Gmail logo.

<div data-full-width="true"><figure><img src="https://s3.amazonaws.com/helpscout.net/docs/assets/5dd72e4d2c7d3a7e9ae44753/images/5e08135604286364bc934af5/file-FV5bPdzIdd.jpg" alt=""><figcaption></figcaption></figure></div>

You'll find yourself on the following page. Click the search box in the center of the top bar.

<div data-full-width="true"><figure><img src="https://s3.amazonaws.com/helpscout.net/docs/assets/5dd72e4d2c7d3a7e9ae44753/images/5e0813d704286364bc934af6/file-r019jZBFRU.jpg" alt=""><figcaption></figcaption></figure></div>

Type "calendar" and click on **"Google Calendar API"** once it appears.

<div data-full-width="true"><figure><img src="https://s3.amazonaws.com/helpscout.net/docs/assets/5dd72e4d2c7d3a7e9ae44753/images/5e0814592c7d3a7e9ae59389/file-6nyxIUYqrN.jpg" alt=""><figcaption></figcaption></figure></div>

Click **"ENABLE"** for the Google Calendar API.

<div data-full-width="true"><figure><img src="https://s3.amazonaws.com/helpscout.net/docs/assets/5dd72e4d2c7d3a7e9ae44753/images/5e0814dc2c7d3a7e9ae5938c/file-coR0m73mH3.jpg" alt=""><figcaption></figcaption></figure></div>

In the similar manner find and enable Contacts API, Google People API, and Tasks API.

### **Configure OAuth consent screen**

***

The last step to do in the Google Developer Console is to create a credential for OAuth, starting with configuring the consent screen. Click the **"CREATE CREDENTIALS"** button.

<div data-full-width="true"><figure><img src="https://s3.amazonaws.com/helpscout.net/docs/assets/5dd72e4d2c7d3a7e9ae44753/images/5e0816232c7d3a7e9ae5938d/file-Y74fQhIo7T.jpg" alt=""><figcaption></figcaption></figure></div>

On the next screen, click "client ID".

<div data-full-width="true"><figure><img src="https://s3.amazonaws.com/helpscout.net/docs/assets/5dd72e4d2c7d3a7e9ae44753/images/5e08168304286364bc934af7/file-Cy2tTimoYw.jpg" alt=""><figcaption></figcaption></figure></div>

Then click **"Configure consent screen"**.

<div data-full-width="true"><figure><img src="https://s3.amazonaws.com/helpscout.net/docs/assets/5dd72e4d2c7d3a7e9ae44753/images/5e0816d304286364bc934af8/file-ISKpV9e1UO.jpg" alt=""><figcaption></figcaption></figure></div>

Choose "Internal" or "External" user type. An "Internal" user type Google application will only allow access to users from your organization ( <mark style="color:red;">`@your-organization.com`</mark>). This type of application allows you to entirely skip the App Verification and Security Review processes required by Google for public-access applications, but limits which accounts can authenticate to your application.

<div data-full-width="true"><figure><img src="https://s3.amazonaws.com/helpscout.net/docs/assets/5dd72e4d2c7d3a7e9ae44753/images/5e0817f92c7d3a7e9ae5938e/file-GBHMgCF63r.jpg" alt=""><figcaption></figcaption></figure></div>

On the following page, fill out the "Application name" field.

<div data-full-width="true"><figure><img src="https://s3.amazonaws.com/helpscout.net/docs/assets/5dd72e4d2c7d3a7e9ae44753/images/5e08196f2c7d3a7e9ae59390/file-uD0m92W592.jpg" alt=""><figcaption></figcaption></figure></div>

You'll need to determine what Google scopes you add to your consent screen based on your application's behavior. Please reference this mapping to see how Aurinko scopes will map to Google scopes during the authentication process:

| Aurinko scope        | Google API permission                                                                                    |
| -------------------- | -------------------------------------------------------------------------------------------------------- |
| `Mail.ReadOnly`      | [`https://www.googleapis.com/auth/gmail.readonly`](https://www.googleapis.com/auth/gmail.readonly)       |
| `Mail.ReadWrite`     | [`https://www.googleapis.com/auth/gmail.modify`](https://www.googleapis.com/auth/gmail.modify)           |
| `Mail.Draft`         | [`https://www.googleapis.com/auth/gmail.compose`](https://www.googleapis.com/auth/gmail.compose)         |
| `Mail.Send`          | [`https://www.googleapis.com/auth/gmail.send`](https://www.googleapis.com/auth/gmail.send)               |
| `Calendar.ReadOnly`  | [`https://www.googleapis.com/auth/calendar.readonly`](https://www.googleapis.com/auth/calendar.readonly) |
| `Calendar.ReadWrite` | [`https://www.googleapis.com/auth/calendar`](https://www.googleapis.com/auth/calendar)                   |
| `Contacts.ReadOnly`  | [`https://www.googleapis.com/auth/contacts.readonly`](https://www.googleapis.com/auth/contacts.readonly) |
| `Contacts.ReadWrite` | [`https://www.googleapis.com/auth/contacts`](https://www.googleapis.com/auth/contacts)                   |
| `Tasks.ReadOnly`     | [`https://www.googleapis.com/auth/tasks.readonly`](https://www.googleapis.com/auth/tasks.readonly)       |
| `Tasks.ReadWrite`    | [`https://www.googleapis.com/auth/tasks`](https://www.googleapis.com/auth/tasks)                         |

Then add all required Google scopes, i.e. gmai.modify, gmail.send, calendar, contacts, tasks.

<div data-full-width="true"><figure><img src="https://s3.amazonaws.com/helpscout.net/docs/assets/5dd72e4d2c7d3a7e9ae44753/images/5e081d402c7d3a7e9ae59393/file-7EpfR1Bme9.jpg" alt=""><figcaption></figcaption></figure></div>

Finally, add your app's domain to the "Authorized domains" field.

<div data-full-width="true"><figure><img src="https://s3.amazonaws.com/helpscout.net/docs/assets/5dd72e4d2c7d3a7e9ae44753/images/5e08203004286364bc934b03/file-inxsshQ2Al.jpg" alt=""><figcaption></figcaption></figure></div>

&#x20;Scroll down to the bottom of the page and click the blue "Save" button!

### **Create an OAuth credential**

***

Click **"Create credentials"** and select **"OAuth client ID"** from the drop-down menu.

<div data-full-width="true"><figure><img src="https://s3.amazonaws.com/helpscout.net/docs/assets/5dd72e4d2c7d3a7e9ae44753/images/5e0820da04286364bc934b05/file-oZZ7TxbCMk.jpg" alt=""><figcaption></figcaption></figure></div>

Fill out the form choosing the appropriate application type based on your application, and be sure to read the article regarding redirect URIs.

<div data-full-width="true"><figure><img src="https://s3.amazonaws.com/helpscout.net/docs/assets/5dd72e4d2c7d3a7e9ae44753/images/5e0a55da04286364bc93532b/file-INUoKNGwIq.jpg" alt=""><figcaption></figcaption></figure></div>

Then click the blue "Create" button at the bottom of the screen.

You'll be presented with a page that shows your new OAuth client ID and Secret. Keep the page open, as you'll need the credentials in the next step.

### **Configure Aurinko to use your Google OAuth credentials**

***

Head on over to [Aurinko portal](https://app.aurinko.io/) and log in.

Select your app at the top, choose Settings menu and switch to the GOOGLE tab.&#x20;

<div data-full-width="true"><figure><img src="/files/ows35K7VsaiGx2ffNDZ1" alt=""><figcaption></figcaption></figure></div>

Copy-paste your Google OAuth client ID and Secret from the Google Developer Console and click "Save".

**You are now all set to start connecting Google accounts to Aurinko!**


# Office 365 OAuth setup

Set up Office 365 OAuth by registering your app in Azure Active Directory. Configure API permissions and upload your credentials to Aurinko.

In order to connect Office 365 accounts to Aurinko through OAuth2 authentication you'll need to register your app in Azure Active Directory (AAD). You will then configure Aurinko to use your AAD application Id. If you have any trouble registering your application in Azure AD, get in touch with  [support@aurinko.io](mailto:mailto:support@aurinko.io) and we'd be happy to help you out!

Create your [free Microsoft Azure](https://azure.microsoft.com/en-us/free/) account if you don't already have one. You'll use this account to create the Microsoft developer application that is used for authenticating end users via OAuth with Aurinko.

### **Creating an app registration**

***

The first step is to create an app that will be used to authenticate your customers to Office365. To do that we're going to use the Azure web portal. Log into [https://portal.azure.com](https://portal.azure.com/) and go to Azure Active Directory service.

<div data-full-width="true"><figure><img src="https://s3.amazonaws.com/helpscout.net/docs/assets/5dd72e4d2c7d3a7e9ae44753/images/5e0a599c2c7d3a7e9ae59c8f/file-ITfUR7SGeL.jpg" alt=""><figcaption></figcaption></figure></div>

Then click **"New Registration"**.

<div data-full-width="true"><figure><img src="https://s3.amazonaws.com/helpscout.net/docs/assets/5dd72e4d2c7d3a7e9ae44753/images/5e0a653a04286364bc9353d1/file-t9ttrT40ax.jpg" alt=""><figcaption></figcaption></figure></div>

You are going to be presented with the following screen. Set your name to your app's name (this is going to be customer visible). Set the audience for this app to *"Account in any organizational directory and personal Microsoft accounts"* to be able to log into any Office 365 account (business and personal). You can also restrict it to internal accounts (*"Accounts in this organizational directory only"*) if you're building an internal app. Then, specify a redirect URI, read [this article](/authentication/authorized-return-urls) for more information.

<div data-full-width="true"><figure><img src="https://s3.amazonaws.com/helpscout.net/docs/assets/5dd72e4d2c7d3a7e9ae44753/images/5e0a66082c7d3a7e9ae59d04/file-J6s0cfrZes.jpg" alt=""><figcaption></figcaption></figure></div>

Congrats, you've just registered your app!&#x20;

<div data-full-width="true"><figure><img src="https://s3.amazonaws.com/helpscout.net/docs/assets/5dd72e4d2c7d3a7e9ae44753/images/5e0a689d04286364bc9353f4/file-eR3USqoRZN.jpg" alt=""><figcaption></figcaption></figure></div>

### **Specifying API permissions**

***

Now, let's make sure your app has the right API permissions. To do that, head to the "API permissions" panel and click **"Add a permission".**

<div data-full-width="true"><figure><img src="https://s3.amazonaws.com/helpscout.net/docs/assets/5dd72e4d2c7d3a7e9ae44753/images/5e0a6b7204286364bc935407/file-dQ5KNyNmPw.jpg" alt=""><figcaption></figcaption></figure></div>

Choose Microsoft Graph set of permissions

<div data-full-width="true"><figure><img src="https://s3.amazonaws.com/helpscout.net/docs/assets/5dd72e4d2c7d3a7e9ae44753/images/5e0a6c0a2c7d3a7e9ae59d4e/file-FOAuckn1fN.jpg" alt=""><figcaption></figcaption></figure></div>

You'll need to determine what Graph API permissions you add to your consent screen based on your application's behavior. Please reference this mapping to see how Aurinko scopes will map to Graph API permissions during the [authentication](/authentication/oauth-flow) process:

| Aurinko scope        | Graph API permission  |
| -------------------- | --------------------- |
| `Mail.ReadOnly`      | `Mail.Read`           |
| `Mail.ReadWrite`     | `Mail.ReadWrite`      |
| `Mail.Draft`         | `Mail.ReadWrite`      |
| `Mail.Send`          | `Mail.Send`           |
| `Calendar.ReadOnly`  | `Calendars.Read`      |
| `Calendar.ReadWrite` | `Calendars.ReadWrite` |
| `Contacts.ReadOnly`  | `Contacts.Read`       |
| `Contacts.ReadWrite` | `Contacts.ReadWrite`  |
| `Tasks.ReadOnly`     | `Tasks.Read`          |
| `Tasks.ReadWrite`    | `Tasks.ReadWrite`     |

Then add all required **Delegated permissions**, i.e. <mark style="color:red;">`Calendars.ReadWrite`</mark>, <mark style="color:red;">`Contacts.ReadWrite`</mark>, <mark style="color:red;">`Mail.ReadWrite`</mark>, <mark style="color:red;">`Mail.Send`</mark>, <mark style="color:red;">`Tasks.ReadWrite`</mark>.

Additionally, ensure that the application is configured with the following OAuth scopes: <mark style="color:red;">`offline_access`</mark>, <mark style="color:red;">`openid`</mark>, <mark style="color:red;">`email`</mark>, <mark style="color:red;">`profile`</mark>, <mark style="color:red;">`MailboxSettings.Read`</mark>, <mark style="color:red;">`User.Read`</mark>.

{% hint style="warning" %}
**Note:** Aurinko requests these permissions implicitly.
{% endhint %}

<figure><img src="/files/HrQOpPWW9lqlO1JVxwvR" alt=""><figcaption></figcaption></figure>

This is what your application permissions screen should look like

<div data-full-width="true"><figure><img src="https://s3.amazonaws.com/helpscout.net/docs/assets/5dd72e4d2c7d3a7e9ae44753/images/5e0a700e04286364bc93542d/file-OhDnYluRmu.jpg" alt=""><figcaption></figcaption></figure></div>

### **Creating OAuth credentials**

***

Head to the "Certificates & secrets" panel and click **"New client secret".**

<div data-full-width="true"><figure><img src="https://s3.amazonaws.com/helpscout.net/docs/assets/5dd72e4d2c7d3a7e9ae44753/images/5e0a70d004286364bc935434/file-ugh5uDSCm2.jpg" alt=""><figcaption></figcaption></figure></div>

Give the secret a name and an expiration date of "never", then click **"Add"**.

<div data-full-width="true"><figure><img src="https://s3.amazonaws.com/helpscout.net/docs/assets/5dd72e4d2c7d3a7e9ae44753/images/5e0a71af2c7d3a7e9ae59d8a/file-vrUoKPtMCg.jpg" alt=""><figcaption></figcaption></figure></div>

Copy the secret somewhere safe. You won't be able to retrieve it from this page afterwards!

<div data-full-width="true"><figure><img src="https://s3.amazonaws.com/helpscout.net/docs/assets/5dd72e4d2c7d3a7e9ae44753/images/5e0a72522c7d3a7e9ae59d94/file-cX1og6NWw1.jpg" alt=""><figcaption></figcaption></figure></div>

Finally, copy the app id and secret and upload them to the Aurinko portal.

### **Configure Aurinko to use your Office 365 OAuth credentials**

***

Head on over to [Aurinko portal](https://app.aurinko.io/) and log in.

Select your app at the top, choose Settings menu and switch to the OFFICE 365 tab.

<div data-full-width="true"><figure><img src="/files/qtrWR9IdJX3FyKdEQqU5" alt=""><figcaption></figcaption></figure></div>

Copy-paste your Azure AD OAuth Client ID and Secret from the Azure AD app page and click "Save".

**You are now all set to start connecting Office 365 accounts to Aurinko!**


# ZOHO OAuth setup

Set up Zoho OAuth by registering your app in the ZOHO API Console. Configure API permissions and upload your credentials to Aurinko.

To connect Zoho accounts to Aurinko through OAuth2 authentication, you'll need to register your application in Zoho's API Console. Afterward, you can configure Aurinko to use your Zoho application credentials. If you encounter any issues registering your application, reach out to [support@aurinko.io](mailto:mailto:support@aurinko.io) for assistance.

### **Creating a ZOHO Project**

***

Begin by visiting to the [Zoho API Console](https://api-console.zoho.com/) (use <https://api-console.zoho.eu/> if you're based in Europe). Sign in with your Zoho account, or create one if you don't already have it.

Click **Add Client** (or similar option based on your interface) and select the "Server-Based Application" Client Type.

<div data-full-width="true"><figure><img src="/files/yMODE91HMVulNzsIXxLb" alt=""><figcaption></figcaption></figure></div>

You’ll see a registration form:

* Set **Client Type** to **Server-Based Application**.
* Set **Name** to your app’s name (this name will be visible to users).
* Enter **Homepage URL**&#x20;
* Enter the **Redirect URI** where Zoho will redirect users after they authorize access. This URL is essential for completing the OAuth flow. Read [this article](https://docs.aurinko.io/~/changes/yv1VO4PXj9jgHpMsK3Io/authentication/authorized-return-urls) for more information.

<figure><img src="/files/g7chHiA6Xjk5OikjNWeY" alt="" width="563"><figcaption></figcaption></figure>

Congratulations, you’ve just registered your app!

<div data-full-width="true"><figure><img src="/files/Gs8YwExSMwjxK7T6s01F" alt=""><figcaption></figcaption></figure></div>

### Use the Same OAuth Credentials Across All Data Centers

***

To ensure your Zoho integration works globally, go to **Zoho Developer Console → Settings**, and make sure to enable the checkbox: **“Use the same OAuth credentials for all data centers”**.

This setting allows your extension or integration to function seamlessly across different Zoho domains (e.g., `.com`, `.eu`, `.in`), using a single set of OAuth credentials.\
Without this option enabled, your app may only work within the region where it was created.

<figure><img src="/files/oz3SPLVPmjJaBiPxqHlU" alt=""><figcaption></figcaption></figure>

### **Specifying API Permissions (Scopes)**

***

Next, set the required API permissions (Scopes) for your application.

In the **Scope** section, choose the necessary permissions based on the features you want to access. Here’s an example of how Zoho Scopes align with Aurinko’s permissions:

<table><thead><tr><th width="242">Aurinko Scope</th><th>Zoho API permission</th></tr></thead><tbody><tr><td><code>Mail.Read</code></td><td><code>mailScopes("READ")</code></td></tr><tr><td><code>Mail.ReadWrite</code></td><td><code>mailScopes("CREATE", "READ", "UPDATE", "DELETE")</code></td></tr><tr><td><code>Mail.Drafts</code></td><td><code>mailScopes("CREATE")</code></td></tr><tr><td><code>Mail.Send</code></td><td><code>mailScopes("CREATE")</code></td></tr></tbody></table>

Add all required permissions for your application’s functionality.

### **Creating OAuth Credentials**

***

Head to **Client Secret** in your Zoho application and click **Generate** to create a new client secret.

Copy the client secret and save it securely, as you won’t be able to retrieve it later.

Finally, copy the **Client ID** and **Client Secret** from the Zoho app page.

<figure><img src="/files/PmXjlToBuL1Ar7au48WN" alt="" width="563"><figcaption></figcaption></figure>

### **Configure Aurinko to Use Your Zoho OAuth Credentials**

***

Log in to the [Aurinko portal](https://app.aurinko.io/), select your app, navigate to **Settings**, and switch to the **ZOHO** tab.<br>

<div data-full-width="true"><figure><img src="/files/HMN4lTLh8Tl6sEshIR8L" alt=""><figcaption></figcaption></figure></div>

Copy-paste your Zoho OAuth **Client ID** and **Client Secret**, then click **Save**.

**You’re now ready to start connecting Zoho accounts to Aurinko!**


# Service accounts

Service accounts enable server-to-server access to web resources without user involvement. Aurinko supports G Suite, MS Exchange, and Office 365.

### **What is a Service account?**

***

A service account (or daemon authorization) is a way to access web-hosted resources for server-to-server interactions that must run in the background, without immediate interaction with a user. They are useful for organizations that need to connect multiple accounts with Aurinko without interrupting end users to complete their account authentications.

### **Which providers does Aurinko currently support?**

***

Aurinko is currently able to onboard G Suite and MS Exchange service accounts as well as Office 365 "global admin" based app registrations. All Aurinko API's (email, calendar, contacts) support this.

### **Service Account Setup**

***

There are 3 main steps to using service accounts for authentication.

1. Your customer's IT Administrator does a one-time configuration of service accounts for their G Suite or Office 365 Organization, or MS Exchange server and shares the credentials with you. For more details please refer to the following articles:

* Setting up G Suite service account
* Setting up Office 365 daemon app registration
* Setting up MS Exchange service account

2. **G Suite or MS Exchange**: Upload the service account credentials to Aurinko from the Account/SERVICE tab:

<div data-full-width="true"><figure><img src="/files/SShNIAYmrsDPBJPt2rwx" alt=""><figcaption></figcaption></figure></div>

3. **Office 365**: specify your daemon app registration details in the Application settings / Office 365 OAuth (Daemon):

<div data-full-width="true"><figure><img src="/files/oxxKK59KYUiVdtMDCw4H" alt=""><figcaption></figcaption></figure></div>

Use the [service/daemon account authentication API](https://apirefs.aurinko.io/#operation/authorizeDaemon) to add a new service account.

4. Use the [managed accounts API](https://apirefs.aurinko.io/#tag/Managed-accounts) to add user accounts that will use a service account for authentications. Your application can then use the <mark style="color:red;">`managed accounts`</mark> to access user data.


# Setting up G Suite service account

Setting up a G Suite service account to generate credentials and delegate authority. Follow the steps in the Google API Console for configuration.

To generate service-account credentials, or to view the public credentials that you've already generated, do the following in your Google API Console:

1. Open the [Service accounts page](/authentication/service-accounts).
2. If prompted, select a project, or create a new one. Refer to [this article](/authentication/google-oauth-setup) if creating a new project, the following API's need to be enabled: Gmail API, Google Calendar API, Contacts API, Google People API, and Tasks API.
3. Click **Create service account**.

<div data-full-width="true"><figure><img src="https://s3.amazonaws.com/helpscout.net/docs/assets/5dd72e4d2c7d3a7e9ae44753/images/5f062d6904286306f80662ee/file-dbDE54UOkR.jpg" alt=""><figcaption></figcaption></figure></div>

4. Under **Service account details**, type a name, ID, and description for the service account, then click **Create**.

<div data-full-width="true"><figure><img src="https://s3.amazonaws.com/helpscout.net/docs/assets/5dd72e4d2c7d3a7e9ae44753/images/5f06307f2c7d3a10cbaa3bce/file-TVd6h5i5Tp.jpg" alt=""><figcaption></figcaption></figure></div>

5. Optional: Under **Service account permissions**, select the IAM roles to grant to the service account, then click **Continue**.
6. Optional: Under **Grant users access to this service account**, add the users or groups that are allowed to use and manage the service account.
7. From the main "Service accounts" screen select the newly created account

<div data-full-width="true"><figure><img src="https://s3.amazonaws.com/helpscout.net/docs/assets/5dd72e4d2c7d3a7e9ae44753/images/5f06332404286306f8066384/file-Xql5fiM9SF.jpg" alt=""><figcaption></figcaption></figure></div>

8. Use "EDIT" mode to activate "G Suite Domain-wide Delegation" and also copy the **Unique ID** (you will need it later). Click ADD KEY to create a new JSON key if there is no key yet (you will need to upload this key to Aurinko).  Then save the form.

<div data-full-width="true"><figure><img src="https://s3.amazonaws.com/helpscout.net/docs/assets/5dd72e4d2c7d3a7e9ae44753/images/5f06347404286306f80663a5/file-7uzn6eyQ00.jpg" alt=""><figcaption></figcaption></figure></div>

Now an administrator of the G Suite domain needs to delegate authority to the service account, using the Unique ID value you copied.

1. From your G Suite domain’s [Admin console](https://admin.google.com/), go to **Main menu menu > Security > Advanced settings \[API Controls].**
2. In the **Domain wide delegation** pane, select **Manage Domain Wide Delegation**.
3. Click **Add new**.

<div data-full-width="true"><figure><img src="https://s3.amazonaws.com/helpscout.net/docs/assets/5dd72e4d2c7d3a7e9ae44753/images/5f0638252c7d3a10cbaa3c8a/file-K1rKt1BSne.jpg" alt=""><figcaption></figcaption></figure></div>

4. In the **Client ID** field, enter the service account's **Unique ID** that you have copied.
5. In the **OAuth scopes (comma-delimited)** field, enter the list of scopes that your application should be granted access to. Aurinko API will need these scopes <https://www.googleapis.com/auth/gmai.modify>, \
   <https://www.googleapis.com/auth/gmail.send>, \
   <https://www.googleapis.com/auth/calendar>, \
   <https://www.googleapis.com/auth/contacts>, \
   <https://www.googleapis.com/auth/tasks>
6. Click **Authorize**.


# Setting up Office 365 daemon app registration

Set up an Office 365 daemon app registration to enable global admin authorizations, configure API permissions, and connect service accounts with Aurinko.

Setting up an Office 365 / Azure app registration that allows global admin authorizations (or daemon OAuth2 flow) is quite similar to the regular Azure app registration described in the article [Office 365 OAuth setup](/authentication/office-365-oauth-setup). Please follow "Creating an app registration" steps from that article if you have not created any app registrations yet or want to create a separate daemon app registration.

The following settings are specific to daemon app registrations (daemon OAuth2 flow).

### **Specifying API permissions**

***

Head to the "API permissions" panel and click "Add a permission".&#x20;

<div data-full-width="true"><figure><img src="https://s3.amazonaws.com/helpscout.net/docs/assets/5dd72e4d2c7d3a7e9ae44753/images/5f06475d04286306f80664f8/file-kF4BjKjgqT.jpg" alt=""><figcaption></figcaption></figure></div>

Choose Microsoft Graph set of permissions

<div data-full-width="true"><figure><img src="https://d33v4339jhl8k0.cloudfront.net/docs/assets/5dd72e4d2c7d3a7e9ae44753/images/5e0a6c0a2c7d3a7e9ae59d4e/file-FOAuckn1fN.jpg" alt=""><figcaption></figcaption></figure></div>

You'll need to determine what Graph API permissions you add to your consent screen based on your application's behavior. Please reference this mapping to see how Aurinko scopes will map to Graph API permissions during the [authentication](/authentication/oauth-flow) process:

| Aurinko scope        | Graph API permission  |
| -------------------- | --------------------- |
| `Mail.ReadOnly`      | `Mail.Read`           |
| `Mail.ReadWrite`     | `Mail.ReadWrite`      |
| `Mail.Send`          | `Mail.Send`           |
| `Calendar.ReadOnly`  | `Calendars.Read`      |
| `Calendar.ReadWrite` | `Calendars.ReadWrite` |
| `Contacts.ReadOnly`  | `Contacts.Read`       |
| `Contacts.ReadWrite` | `Contacts.ReadWrite`  |

Then add all required **Application** permissions, i.e. <mark style="color:red;">`Calendars.ReadWrite`</mark>, <mark style="color:red;">`Contacts.ReadWrite`</mark>, <mark style="color:red;">`Mail.ReadWrite`</mark>, <mark style="color:red;">`Mail.Send`</mark>.

<div data-full-width="true"><figure><img src="https://s3.amazonaws.com/helpscout.net/docs/assets/5dd72e4d2c7d3a7e9ae44753/images/5f06470f04286306f80664f6/file-6Dac6tkbth.jpg" alt=""><figcaption></figcaption></figure></div>

This is what your application permissions screen should look like

<div data-full-width="true"><figure><img src="https://s3.amazonaws.com/helpscout.net/docs/assets/5dd72e4d2c7d3a7e9ae44753/images/5f0648302c7d3a10cbaa3da6/file-VSAYBJuJSk.jpg" alt=""><figcaption></figcaption></figure></div>

#### **Creating OAuth credentials**

Prepare a self-signed certificat, see [this article](https://docs.microsoft.com/en-us/azure/active-directory/develop/howto-create-service-principal-portal#upload-a-certificate) for sample instructions. The certificate and its private key will need to be uploaded to Aurinko later. Then, head to the "Certificates & secrets" panel and click "Upload certificate".&#x20;

<div data-full-width="true"><figure><img src="https://s3.amazonaws.com/helpscout.net/docs/assets/5dd72e4d2c7d3a7e9ae44753/images/5f06490b2c7d3a10cbaa3db4/file-tJCvYXEots.jpg" alt=""><figcaption></figcaption></figure></div>

\
Configure Aurinko to use your Office 365 OAuth (Daemon) credentials

Head on over to [Aurinko portal](https://app.aurinko.io/) and log in.

Select your app at the top, choose Settings menu and switch to the OFFICE 365 tab. Enter **Client ID**, **Private key**, and **Certificate** into the form and save.&#x20;

<div data-full-width="true"><figure><img src="/files/dRSH8SXUblFMMHC5HzIK" alt=""><figcaption></figcaption></figure></div>

**You are now all set to start connecting Office 365 service accounts to Aurinko!**


# Setting up MS Exchange service account

<https://docs.microsoft.com/en-us/exchange/client-developer/exchange-web-services/how-to-configure-impersonation>


# Create your first appointment booking page

Create a personalized appointment booking page by connecting your Google or Office 365 calendar. Download scheduler.html for setup and API details.

First, create an account in the [Aurinko portal](https://app.aurinko.io/).&#x20;

Create your app, then сheck the **'Scheduler'** feature for your new app (Mailbox API will be activated too).

<div data-full-width="true"><figure><img src="/files/NY2ZAa2kWE2dglhoUSBO" alt=""><figcaption></figcaption></figure></div>

On your new app's dashboard go to the todo item **'Check out your appointment booking page!'**

<div data-full-width="true"><figure><img src="/files/e6mqSTJ70vczHdYsegJ9" alt=""><figcaption></figcaption></figure></div>

and click **'Authorize access to a calendar'** (in Google or Office 365 account that you own):

<figure><img src="/files/GhMmTb0vjsMzhtfa1kw0" alt="" width="375"><figcaption></figcaption></figure>

Once a mailbox account (with calendar access) is connected click '**Download html file'** to download your scheduler.html file.

Then open the scheduler.html file in your browser; this is your appointment booking page!<br>

<div data-full-width="true"><figure><img src="/files/lrpWSXIbhMUNMpxURane" alt="" width="563"><figcaption></figcaption></figure></div>

To continue building your appointment booking app set up your own OAuth details:\
\
[Google OAuth setup](/authentication/google-oauth-setup)

[Office 365 OAuth setup](/authentication/office-365-oauth-setup)

\
Then review [Booking API](/scheduling/booking-api) on how to create booking profiles.\
\
Check out our public Github repo [aurinko-workspace-apps](https://github.com/yoxel/aurinko-workplace-apps); the 'index.html' in the scheduler directory is essentially the scheduler.html that you've downloaded. It is quite simple.<br>

<div data-full-width="true"><figure><img src="/files/N9vA7FZAE5wdioKub739" alt=""><figcaption></figcaption></figure></div>

You can host the the calendar page on your site, just specify your <mark style="color:red;">`AURINKO_CLIENT_ID`</mark> so that the widget knows your Aurinko app and looks for booking profiles in it.


# Calendar Booking Page

Streamline scheduling with Aurinko's integrated calendar booking page, designed for seamless client interactions and effortless appointment management.

Aurinko offers a prebuilt calendar booking page seamlessly integrated with its [Booking API](/scheduling/booking-api). This page streamlines the scheduling process for you and your clients, offering a user-friendly interface for booking appointments based on your defined availability profiles.

<div data-full-width="true"><figure><img src="/files/X6uM7chOIAUhCh0hsYN1" alt=""><figcaption></figcaption></figure></div>

### Key Features

***

* **Availability-Driven Booking**: Clients can only select time slots based on the pre-defined availability profiles.
* **Seamless Integration**: Works seamlessly with the [Aurinko Booking API](/scheduling/booking-api), managing bookings effortlessly.
* **Customization Options**: While offering a default design, the page follows the essential branding attributes specified for your Aurinko app (see Settings in the Aurinko portal).
* **Client-Centric Design**: Intuitive interface ensures smooth and hassle-free booking for your clients.

### Quick Start

***

* **Test Drive**: Experience the prebuilt booking page firsthand through Aurinko’s portal: [Create Your First Appointment Booking Page](/scheduling/create-your-first-appointment-booking-page).
* **Sample Code**: Explore the [open-source project](https://github.com/yoxel/aurinko-workplace-apps/tree/main/scheduler) showcasing the scheduler page:

<pre class="language-html"><code class="lang-html"><strong>&#x3C;!DOCTYPE html>
</strong>&#x3C;html>

    &#x3C;head>
        &#x3C;meta charset="UTF-8">
        &#x3C;title>Book&#x3C;/title>
        &#x3C;link rel="stylesheet" href="https://example.aurinko.io/scheduler/assets/salesforce-lightning-design-system.min.css">
        &#x3C;link rel="stylesheet" href="https://example.aurinko.io/scheduler/assets/styles.css">
    &#x3C;/head>

    &#x3C;body id="appContainer">
        
        &#x3C;script>
            var auClientId="{{YOUR_AURINKO_CLIENT_ID}}"
            var defaultProfileName="{{YOUR_DEFAULT_PROFILE_NAME}}"
        &#x3C;/script>

        &#x3C;script type="text/javascript" src="https://example.aurinko.io/scheduler/scheduler.js">&#x3C;/script>
    &#x3C;/body>

&#x3C;/html>
</code></pre>

### Integration

***

Host the sample calendar page at your domain, i.e. *calendar.mydomain.com*, and specify <mark style="color:red;">`{{YOUR_AURINKO_CLIENT_ID}}`</mark> in the index.html file. <mark style="color:red;">`{{YOUR_DEFAULT_PROFILE_NAME}}`</mark> is optional.

*Alternatively, we can host this page for you and associate your domain alias with your app's clientId.*

In either case, add your domain to the list of trusted domains in your Aurinko portal:

<div data-full-width="true"><figure><img src="/files/xBxBefsMWOyNRp81RxDH" alt=""><figcaption></figcaption></figure></div>

* You can view calendar availability for a given booking profile by specifying the profile's name in the URL path: <mark style="color:red;">`https://calendar.mydomain.com/{profileName}`</mark>. Those links are convenient for sharing by email.
* If you deploy the calendar page at a path then use hash segments to specify a profile and other parameters, i.e. <mark style="color:red;">`https://myapp.mydomain.com/pathTo/calendarPage/#profile={profileName}`</mark>. You can specify your clientId this way too.
* Our code always looks for the hash segment parameters first; then considers the path to be a profile name.

If you need to integrate the page into your existing website we recommend using an *iframe* which your code can redirect to different profiles as needed:

{% code fullWidth="true" %}

```html
<iframe id="myIframe"></iframe>

<script>
  document.getElementById("myIframe").src = "https://calendar.mydomain.com/#profile={profileName}";
</script>

```

{% endcode %}

The page supports the following parameters <mark style="color:red;">`#profile=&extensionProfile=&mode=&layout=&view=&...`</mark>:

* <mark style="color:red;">`profile`</mark> - The main booking profile name that determines the availability.
* <mark style="color:red;">`extensionProfile`</mark> - 2nd profile that will determine availability after the main profile's end date.
* <mark style="color:red;">`mode`</mark> - Use 'view' to disable booking capability.
* <mark style="color:red;">`layout`</mark> - Use 'month' for Calendly-like layout.
* <mark style="color:red;">`suppressInvitation`</mark> - Then 'true' an event will be created without any attendees. It becomes your code's responsibility to add attendees later.
* <mark style="color:red;">`date`</mark> - Display the booking profile with the pre-selected date and slots.
* <mark style="color:red;">`rescheduleToken`</mark>  - Allows a client to **reschedule an already booked event** without requiring authentication or access to the original calendar provider.

  The `rescheduleToken` is a unique code generated by Aurinko when an event is created.\
  It uniquely identifies the event and grants limited permission to **change the event’s date and time** through the scheduler UI.\
  \
  You can embed this token inside your booking description or notification email, for example:<br>

  <pre class="language-json" data-overflow="wrap"><code class="lang-json">"description": "Here is an event... If you want to change the time, please follow the link: https://example.aurinko.io/scheduler/#profile=Test_Booking&#x26;clientId=552f95116d0a08933203109d1ca124r4&#x26;rescheduleToken={{rescheduleToken}}"
  </code></pre>

{% hint style="info" icon="envelope-open-text" %}
For other custom integration scenarios please reach out to us at <support@aurinko.io>.
{% endhint %}


# Booking API

The Aurinko Booking API automates meeting scheduling, enabling developers to access calendar availability and create booking profiles easily.

## Aurinko Booking API

***

The Booking API is a powerful tool designed to facilitate the automated scheduling of meetings for one calendar. It enables developers to gather availability information from a calendar and find time slots when the calendar owner is available.

The API is built on top of the Aurinko Account concept. Please see [Account OAuth Flow](/authentication/oauth-flow) section to understand how to add an account and get access to its calendars.

### Booking profile

***

At the heart of the [Booking API](https://apirefs.aurinko.io/#tag/Booking/operation/create) lies a booking/availability profile. This profile consists of a set of properties that describe calendar availability and the types of meetings that can be booked. It includes the following information:

1. Work hours
2. Meeting duration
3. Meeting subject
4. Meeting description
5. Meeting teleconference link
6. Meeting location
7. Profile scheduler link
8. Profile active period
9. And more...

To create a new booking profile POST json payload to the [/book/profiles](https://apirefs.aurinko.io/#tag/Booking/operation/create) endpoint:

```shell
curl -H 'Authorization: Bearer <access token>'
    -X POST https://api.aurinko.io/v1/book/account/profiles
    -d '{
        "id": 1,
        "name": "aurinkoDemo",
        "durationMinutes": 30,
        "availabilityStep": 15,
        "timeAvailableFor": "30D",
        "subject": "Aurinko Demo",
        "description": "A conference call with Aurinko.",
        "location": "Teleconference",
        "workHours": {
            "timezone": "Americas/New\_York",
            "daySchedules": [
                {
                    "dayOfWeek": "monday",
                    "workingIntervals": [{"start": "14:15:22Z","end": "14:15:22Z"},...]
                },
                ...
                
            ],
        },
        "context": "string",
        "startConference": true
}'  
```

You can insert variables like <mark style="color:red;">`{{name}}`</mark>, <mark style="color:red;">`{{comments}}`</mark> in the meeting description text. They will be passed to a scheduling widget to be filled by an end user booking a meeting (see <mark style="color:red;">`additionalFields`</mark> of the availability endpoint below).\
You can also use the <mark style="color:red;">`{{rescheduleToken}}`</mark> variable, which allows a client to reschedule an already booked event without requiring authentication or access to the original calendar provider.

*Use PATCH request to update existing profiles*:

```bash
curl -H 'Authorization: Bearer <access token>'
    -X PATCH https://api.aurinko.io/v1/book/account/profiles/{id}
    -d '{
        "name": "aurinkoDemo",
        "durationMinutes": 30,
        "availabilityStep": 15,
        "timeAvailableFor": "30D",
        "subject": "Aurinko Demo",
        "description": "My new event description",
        "location": "Google Hangout",
        "context": "string",
        "startConference": true
}'  
```

### Availability

***

Once a booking profile is created, the [Booking API](https://apirefs.aurinko.io/#tag/Availability/operation/getMeetingTimes) can be used to query a user's availability for the types of meetings defined in the profile and within the specified work hours. ) can be used to query a user's availability for the types of meetings defined in the profile and within the specified work hours.

<mark style="color:red;">`curl -X GET`</mark> \ <mark style="color:red;">`https://api.aurinko.io/v1/book/account/profiles/{id}/meeting`</mark>

This endpoint produces information that can be used to build a public calendar page like [Aurinko's Calendar Page](/scheduling/calendar-booking-page).

{% hint style="info" %}
**Note:** this endpoint requires app-level authentication (ClientId+Secret).
{% endhint %}

```json
{
    "items": [
        {
            "start": "2024-01-27T14:00:00Z",
            "end": "2024-01-27T14:45:00Z"
        },...
    ],
    "startTime": "2024-01-01T00:00:00Z",
    "endTime": "2024-04-01T00:00:00Z",
    "durationMinutes": 45,
    "availabilityStep": 15,
    "subject": "Aurinko Demo",
    "primaryColor":"#303030",
    "secondaryColor":"#30A9EE",
    "additionalFields": [
        {
            "name":"comment",
            "type":"text",
            "default": null
        },
        ...
        
    ]
}
```

### Schedule

***

The <mark style="color:red;">`additionalFields`</mark> array contains the <mark style="color:red;">`{{variables}}`</mark> that you specified in the meeting description text. If you're building your own scheduling widget it needs to ask the end user for those inputs. Booking a meeting will require the fields that don't specify defaults.

Book a meeting by sending json payload to the \ <mark style="color:red;">`book/account/profiles/{id}/meeting`</mark> endpoint:

```bash
curl -X POST {id}/meeting
    -d '{
    "time": {
        "start": "2024-01-27T14:00:00Z",
        "end": "2024-01-27T14:45:00Z"
    },
    "name": "string",
    "email": "string",
    "substitutionData": {
        "property1": "string",
        "property2": "string"
    }
}'
```

A new event will be created on the calendar associated with the booking profile and the person specified by the email and name fields will be invited to the event.


# Group Booking API

The Group Booking API automates meeting scheduling for groups by gathering availability from multiple calendars and finding suitable time slots.

The Group Booking API is a powerful tool designed to facilitate the automated scheduling of meetings within a group. It enables developers to gather availability information from multiple user calendars and find time slots when at least one user is available.

The API is built on top of the Aurinko User concept. Please see [User OAuth Flow](/authentication/oauth-flow) section to understand how to add a user and one or more accounts/calendars.

### Booking profile

***

At the heart of the [Group Booking API](https://apirefs.aurinko.io/#tag/GroupBooking) lies a booking/availability profile for a set of accounts or groups of accounts. This profile consists of a set of properties that describe calendar availability and the types of meetings that can be booked. It includes the following information:

1. Work hours
2. Meeting duration
3. Meeting subject
4. Meeting description
5. Meeting teleconference link
6. Meeting location
7. Profile scheduler link
8. Profile active period
9. And more...

To create a new booking profile POST json payload to the [/book/group/profiles](https://apirefs.aurinko.io/#tag/GroupBooking/operation/createGroupBooking) endpoint:

```bash
curl -u ClientId:Secret
    -X POST https://api.aurinko.io/v1/book/group/profiles
    -d '{
        "id": 1,
        "name": "aurinkoDemo",
        "durationMinutes": 30,
        "availabilityStep": 15,
        "timeAvailableFor": "30D",
        "subject": "Aurinko Demo",
        "description": "A conference call with Aurinko.",
        "location": "Teleconference",
        "workHours": {
            "timezone": "Americas/New_York",
            "daySchedules": [
                {
                    "dayOfWeek": "monday",
                    "workingIntervals": [{"start": "14:15:22Z","end": "14:15:22Z"},...]
                },
                ...
                
            ],
        },
        "context": "string",
        "startConference": true
}'  
```

{% hint style="info" %}
**Note:** this endpoint requires app-level authentication (ClientId+Secret).
{% endhint %}

You can insert variables like <mark style="color:red;">`{{name}}`</mark>, <mark style="color:red;">`{{comments}}`</mark> in the meeting description text. They will be passed to a scheduling widget to be filled by an end user booking a meeting (see additionalFields of the availability endpoint below).

*Use PATCH request to update existing profiles*:

```bash
curl -u ClientId:Secret
    -X PATCH https://api.aurinko.io/v1/book/group/profiles/{id}
    -d '{
        "name": "aurinkoDemo",
        "durationMinutes": 30,
        "availabilityStep": 15,
        "timeAvailableFor": "30D",
        "subject": "Aurinko Demo",
        "description": "My new event description",
        "location": "Google Hangout",
        "context": "string",
        "startConference": true
}'
```

To associate accounts with a booking profile, use the [attachAccounts endpoint](https://apirefs.aurinko.io/#tag/GroupBooking/operation/attachAccountsGroupBooking):

```bash
curl -u ClientId:Secret
    -X POST https://api.aurinko.io/v1/book/group/profiles/{id}/attachAccounts
    -d '{ "accountIds": [accId1, accId2]
}'
```

To associate groups of accounts with a booking profile, use the [attachGroups endpoint](https://apirefs.aurinko.io/#tag/GroupBooking/operation/attachGroupsBooking):

```bash
curl -u ClientId:Secret
    -X POST https://api.aurinko.io/v1/book/group/profiles/{id}/attachGroups
    -d '{ "groups": [
    
    { "extId": "groupExtId1", 
                "accountIds": [accId1, accId2], 
                "required": "one" 
    },
                
    { "extId": "groupExtId2", 
                "accountIds": [accId3, accId4], 
                "required": "all" 
    }
  ] 
}'
```

The `required` field in the request body determines how the booking should handle group availability:

* `"one"` – The meeting can be scheduled if **at least one** member of the group is available.
* `"all"` – The meeting can be scheduled **only if all** members of the group are available.

### Availability

***

Once a booking profile is created, and its accounts/groups are defined the [availability endpoint](https://apirefs.aurinko.io/#tag/Availability/operation/getMeetingTimes) can be used to query the members availability for the types of meetings defined in the profile and within the specified work hours.

<mark style="color:red;">`curl -X GET`</mark> \ <mark style="color:red;">`https://api.aurinko.io/v1/book/group/profiles/{id}/meeting?required=one|all`</mark>

This endpoint produces information that can be used to build a public calendar page like [Aurinko's Calendar Page](/scheduling/calendar-booking-page).

<mark style="color:red;">`groupXids`</mark> indicate which groups are available for a given time slot.

<mark style="color:red;">`accountIds`</mark> indicate which accounts are available for a given time slot.

{% hint style="info" %}
**Note:** this endpoint requires app-level authentication (ClientId+Secret).
{% endhint %}

```json
{
    "items": [
        {
            "start": "2024-01-27T14:00:00Z",
            "end": "2024-01-27T14:45:00Z",

            "groupXids": ["group1", "group2", "group3"],
            "accountIds": [id1, id2, id3, ...]        
        },
        ...
        
    ],
    "startTime": "2024-01-01T00:00:00Z",
    "endTime": "2024-04-01T00:00:00Z",
    "durationMinutes": 45,
    "availabilityStep": 15,
    "subject": "Aurinko Demo",
    "primaryColor":"#303030",
    "secondaryColor":"#30A9EE",
    "additionalFields": [
        {
            "name":"comment",
            "type":"text",
            "default": null
        },
        ...
        
    ]
}
```

The <mark style="color:red;">`additionalFields`</mark> array contains the <mark style="color:red;">`{{variables}}`</mark> that you specified in the meeting description text. If you're building your own scheduling widget it needs to ask the end user for those inputs. Booking a meeting will require the fields that don't specify defaults.

{% hint style="info" %}
**Note:** When dealing with larger groups (over 10 users) request next page with <mark style="color:red;">`offset`</mark> query parameter. The same time slots will be returned but for additional userIds.
{% endhint %}

### Schedule

***

Book a meeting by sending json payload to the <mark style="color:red;">`book/group/profiles/{id}/meeting?required=one|all`</mark> endpoint and specify groupXids and/or accountIds that you received earlier for the specified time slot:

```bash
curl -X POST {id}/meeting
    -d '{
    "time": {
        "start": "2024-01-27T14:00:00Z",
        "end": "2024-01-27T14:45:00Z"
    },
    "groupXids": ["group1", "group2", "group3"],
    "accountIds": [id1, id2, id3, ...],
    "name": "string",
    "email": "string",
    "substitutionData": {
        "property1": "string",
        "property2": "string"
    }
}'  
```

Specify the accountIds or groupXids that you received from the availability endpoint.

A new event will be created based on the profile:

* If an account is specified, the event will be scheduled in its primary calendar.
* If a group is specified, the event will be scheduled in the primary calendar of an available account within that group.

In both cases, the person specified in the <mark style="color:red;">`email`</mark> and <mark style="color:red;">`name`</mark> fields will be invited to the event. In the '?required=all' mode also all specified accounts will be invited.


# Outlook addins

Integrate Outlook with third-party services using add-ins built on JavaScript/HTML, enabling seamless access to emails, meetings, and more.

Outlook add-ins (and Office add-ins in general) are integrations built by third parties into Outlook by using Microsoft's web-based platform. Outlook add-ins are essentially JavaScript/HTML code that runs in the context of a browser in a sandbox with special access to Outlook items like email messages, meeting requests, responses and cancellations, and appointments.

Most Outlook add-ins are built to provide convenient integrations to a third-party system or service right from Outlook, like Customer Relationship Management, Customer Service, and Project Management,... and the add-in developers all end up developing the same or similar elements of their app:

* Provision a backend API that will support the client code.
* Implement user management (login/logout/session) which needs to be correlated with an authenticated Outlook user.
* Support one or more 3rd party authorization flows. For example, a user needs to link his or her CRM account, maybe also a cloud file storage.
* Proxy requests to 3rd party API's. Quite often direct API communications from JavaScript are blocked by CORS in browsers.
* Storing various add-in configurations for users or organizations.
* Offline mailbox access. Often special workers are implemented to run in the background when an add-in user is offline.

Aurinko aims to provide the necessary backend functionality for these add-ins so that developers could focus on the client code to create the best user experiences. Here are the steps to start using Aurinko as a backend API for your Outlook:

1. Get your developer API keys and put your app's client id into your client code or better pass it from your manifest file as a url parameter.
2. In most cases you want to have offline mailbox access or ability to access Graph API so provision your Azure app registrations.
3. After your add-in client code has initialized and gained access to Office JS API, test if the current user is already authenticated with Aurinko (logged in):

   <mark style="color:red;">`curl -X GET -G https://api.aurinko.io/v1/user`</mark>

   For a logged in user the request will return the user info and its active Aurinko accounts:

   ```json
   {
       "id": "3df3ce21-07c0-4cec-a8de-ed4c570ee15c",
       "appId": 1,
       "email": "user@yoxel.net",
       "authOrgId": "abcda5bb-1d9f-0514-a4c6-1234502167890",
       "trustedIdentity": true,
       "accounts": [
           {
               "id": 2739,
               "serviceType": "Office365",
               "type": "primary",
               "active": true,
               "daemon": false,
               "loginString": "user@yoxel.net",
               "email": "user@yoxel.net",
               "name": "Addin User",
               "authUserId": "abcdabcb-ad8d-4bee-bd69-787675478785",
               "authOrgId": "abcda5bb-1d9f-0514-a4c6-1234502167890",
               "authObtainedAt": "2021-03-21T16:58:56.823Z"
           }
       ]
   }
   ```

   Otherwise, 401 Unauthorized status will be returned in which case your addin needs to ask the user to login (see next step).
4. Office JS API provides a special idToken that can be used to validate a current user but we recommend using OAuth2 authorization flow to confirm the current user as this way your app can also get offline access to Graph API:

   ```bash
   curl -X GET -G https:/api.aurinko.io/v1/auth/authorize
       -d clientId='{APPLICATION_ID}'
       -d serviceType='Office365'
       -d scopes='Mail.Read Mail.Send'
       -d userAccount='primary'
       -d returnUrl='https://static.mydomain.com/outlook_auth_callback.html'
   ```

   The important parameter here is <mark style="color:red;">`userAccount = primary`</mark> which turns this account authorization into user session initialization (user login). Upon successful authentication and authorization the redirect to <mark style="color:red;">`returnUrl`</mark> will result in setting a session cookie which will allow your app to stay recognized by Aurinko until the user logs out.

   In addition to the login Aurinko gets access to Graph API with the following scopes: Mail.Read, Mail.Send. This will allow your app to work with the Outlook account while the user is not using your Outlook addin.
5. Authorize access to a 3rd party API. Contact us at [support@aurinko.io](mailto:mailto:support@aurinko.io) to arrange adding a connector for your system, i.e. {MyCRM}.

   ```bash
   curl -X GET -G https:/api.aurinko.io/v1/auth/authorize
       -d clientId='{APPLICATION_ID}'
       -d serviceType='{MyCRM}'
       -d userAccount='secondary'
       -d returnUrl='https://static.mydomain.com/outlook_auth_callback.html'
   ```

   Upon a successful authentication and authorization an Aurinko account representing your 3rd party API {MyCRM} will be added and your app can issue the following request again:

   ```bash
   curl -X GET -G https://api.aurinko.io/v1/user
   ```

   The request will return all Aurinko accounts associated with the current user session:

   ```json
   {
       "id": "3df3ce21-07c0-4cec-a8de-ed4c570ee15c",
       "appId": 1,
       "email": "user@yoxel.net",
       "authOrgId": "abcda5bb-1d9f-0514-a4c6-1234502167890",
       "trustedIdentity": true,
       "accounts": [
           {
               "id": 2739,
               "serviceType": "Office365",
               "type": "primary",
               "active": true,
               "daemon": false,
               "loginString": "user@yoxel.net",
               "email": "user@yoxel.net",
               "name": "Addin User",
               "authUserId": "abcdabcb-ad8d-4bee-bd69-787675478785",
               "authOrgId": "abcda5bb-1d9f-0514-a4c6-1234502167890",
               "authObtainedAt": "2021-03-21T16:58:56.823Z"
           },
           {
               "id": 2740,
               "serviceType": "{MyCRM}",
               "type": "secondary",
               "active": true,
               "daemon": false,
               "loginString": "user@yoxel.net",
               "email": "user@yoxel.net",
               "name": "Crm User",
               "serverUrl": "https://crm.repfabric.com",
               "authUserId": "374",
               "authOrgId": "999",
               "authObtainedAt": "2021-03-21T17:39:10.513Z"
           }
       ]
   }
   ```
6. Now your addin can access either Graph API (through Aurinko's unified API) or the 3rd party API. Specify an account id in the special header <mark style="color:red;">`X-Aurinko-AccountId`</mark> and use Aurinko <mark style="color:red;">`Email/Calendar/Contact`</mark> to access those accounts.

   <pre class="language-bash"><code class="lang-bash">curl -H 'X-Aurinko-AccountId: 2739'
   <strong>    -X GET https:/api.aurinko.io/v1/email/messages  
   </strong>
   curl -H 'X-Aurinko-AccountId: 2740'
       -X GET https:/api.aurinko.io/v1/contacts
   </code></pre>


# Create your first Outlook addin

Set up your Aurinko Outlook add-in by creating an account, installing the manifest, and accessing user data through the Unified Mailbox API.

First, create an account in the [Aurinko portal](https://app.aurinko.io/).&#x20;

Create your app, then сheck API/features that should be activated for your new app. Besides 'Mailbox API' and 'User sessions' your addin may need to access CRM APIs.

<div data-full-width="true"><figure><img src="/files/lyaTqZtt8w4QDw5bpfP5" alt=""><figcaption></figcaption></figure></div>

You're ready to activate your Aurinko Outlook addin!

Install the manifest file in your Office 365 Outlook.

Once you've installed the manifest, opened the addin in Outlook, and logged in, you'll see a new user record in Aurinko:&#x20;

<div data-full-width="true"><figure><img src="https://s3.amazonaws.com/helpscout.net/docs/assets/5dd72e4d2c7d3a7e9ae44753/images/6284116168d51e7794441477/file-fq65QClui6.jpg" alt=""><figcaption></figcaption></figure></div>

Now you frontend code can call Aurinko API on behalf of this user. Read this [article](https://docs.aurinko.io/workspace-addons/outlook-addins) for more details.

Also a there is a new account that supports the user record. Your addin's frontend code can access the mailbox data through this account now.&#x20;

{% hint style="info" icon="file-lines" %}
See [the Unified mailbox API docs](https://docs.aurinko.io/) for details.
{% endhint %}

<div data-full-width="true"><figure><img src="https://s3.amazonaws.com/helpscout.net/docs/assets/5dd72e4d2c7d3a7e9ae44753/images/628413428c9b58508348a95c/file-ZKkH5ekO9l.jpg" alt=""><figcaption></figcaption></figure></div>


# Office 365: Installing Outlook addin

Install your Aurinko Outlook add-in by uploading the auto-generated manifest in Outlook. Open the add-in from the main ribbon to get started.

An Outlook add-in consists of two components: the XML add-in manifest and a web page supported by the JavaScript library for Office Add-ins (office.js). The manifest describes how the add-in integrates across Outlook clients.&#x20;

{% hint style="info" icon="file-lines" %}
See [Microsoft documentation](https://docs.microsoft.com/en-us/office/dev/add-ins/outlook/manifests) for details.
{% endhint %}

Aurinko auto-generates an addin manifest for youe Aurinko addin apps, see how.

In Outlook (desktop) click the **Get add-ins** ribbon button:

<div data-full-width="true"><figure><img src="https://s3.amazonaws.com/helpscout.net/docs/assets/5dd72e4d2c7d3a7e9ae44753/images/628407238c9b58508348a91d/file-X7v5lqvbz8.png" alt=""><figcaption></figcaption></figure></div>

A popup will appear. Select **My add-ins**, scroll down to the **Custom Addins** section, and select the **Add from File...** option. Upload the manifest file you downloaded from your Aurinko app, click **Install**.

<div data-full-width="true"><figure><img src="https://s3.amazonaws.com/helpscout.net/docs/assets/5dd72e4d2c7d3a7e9ae44753/images/628407dbb2de5178f888494f/file-HIOX7QMiBL.jpg" alt=""><figcaption></figcaption></figure></div>

The addin should be installed!

<div data-full-width="true"><figure><img src="https://s3.amazonaws.com/helpscout.net/docs/assets/5dd72e4d2c7d3a7e9ae44753/images/62840a4f8c9b58508348a92a/file-K48tVnDqD5.jpg" alt=""><figcaption></figcaption></figure></div>

Close the popup and check the main ribbon menu in Outlook.

<div data-full-width="true"><figure><img src="https://s3.amazonaws.com/helpscout.net/docs/assets/5dd72e4d2c7d3a7e9ae44753/images/62840bd7b2de5178f8884966/file-O3ROa4U1Ag.jpg" alt=""><figcaption></figcaption></figure></div>

Click **Open Aurinko** to open your Aurinko addin!


# Microsoft Teams apps

Integrate third-party solutions with Teams using Aurinko API. Develop bots and tabs to enhance user experience and access Graph API seamlessly.

Teams apps are integrations built by third parties into Teams by using Microsoft's web-based platform and bot framework. Teams apps can provide many different capabilities but usually most of them provide at least one tab and some bot functionality. Teams tabs are quite similar to Outlook add-ins as essentially they are JavaScript/HTML code that runs in the context of a browser in a sandbox with special access to Teams chat or channel properties. Usually you Teams app provides a tab in which the app can be configured.

Most Teams apps are built to provide convenient integrations to a third party system or service right from Teams, like Customer Relationship Management, Customer Service, Project Management,... and the app developers all end up developing the same or similar elements of their app:

* Provision a backend API that will support the client code.
* Implement user management (login/logout/session) which needs to be correlated with an authenticated Teams user.
* Support one or more 3rd party authorization flows. For example, a user needs to link his or her CRM account, maybe also a cloud file storage.
* Proxy requests to 3rd party API's. Quite often direct API communications from JavaScript are blocked by CORS in browsers.
* Storing various app user configurations.
* Bot functionality or offline account access. Often special workers are implemented to run in background when an app user is offline.

\
Aurinko aims to provide the necessary backend functionality for these apps so that developers could focus on the client code to create the best user experiences. Here are the steps to start using Aurinko as a backend API for your Teams app:

1. Get your developer API keys and put your app's client id into your client code or better pass it from your manifest file as an url parameter.
2. In most cases you want to provide bot functionality or have offline account access so provision your Azure app registrations.
3. Setup your Teams bot if you plan to provide bot functionality in your Teams app.

### Tabs

***

Your Teams app can be configured to provide tabs for channels and/or chats. A tab is usually where a user will activate your app and configure it. Here is how you use Aurinko API from your tabs.<br>

1. After your app client code has initialized in a Teams tab, test if the current user is already authenticated with Aurinko (logged in):

   <mark style="color:red;">`curl -X GET -G https://api.aurinko.io/v1/user`</mark>

   \
   For a logged in user the request will return the user info and its active Aurinko accounts:

   ```json
   {
       "id": "3df3ce21-07c0-4cec-a8de-ed4c570ee15c",
       "appId": 1,
       "email": "user@yoxel.net",
       "authOrgId": "abcda5bb-1d9f-0514-a4c6-1234502167890",
       "trustedIdentity": true,
       "accounts": [
           {
               "id": 2739,
               "serviceType": "Office365",
               "type": "primary",
               "active": true,
               "daemon": false,
               "loginString": "user@yoxel.net",
               "email": "user@yoxel.net",
               "name": "Office User",
               "authUserId": "abcdabcb-ad8d-4bee-bd69-787675478785",
               "authOrgId": "abcda5bb-1d9f-0514-a4c6-1234502167890",
               "authObtainedAt": "2021-03-21T16:58:56.823Z"
           }
       ]
   }
   ```

   Otherwise 401 Unauthorized in which case your app needs to ask the user to login (see next step).<br>
2. Confirm the current Teams user using the OAuth2 authorization flow. This way your app can also get offline access to Graph API and request additional permissions:

   ```bash
   curl -X GET -G https:/api.aurinko.io/v1/auth/authorize
       -d clientId='{APPLICATION_ID}'
       -d serviceType='Office365'
       -d nativeScopes=ChannelMessage.Send
       -d userAccount='primary'
       -d returnUrl='https://static.mydomain.com/msteams_auth_callback.html'
   ```

   \
   The important parameter here is <mark style="color:red;">`userAccount = primary`</mark> which turns this account authorization into a user session initialization (user login). Upon successful authentication and authorization the redirect to <mark style="color:red;">`returnUrl`</mark> will result in setting a session cookie which will allow your app to stay recognized by Aurinko until the user logs out.

   In addition to the login Aurinko gets access to Graph API with the following Teams scope: ChannelMessage.Send. This scope could allow your app to post to private channels, for example.<br>
3. Authorize access to a 3rd party API. \
   Contact us at [support@aurinko.io](mailto:mailto:support@aurinko.io) to arrange adding a connector for your system, i.e. {MyCRM}.<br>

   ```bash
   curl -X GET -G https:/api.aurinko.io/v1/auth/authorize
       -d clientId='{APPLICATION_ID}'
       -d serviceType='{MyCRM}'
       -d userAccount='secondary'
       -d returnUrl='https://static.mydomain.com/msteams_auth_callback.html'
   ```

   Upon a successful authentication and authorization an Aurinko account representing your 3rd party API {MyCRM} will be added and your app can issue the following request (or the request from step 3):

   <mark style="color:red;">`curl -X GET -G https://api.aurinko.io/v1/user`</mark>

   \
   The request will return all Aurinko accounts associated with the current user session:

   ```json
   {
       "id": "3df3ce21-07c0-4cec-a8de-ed4c570ee15c",
       "appId": 1,
       "email": "user@yoxel.net",
       "authOrgId": "abcda5bb-1d9f-0514-a4c6-1234502167890",
       "trustedIdentity": true,
       "accounts": [
           {
               "id": 2739,
               "serviceType": "Office365",
               "type": "primary",
               "active": true,
               "daemon": false,
               "loginString": "user@yoxel.net",
               "email": "user@yoxel.net",
               "name": "Office User",
               "authUserId": "abcdabcb-ad8d-4bee-bd69-787675478785",
               "authOrgId": "abcda5bb-1d9f-0514-a4c6-1234502167890",
               "authObtainedAt": "2021-03-21T16:58:56.823Z"
           },
           {
               "id": 2740,
               "serviceType": "{MyCRM}",
               "type": "secondary",
               "active": true,
               "daemon": false,
               "loginString": "user@yoxel.net",
               "email": "user@yoxel.net",
               "name": "Crm User",
               "serverUrl": "https://crm.instance",
               "authUserId": "374",
               "authOrgId": "999",
               "authObtainedAt": "2021-03-21T17:39:10.513Z"
           }
       ]
   }
   ```
4. Now your addin can access either Graph API (through Aurinko's unified API) or the 3rd party API. Specify an account id in the special header <mark style="color:red;">`X-Aurinko-AccountId`</mark> and use Aurinko Email/Calendar/Contact to access those accounts.

   ```bash
   curl -H 'X-Aurinko-AccountId: 2739'
       -X GET https:/api.aurinko.io/v1/email/messages
   	
   ```

   ```bash
   curl -H 'X-Aurinko-AccountId: 2740'
       -X GET https:/api.aurinko.io/v1/contacts
   ```
5. To manage app configurations use Aurinko's storage API.

   > ***Note:** all Teams users in Aurinko are associated with their Office 365 organizations automatically.*

   User level properties - receive key/value properties associated with the user.

   ```bash
   curl -X GET https:/api.aurinko.io/v1/storage/user
   ```

   Org level properties - receive key/value properties associated with the user's Office 365 organization.

   ```bash
   curl -X GET https:/api.aurinko.io/v1/storage/organization
   ```

### Bots (workers)

***

When developing a bot or a worker for a specific task (i.e. sync or scanner) you need to have a background process that can work with Teams data while its users are offline. Here is how such worker processes can use Aurinko API.<br>

1. Host your worker process anywhere you like. \
   Contact us at [support@aurinko.io](mailto:mailto:support@aurinko.io) about activating our pre-built chat sync logic.
2. Have your worker connect to Aurinko API periodically to find out about new app installations (webhooks will be available soon too). Use the following API request to retrieve the list of MsTeamsBot service accounts:

   ```bash
   curl -u ClientId:Secret -X GET https:/api.aurinko.io/v1/svc_accounts 
       -G -d serviceType='MsTeamsBot'
   {
       "records": [
           {
               "id": 2152,
               "serviceType": "MsTeamsBot",
               "active": true,
               "daemon": true,
               "loginString": "c345743-ecea-47fa-97d4-b4b4b6c70fa52",
               "name": "yoxel.net",
               "authOrgId": "c345743-ecea-47fa-97d4-b4b4b6c70fa52"
           },
           {
               "id": 2262,
               "serviceType": "MsTeamsBot",
               "active": true,
               "daemon": true,
               "loginString": "48f3456a-61d5-4673-8cd2-d24c39ee34f3",
               "name": "team.onmicrosoft.com",
               "authOrgId": "48f3456a-61d5-4673-8cd2-d24c39ee34f3"
           },
           ...
           
       ],
       "totalSize": 5,
       "offset": 0,
       "done": true
   }
   ```
3. Receive app configurations using Aurinko's storage API. These could be user or organization level configurations created by your tab.

   User level properties - receive key/value properties associated with the user.

   ```bash
   curl -u ClientId:Secret
       -X GET https:/api.aurinko.io/v1/storage/user
   ```

   Org level properties - receive key/value properties associated with the user's Office 365 organization (see authOrgId in the service account responses).

   ```bash
   curl -u ClientId:Secret
       -X GET https:/api.aurinko.io/v1/storage/organization/find
       -G -d provider='Office365' -d xid='48f3456a-61d5-4673-8cd2-d24c39ee34f3'
   ```
4. Post messages to Teams using Aurinko's chat API
5. Subscribe to receive events.


# Microsoft Teams bot setup

Register your bot in the Microsoft Bot Framework, link it to Aurinko, and use the API to manage Teams interactions effectively.

In order to build a Teams app that is a bot you need to register your bot in the Microsoft bot framework and link it to your Aurinko app.&#x20;

{% hint style="info" icon="envelope-open-text" %}
If you have any trouble registering bot in the Microsoft bot framework, get in touch with [support@aurinko.io](mailto:mailto:support@aurinko.io) and we'd be happy to help you out!
{% endhint %}

1. Provision Office 365 / Azure AD app registration for your new Aurinko app. Remember your Azure AD app id and secret, you'll need them on the next steps.<br>
2. To create a new bot registration navigate to the bot framework link [dev.botframework.com/bots/new](https://dev.botframework.com/bots/new).<br>

   To link this bot configuration with your Aurinko app make sure to enter the Aurinko endpoint <mark style="color:red;">`https://api.aurinko.io/push/office/bot/{AurinkoAppId}/chat`</mark> as the 'Messaging endpoint' and the Azure AD app id (from step 1) as the 'App Id'.

<div data-full-width="true"><img src="https://s3.amazonaws.com/helpscout.net/docs/assets/5dd72e4d2c7d3a7e9ae44753/images/606b5aff8996210f18bd0283/file-leeUPfNwsp.png" alt=""></div>

Then click **'Register'** button.<br>

3. Connect your bot to the 'Microsoft Teams' channel:

<div data-full-width="true"><img src="https://s3.amazonaws.com/helpscout.net/docs/assets/5dd72e4d2c7d3a7e9ae44753/images/60579e69207e3b1188e1e60a/file-ubhcY4ebyT.png" alt=""></div>

4. Back in the Aurinko app settings open MS Teams Bot OAuth section and enter your Azure AD app id and secret for 'Client id' and 'Client secret'. Then generate a new universal unique identifier (UUID) for your bot and enter it as 'Bot id'. Store this bot id as you will use it as your ID in the Teams manifest file.                                                                                                                                                     Keep 'External app' checkbox checked while you're developing your app and distributing it by uploading the manifest file. Other tenants consider this app 'External' if it's installed from the manifest file. Uncheck the box and update the bot id after you've published your app to the Office store and it has become listed in the store catalogue.

<div data-full-width="true"><figure><img src="/files/IQdQwEZt8a7Pq8Cu8kG7" alt=""><figcaption></figcaption></figure></div>

{% hint style="info" %}
**Note:** MS Bot Framework has limitations, bots don't get notified on channel events and receive only the messages explicitly addressing the bots. The bots can really do just two things: reply to a conversation initiated by a user or initiate a conversation (needs to know user id or channel id first). If your Teams app needs capabilities beyond this you will have to configure your app to request application level permissions.
{% endhint %}

5. With this configuration in place Aurinko platform starts receiving events generated by Microsoft bot framework for your bot and automatically provisions a new service account for every installation of your Teams app.                                                                                                                       You'll see all those service accounts in your Aurinko portal under Accounts:

<div data-full-width="true"><figure><img src="/files/5iPz3MetAXsDpLSxuyvd" alt=""><figcaption></figcaption></figure></div>

6. Use the following API request to retrieve the list of these service accounts:

```bash
curl -u ClientId:Secret -X GET https:/api.aurinko.io/v1/svc_accounts 
    -G -d serviceType='MsTeamsBot'

{
    "records": [
         {
            "id": 2152,
            "serviceType": "MsTeamsBot",
            "active": true,
            "daemon": true,
            "loginString": "c345743-ecea-47fa-97d4-b4b4b6c70fa52",
            "name": "yoxel.net",
            "authOrgId": "c345743-ecea-47fa-97d4-b4b4b6c70fa52"
        },
        {
            "id": 2262,
            "serviceType": "MsTeamsBot",
            "active": true,
            "daemon": true,
            "loginString": "48f3456a-61d5-4673-8cd2-d24c39ee34f3",
            "name": "team.onmicrosoft.com",
            "authOrgId": "48f3456a-61d5-4673-8cd2-d24c39ee34f3"
        },
        ...
        
  ],
  "totalSize": 5,
  "offset": 0,
  "done": true
}	  
```

7. Use these accounts to call our unified Chat API. An account id has to be specified in the header <mark style="color:red;">`X-Aurinko-AccountId`</mark>:

```bash
curl -u ClientId:Secret
    -H 'X-Aurinko-AccountId: 2152'
    -X POST https:/api.aurinko.io/v1/chat/channels/{id}/messages
    -d '{ message json payload }'
```


# Create your first MS Teams app

Create an Aurinko account, set up your app, enable necessary APIs, and start using your MS Teams app by accessing the Aurinko API.

First, create an account in the [Aurinko portal](https://app.aurinko.io/). <br>

Create your app, then check API/features that should be activated for your new app. Besides 'Messaging' and 'End usersessions' your addin may need to access CRM APIs.

<div data-full-width="true"><figure><img src="/files/X4HJS9vunyQp7Ex5LyZK" alt=""><figcaption></figcaption></figure></div>

**You're ready to activate your MS Teams app!**

\
**Installing MS Teams app.**

Once you've installed the app, opened its tab, and confirmed your id, you'll see a new user record in Aurinko:

<div data-full-width="true"><figure><img src="https://s3.amazonaws.com/helpscout.net/docs/assets/5dd72e4d2c7d3a7e9ae44753/images/62a0c50392cb8c175b46afd6/file-amc790HtSa.jpg" alt=""><figcaption></figcaption></figure></div>

Now you frontend code can call Aurinko API on behalf of this user. Read this article for more details.


# Installing MS Teams app

Install the Aurinko app in Microsoft Teams to integrate its features seamlessly.

In your MS Teams account go to the **'Apps'** section:<br>

<div data-full-width="true"><figure><img src="https://s3.amazonaws.com/helpscout.net/docs/assets/5dd72e4d2c7d3a7e9ae44753/images/62841aa4b2de5178f88849b2/file-MQZMcyZoVH.jpg" alt=""><figcaption></figcaption></figure></div>

At the bottom choose **'Manage your apps'**:

<figure><img src="https://s3.amazonaws.com/helpscout.net/docs/assets/5dd72e4d2c7d3a7e9ae44753/images/62841b16b2de5178f88849b3/file-UOy8Xr2Pr0.jpg" alt=""><figcaption></figcaption></figure>

Then, choose **'Publish an app'**:

<figure><img src="https://s3.amazonaws.com/helpscout.net/docs/assets/5dd72e4d2c7d3a7e9ae44753/images/62841b6eb2de5178f88849b6/file-C0WFO70nK4.jpg" alt=""><figcaption></figcaption></figure>

and the **'Upload a custom app'** option:

<figure><img src="https://s3.amazonaws.com/helpscout.net/docs/assets/5dd72e4d2c7d3a7e9ae44753/images/62841bf08bf21a2e2b6d50a3/file-BvLJeIXQCE.jpg" alt=""><figcaption></figcaption></figure>

Upload the app package you downloaded from your Aurinko app, click **'Add to a Team'**. The app should be installed and you'll see 'Aurinko' tab!

<figure><img src="https://s3.amazonaws.com/helpscout.net/docs/assets/5dd72e4d2c7d3a7e9ae44753/images/62841ffa8bf21a2e2b6d50bf/file-BikqgH1YZn.jpg" alt=""><figcaption></figcaption></figure>


# Chrome Extensions with Google authentication

Integrate Google authentication into your Chrome extension using Aurinko's backend API for seamless user management and offline access.

Chrome extensions are plugin-like integrations built by third parties into Chrome. They are essentially JavaScript/HTML code that runs in the context of a browser page in a sandbox with special access to Chrome browser API.

Many Chrome extensions are built to provide convenient integrations to a third-party system or service, like Customer Relationship Management, Customer Service, and Project Management,... and the extension developers all end up developing the same or similar elements of their app:

* Provision a backend API that will support the client code.
* Implement user management (login/logout/session) which needs to be correlated with an authenticated user, often a Google or Office 365 user.
* Support one or more 3rd party authorization flows. For example, a user needs to link his or her CRM account, maybe also a cloud file storage.
* Proxy requests to 3rd party API's. Quite often direct API communications from JavaScript are blocked by CORS in browsers.
* Storing various add-in configurations for users or organizations.
* Offline API access. Often special workers are implemented to run in the background when an extension user is offline.

Aurinko aims to provide the necessary backend functionality for these extensions so that developers could focus on the client code to create the best user experiences. Here are the steps to start using Aurinko as a backend API for your Chrome extension:<br>

1. Get your developer API keys and put your app's client id into your client code.<br>
2. To provide Google authentication and to have offline Google API access provision Google OAuth setup.<br>
3. After your extension client code has initialized test if the current user is already authenticated with Aurinko (logged in):

   <mark style="color:red;">`curl -X GET -G https://api.aurinko.io/v1/user`</mark>

   \
   For a logged in user the request will return the user info and its active Aurinko accounts (see step 5). Otherwise, 401 Unauthorized status will be returned in which case your extension needs to ask the user to login (see next step).<br>
4. To authorize a user start the authorization flow in a popup window. This way your extention can also get offline access to Google API:

   ```bash
   curl -X GET -G https://api.aurinko.io/v1/auth/authorizeUser 
        -d clientId='{APPLICATION_ID}' 
        -d accountRole=primary 
        -d serviceType='Google' 
        -d scopes='Mail.Send'
   ```

   \
   The important parameter here is `accountRole=primary` which turns this account authorization into user session initialization (user login). Upon successful authentication and authorization, a session cookie is set which will allow your app to stay recognized by Aurinko until the user logs out.

   \
   The following JavaScript code is executed in your popup as a callback:

   ```javascript
   window.onload=function(){
       if(window.opener!=null){
           window.opener.postMessage("{\\"status\\":\\"success\\",\\"requestId\\":\\
           "a22ed91e-14a1-49f8-a148-9b5bb33af91a\\",\\"type\\":\\"accountAuthResult
           \\"}",'\*');
       }
       window.close();
   } 
   ```

   \
   In addition to the login Aurinko gets access to Google API with the requested scopes: <mark style="color:$danger;">`Mail.Send`</mark>. This will allow your app to work with the Gmail account while the user is not using your extension.<br>
5. Authorize access to a 3rd party API. \
   Contact us at [support@aurinko.io](mailto:mailto:support@aurinko.io) to arrange adding a connector for your system, i.e. {MyCRM}.<br>

   ```bash
   curl -X GET -G https://api.aurinko.io/v1/auth/authorizeUser 
       -d clientId='{APPLICATION_ID}' 
       -d accountRole=secondary 
       -d serviceType='{MyCRM}'
   ```

   \
   Upon a successful authentication and authorization an Aurinko account representing your 3rd party API {MyCRM} will be added and your app can issue the following request again: \ <mark style="color:red;">`curl -X GET -G https://api.aurinko.io/v1/user`</mark>

   \
   The request will return all Aurinko accounts associated with the current user session:<br>

   ```json
   {
       "id": "3df3ce21-07c0-4cec-a8de-ed4c570ee15c",
       "appId": 1,
       "email": "user@yoxel.net",
       "authOrgId": "yoxel.net",
       "trustedIdentity": true,
       "accounts": [
           {
               "id": 2739,
               "serviceType": "Google",
               "type": "primary",
               "active": true,
               "daemon": false,
               "loginString": "user@yoxel.net",
               "email": "user@yoxel.net",
               "name": "Google User",
               "authUserId": "abcdabcb-ad8d-4bee-bd69-787675478785",
               "authOrgId": "yoxel.net",
               "authObtainedAt": "2021-03-21T16:58:56.823Z"
           },
           {
               "id": 2740,
               "serviceType": "{MyCRM}",
               "type": "secondary",
               "active": true,
               "daemon": false,
               "loginString": "user@yoxel.net",
               "email": "user@yoxel.net",
               "name": "Crm User",
               "serverUrl": "https://crm.instance",
               "authUserId": "374",
               "authOrgId": "999",
               "authObtainedAt": "2021-03-21T17:39:10.513Z"
           }
       ]
   }
   ```
6. Now your extension can access either Google API (through Aurinko's unified API) or the 3rd party API. Specify an account id in the special header <mark style="color:red;">`X-Aurinko-AccountId`</mark> and use Aurinko Email/Calendar/Contact to access those accounts.

   ```bash
   curl -H 'X-Aurinko-AccountId: 2739'
       -X GET https://api.aurinko.io/v1/email/messages

   curl -H 'X-Aurinko-AccountId: 2740'
       -X GET https://api.aurinko.io/v1/contacts
   ```


# Google Workspace Add-Ons

Simplify your Google Workspace Add-Ons development with Aurinko's backend services for user management, third-party integrations, and offline access.

Google workspace addons are server based AppScript code that runs on Google servers producing pages for the Google addon engine. The AppScript code runs in a trusted user context, meaning, your code can trust the user id provided by the addon API.

Most addons are built to provide convenient integrations to a third party system or service right from Gmail or Google calendar, like Customer Relationship Management, Customer Service, Project Management,... and the addon developers often end up developing the same or similar elements of their app:

* Implement user management (login/logout/session) which needs to be correlated with an authenticated Google user.
* Support one or more 3rd party authorization flows. For example, a user needs to link his or her CRM account, maybe also a non-Google cloud file storage.
* Proxy requests to 3rd party API's.
* Store various addon configurations for users or organizations.
* Offline mailbox access. Often special workers are implemented to run in background when an addon user is offline.

Plus the big challenge with AppScript is that developers have to develop in a web based editor (your online AppScript project) so it could be difficult to mange complex logic especially if you're new to AppScript.

Aurinko aims to provide the necessary backend functionality for these addons so that developers could simplify their AppScript code and to create the best user experiences. Here are the steps to start using Aurinko to simplify your addon development:<br>

1. Get your developer API keys and put your app's client id into your client code or better pass it from your manifest file as as url parameter.<br>

2. In most cases you want to have offline mailbox access or ability to access Gmail, Calendar, Contacts API so provision your Google OAuth app registrations.<br>

3. Because your AppScript code runs on servers in a safe trusted context you can use Aurinko account management API methods with the app id/secret. The simplest way to register the current addon user with your Aurinko app is the following:<br>

   ```bash
   curl -u ClientId:Secret
       -X POST https:/api.aurinko.io/v1/am/accounts?userAccount=primary
   	-d '{
   	    "serviceType": "Google",
   	    "loginString": "{userEmail}",
   	     "email": "{userEmail}",
   	     "authOrgId": "{emailDomain}",
   	     "active": true
   	}'
   ```

   \
   *Response:*

   ```json
   {
   	"userId": "7082f6ab-6339-4b6a-85f9-afb16515c906",
   	"userSession": "eyJhbGciOiJIUzI1NiJ9.eyJkYXRhIjp7InJtYiI6InRydWUiLCJjbGllbnRJZ
       CI6ImUyNGIwNGZjNmRhYjdjODI3ODEzZGEzODFiNGJmMDZkIiwiaWF0IjoiMTYxNDY5NTQ0OSIsInR
       5cGUiOiJ0b2tlbiIsImVuZFVzZXJJZCI6IjcwODJmNmFiLTYzMzktNGI2YS04NWY5LWFmYjE2NTE1Y
       zkwNiJ9LCJuYmYiOjE2MTQ2OTU0NDksImlhdCI6MTYxNDY5NTQ0OX0.jfpK11tI1QWpfivpu7MP\_Y
       ksIXnKSMqSD9IMfd0Y2fY"
   }
   ```

   \
   Store userId and userSession in AppScript storage so that your code could verify login status after a reload.<br>

   ```javascript
   PropertiesService.getUserProperties().setProperties({
       'userId': response['userId'],
       'userSession': response['userSession']
       })
   ```

4. To obtain offline mailbox access use the OAuth2 flow in a popup window, specify userAccount=primary.

   ```bash
   curl -X GET -G https:/api.aurinko.io/v1/auth/authorize
   	-d clientId='{APPLICATION_ID}'
   	-d serviceType='{MyCRM}'
   	-d userAccount=primary
   	-d scopes='Mail.Read Contacts.Read'
   	-d responseType='none'
   	-d userId='{AurinkoUserId}'
   	-d state='{addonState}'
   	-d returnUrl='{addonReturnUrl}'
   	-d timestamp='{currentTimestamp}'
   	-d userSignature='{signature}'
   ```

   \
   Here is how you produce a timestamp and signature:

   ```javascript
   var timestamp = Math.floor(Date.now() / 1000)
   var userSignature = Utilities.base64EncodeWebSafe(
       Utilities.computeHmacSha256Signature(
           stringToBytes(userId() + timestamp),
   Utilities.base64DecodeWebSafe(auClientSecret)))
   ```

   \
   *state:*

   ```javascript
   var state = ScriptApp.newStateToken()
         .withMethod('authCallback')
         .withTimeout(3600) //??
         .createToken();
   ```

   \
   *returnUrl:*

   ```javascript
   var returnUrl = encodeURIComponent('https://script.google.com/macros/d/'
   	+ ScriptApp.getScriptId() + '/usercallback');
   ```

5. Once a user is provisioned your addon can add other secondary accounts using OAuth2 flow in a popup window. \
   Contact us at [support@aurinko.io](mailto:mailto:support@aurinko.io) to arrange adding a connector for your system, i.e. {MyCRM}.<br>

   ```bash
   curl -X GET -G https:/api.aurinko.io/v1/auth/authorize 
       -d clientId='{APPLICATION_ID}'
   	-d serviceType='{MyCRM}'
   	-d userAccount=secondary
   	-d responseType='none'
   	-d userId='{AurinkoUserId}'
   	-d state='{addonState}'
   	-d returnUrl='{addonReturnUrl}'
   	-d timestamp='{currentTimestamp}'
   	-d userSignature='{addonSignature}'
   ```

   \
   Use <mark style="color:red;">`userAccount=secondary`</mark>, <mark style="color:red;">`userId`</mark> from the the previous step, and sign the request.

   Upon a successful authentication and authorization an Aurinko account representing your 3rd party API {MyCRM} will be added for the user.<br>

6. Aurinko implements user sessions for these addons using <mark style="color:red;">`X-Aurinko-Session`</mark> header so lookup the userSession token you obtained earlier

   <pre class="language-javascript" data-full-width="false"><code class="lang-javascript">function userSession() {
       return PropertiesService.getUserProperties().getProperty('userSession');
   }
   </code></pre>

   \
   And use it to check the current user status

   ```bash
   curl -H 'X-Aurinko-Session: {userSession}'
       -X GET -G https://api.aurinko.io/v1/user
   ```

   \
   The request will return all Aurinko accounts associated with the current user session:

   ```json
   {
       "id": "3df3ce21-07c0-4cec-a8de-ed4c570ee15c",
       "appId": 1,
       "email": "user@yoxel.net",
       "authOrgId": "yoxel.net",
       "trustedIdentity": true,
       "accounts": [
           {
               "id": 2739,
               "serviceType": "Google",
               "type": "primary",
               "active": true,
               "daemon": false,
               "loginString": "user@yoxel.net",
               "email": "user@yoxel.net",
               "name": "Google User",
               "authUserId": "abcdabcb-ad8d-4bee-bd69-787675478785",
               "authOrgId": "yoxel.net",
               "authObtainedAt": "2021-03-21T16:58:56.823Z"
           },
           {
               "id": 2740,
               "serviceType": "{MyCRM}",
               "type": "secondary",
               "active": true,
               "daemon": false,
               "loginString": "user@yoxel.net",
               "email": "user@yoxel.net",
               "name": "Crm User",
               "serverUrl": "https://crm.instance",
               "authUserId": "374",
               "authOrgId": "999",
               "authObtainedAt": "2021-03-21T17:39:10.513Z"
           }
       ]
   }
   ```

7. Now your addon (or a background worker) can access either Gmail API (through Aurinko's unified API) or the 3rd party API. Specify an account id in the special header <mark style="color:red;">`X-Aurinko-AccountId`</mark> and use Aurinko Email/Calendar/Contact to access those accounts.

   ```bash
   curl -H 'X-Aurinko-Session: {userSession}'
   	-H 'X-Aurinko-AccountId: 2739'
   	-X GET https:/api.aurinko.io/v1/email/messages

   curl -H 'X-Aurinko-Session: {userSession}'
   	-H 'X-Aurinko-AccountId: 2740'
   	-X GET https:/api.aurinko.io/v1/contacts
   ```


# Create your first embedded WebEx app

First, create an account in the [Aurinko portal](https://app.aurinko.io/).&#x20;

<br>

Create your app, check 'End user sessions' and 'Messaging' feature for your new app. Besides 'User sessions' your app may need to access CRM or Mailbox APIs.

![](/files/bX0eWkOHaYYRYdUc6jBB)\
\
Next, log into your WebEx developer account (<https://developer.webex.com/>). If you don't have an account yet request a sandbox, then log in with the sandbox credentials, you will need a sandbox to run your new app in:

![](https://s3.amazonaws.com/helpscout.net/docs/assets/5dd72e4d2c7d3a7e9ae44753/images/62b73dcf360964399e46aca5/file-XKzaibGlh2.jpg)

Create a new embedded app:

![](https://s3.amazonaws.com/helpscout.net/docs/assets/5dd72e4d2c7d3a7e9ae44753/images/62aced61f6341f7edc2a648e/file-UUfrqnU54q.jpg)<br>

Select both modes: Meeting and Messaging. Then fill out all required fields.

![](https://s3.amazonaws.com/helpscout.net/docs/assets/5dd72e4d2c7d3a7e9ae44753/images/62acee6bcb3c130081c15718/file-4Ow7oY4Dl9.jpg)<br>

Then specify a valid domain 'example.aurinko.io', start page url '<https://example.aurinko.io/webex/index.html?clientId={AurinkoAppClientId}>', and space start page url '<https://example.aurinko.io/webex/space.html?clientId={AurinkoAppClientId}>'. Now you can create your app.

![](https://s3.amazonaws.com/helpscout.net/docs/assets/5dd72e4d2c7d3a7e9ae44753/images/62acefa4f6341f7edc2a6492/file-xBeQnseSHN.jpg)<br>

On the next page submit your new app for admin approval, so that you could test it in your own organization.&#x20;

![](https://s3.amazonaws.com/helpscout.net/docs/assets/5dd72e4d2c7d3a7e9ae44753/images/62acf7e91e5b41737b38f32a/file-BdTnsXRcDx.jpg)<br>

Go to your sandbox admin site (<https://admin.webex.com>) and approve your new embedded app:

![](https://s3.amazonaws.com/helpscout.net/docs/assets/5dd72e4d2c7d3a7e9ae44753/images/62b74056360964399e46aca7/file-qRZfmNLzho.jpg)

Now you can open your WebEx desktop app and run your app in a room/space

![](https://s3.amazonaws.com/helpscout.net/docs/assets/5dd72e4d2c7d3a7e9ae44753/images/62b7413aeabe9a7235b37c98/file-9pXHWb5Iwn.jpg)<br>

Or when you're in a meeting

![](https://s3.amazonaws.com/helpscout.net/docs/assets/5dd72e4d2c7d3a7e9ae44753/images/62b741eac74a080359c83cf5/file-jGIoWJf142.jpg)\
\
\ <br>


# Storage API


# User management

Workspace addons like Office addins, Google addons, Teams/Slack apps are quite different from regular web apps because they run in a user context of another app with special access to the hosting app API. The addon users don't need to signup for a new account they need to be able to use their existing Id. That is why Aurinko user management is essentially based on `openid`, or a trusted 3rd party oauth2 authentication (i.e. your CRM platform login).

**Office addins / Teams app tabs**

Office addins are essentially JavaScript/HTML code that runs in an IFRAME of a browser. Aurinko implements user session for these addins using a session cookie.

A recommended way for an Office addin using Aurinko to verify a user identity and initialize a user session (to login) is to go through standard steps of an oauth2 flow, at minimum with the "openid" scope. The following example is for an authorization flow in a popup window that an Outlook addin or Teams tab could use:

```
curl -X GET -G https:/api.aurinko.io/v1/auth/authorize 
    -d clientId='{APPLICATION_ID}' 
    -d serviceType='Office365' 
    -d scopes='Mail.Read Mail.Send' 
    -d userAccount='primary' 
    -d returnUrl='https://static.mydomain.com/outlook_auth_callback.html'
```

`userAccount = primary` is the key parameter here which turns this account authorization into user session initialization (user login). Upon successful authentication and authorization the redirect to `returnUrl` will result in setting a session cookie which will allow your app to stay recognized by Aurinko until the user logs out.

In addition to the login Aurinko gets access to Graph API with the following scopes: Mail.Read, Mail.Send. This will allow your app to work with the Office 365 account while the user is not using your addon.

To test if the current user is already authenticated with Aurinko (logged in) call Aurinko user API:

`curl -X GET -G https://api.aurinko.io/v1/user`

For a logged in user the request will return the user info and its active Aurinko accounts:

```
{
  "id": "3df3ce21-07c0-4cec-a8de-ed4c570ee15c",
  "appId": 1,
  "email": "",
  "authOrgId": "abcda5bb-1d9f-0514-a4c6-1234502167890",
  "trustedIdentity": true,
  "accounts": [
    {
      "id": 2739,
      "serviceType": "Office365",
      "type": "primary",
      "active": true,
      "daemon": false,
      "loginString": "",
      "email": "",
      "name": "Addin User",
      "authUserId": "abcdabcb-ad8d-4bee-bd69-787675478785",
      "authOrgId": "abcda5bb-1d9f-0514-a4c6-1234502167890",
      "authObtainedAt": "2021-03-21T16:58:56.823Z"
    }
  ]
}
```

Otherwise, 401 Unauthorized status will be returned.

**Google workspace addons**

Google workspace addons are server based code (AppScript) that runs on Google servers producing pages to be shown by the Google addon engine. The AppScript code runs in a trusted context meaning your code can trust the user id provided by the addon API.\
\
Aurinko implements user sessions for these addons using a special authorization header  `X-Aurinko-Session`.

Because the code runs on servers in a safe trusted context you can use Aurinko account management API methods with app id/secret. The simplest way to register the current addon user with your Aurinko app is the following:

```
curl -u ClientId:Secret -X POST https:/api.aurinko.io/v1//am/accounts?userAccount=primary \
	-d '{
        	"serviceType": "Google",
    		"loginString": "{userEmail}",
    		"email": "{userEmail}",
    		"authOrgId": "{emailDomain}",
    		"active": true
	}'
```

Response:

```
{
  "userId": "7082f6ab-6339-4b6a-85f9-afb16515c906",
  "userSession": "eyJhbGciOiJIUzI1NiJ9.eyJkYXRhIjp7InJtYiI6InRydWUiLCJjbGllbnRJZCI6ImUyNGIwNGZjNmRhYjdjODI3ODEzZGEzODFiNGJmMDZkIiwiaWF0IjoiMTYxNDY5NTQ0OSIsInR5cGUiOiJ0b2tlbiIsImVuZFVzZXJJZCI6IjcwODJmNmFiLTYzMzktNGI2YS04NWY5LWFmYjE2NTE1YzkwNiJ9LCJuYmYiOjE2MTQ2OTU0NDksImlhdCI6MTYxNDY5NTQ0OX0.jfpK11tI1QWpfivpu7MP_YksIXnKSMqSD9IMfd0Y2fY"
}
```

Store userId and userSession in AppScript storage so that your code could verify login status after reloading.&#x20;

Once a user is provisioned your addon can add other secondary accounts using OAuth2 flow in a popup window. Contact us at [support@aurinko.io](mailto:mailto:support@aurinko.io) to arrange adding a connector for your system, i.e. {MyCRM}.

```
curl -X GET -G https:/api.aurinko.io/v1/auth/authorize 
	-d clientId='{APPLICATION_ID}' 
	-d serviceType='{MyCRM}' 
	-d state='{addonState}'
	-d userAccount=secondary 
	-d responseType='none' 
	-d userId='{AurinkoUserId}'
	-d returnUrl='{addonReturnUrl}' 
	-d timestamp='{currentTimestamp}' 
	-d userSignature='{signature}'
```

Use `userAccount=secondary`, `userId` from the the previous step, and sign the request. For more details see Google workspace addons.

**Slack apps**

Slack apps are server based code that runs on your servers producing formatted messages to be shown by Slack. Your code most probably runs in a trusted context, meaning, your code can trust the user id provided by Slack API.\
\
Aurinko will automatically provision users for your app upon receiving certain events directed at your app, i.e. command, app\_home\_visited, app invited to a channel

<br>


# What is Dynamic (Virtual) API?

### Aurinko /dynamic API

***

The Aurinko /dynamic API empowers developers to create robust and adaptable customer integrations for Customer Relationship Management (CRM) and Enterprise Resource Planning (ERP) platforms. It provides a powerful alternative to traditional drag-and-drop editors by enabling you to build integrations using code, offering greater flexibility and control over the integration process.

### **Key Features**

***

* **Customer-Configurable Integrations:** Aurinko Dynamic API breaks away from the limitations of pre-built integrations. Developers can design integrations that adapt to specific customer requirements, allowing for a high degree of customization.
* **Code-Based Development:** Build integrations using your preferred coding language and tools. This approach offers more control and flexibility compared to visual editors.
* **Virtual Unified Data Models:** Create tailored virtual unified data models that provide a simplified view of your customer's data. These models can still access and manipulate any underlying data object or field, including standard and custom ones.
* **Virtual Model Mappings:** Manage complex enterprise customer setups efficiently through virtual model mappings. Have multiple customer specific mapings for the same virtual data model. This simplifies integration development and maintenance for intricate customer environments.

### **Beyond Inflexible Unified APIs**

***

The Aurinko Dynamic API goes beyond the constraints of static, inflexible unified APIs. It empowers developers to build integrations that are tailored to the specific needs of each customer, ensuring a more adaptable and future-proof solution.

### **Focus on Key CRM and ERP Platforms**

***

The Aurinko Dynamic API currently focuses on providing integrations for leading CRM and ERP platforms, i.e. Salesforce, Hubspot, Sugar CRM, Microsoft Dynamics, NetSuite, Eclipse ERP, Acumatica. This ensures that developers have the tools they need to connect to the most widely used business applications.

{% hint style="info" icon="file-lines" %}
Check out the following blog post to learn about the origins of the Dynamic API: [Aurinko Virtual API: A Unified Approach for Custom CRM Integrations](https://www.aurinko.io/blog/virtualized-unified-api/).
{% endhint %}


# Getting Started with Dynamic API

### Aurinko account setup

***

First, create your account in the [Aurinko portal](https://app.aurinko.io/), then follow the guide to [get your developer API keys](/getting-started/get-your-developer-api-keys).\
\
When presented with the **New Application** dialog choose the CRM feature.

<figure><img src="/files/qVDzMwl5gpzhitO2ORwy" alt="" width="563"><figcaption></figcaption></figure>

Next, navigate to **Settings** and specify your app's OAuth details (clientId+secret) for your Salesforce and Hubspot integrations.

<figure><img src="/files/5dkI3VipwMXfr39MXRjW" alt=""><figcaption></figcaption></figure>

Now, navigate to **Accounts** to test creating Salesforce and/or Hubspot accounts.&#x20;

<figure><img src="/files/1I1DKQ5nEc3Y8MuaBDua" alt=""><figcaption></figcaption></figure>

Once a new account is added you can find its Aurinko access token on the **Account** page. You will need this token to make API calls later.

<figure><img src="/files/5kcyNtFs8TnaEGVguhLG" alt=""><figcaption></figcaption></figure>

Upon adding a CRM account, its metadata is automatically loaded into the system. You will be able to examine the provider metadata when adding/ediging object and field mappings.

The **Virtual APIs** tab displays your virtual data models. If you have not created any models yet, start by clicking 'New virtual model'.

<figure><img src="/files/rdqQodfNUEyDGJffY5GV" alt=""><figcaption></figcaption></figure>

You can quickly create a new model from an existing template with a number of CRM provider mappings, i.e. Hubspot, Salesforce, MS Dynamics:\
\
![](/files/WU0Tj4DqR756eEIJHUC6)

Our AurinkoCRM template will clone a model with four objects: Company, Contact, Deal and User.

<figure><img src="/files/B3MFack6TJ8XcV39Ze2D" alt=""><figcaption></figcaption></figure>

and the following mappings/configurations will be pre-populated:\
\
![](/files/Lnxo98NKhqKcKBLvnNfZ)

Choose one of them to see how your virtual model is mapped to a provider model, like Hubspot:

<figure><img src="/files/0z7SpWRZ66Z9XqtD7XND" alt=""><figcaption></figcaption></figure>

Click any object to see its field mappings:

<figure><img src="/files/7whmurhqTyLUVUfgUwIM" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
**Note:** the 'Configuration Id', you need to reference this id when using the Dynamic API.
{% endhint %}

Here is the same Contact object mapped to the Salesforce Contact object (configuration id: 403):

<figure><img src="/files/eCODnCcusUuq8Cos4Iwc" alt=""><figcaption></figcaption></figure>

You can have as many mapping configurations as you need. Many Salesforce and Hubspot instances have their own customizations so you may need a CRM configuration per customer.\
Create them in Aurinko once needed and remember their ids. You will be able to reference a specific configuration when calling the /dynamic API.

#### **Understanding Dynamic API Endpoints**

Aurinko Dynamic API offers a unified API experience, but with the key advantage of being virtualized. This means the API endpoints are dynamically generated based on your configuration. Here's an overview of the endpoint structure:

* **Metadata Endpoints:**
  * `/dynamic/{configId}/metadata/{objName}`: Retrieves metadata for a specific CRM object (e.g., contacts).
  * `/dynamic/{configId}/metadata/{objName}/{fieldName}`: Retrieves metadata for a particular field within a CRM object.
* **Object Endpoints:**
  * `/dynamic/{configId}/objects/{objName}`: Retrieves a list of objects of a specific type (e.g., all contacts).
  * `/dynamic/{configId}/objects/{objName}/{id}`: Retrieves a single CRM object by its ID.
  * `/dynamic/{configId}/objects/{objName}/{id}/{childRelationship}`: Retrieves data related to a child relationship of a specific CRM object.


# Adding a Custom Service Type

Define custom Aurinko service types to connect private APIs and internal services to Aurinko. Access custom services through the Dynamic API and Aurinko Sync.

Not all APIs are public or intended for broad platform ecosystems like Salesforce, HubSpot, or Microsoft Dynamics. Many systems rely on private, internal APIs that need to remain secure and restricted to internal workflows.

To support these use cases and further advance Aurinko as a [capability platform](https://www.aurinko.io/blog/the-case-for-a-capability-platform/), developers can now **add custom service types** in Aurinko.

Inspired by intuitive API builders like Bubble’s API connector, this developer UI allows you to define a new, custom Aurinko <mark style="color:$danger;">`serviceType`</mark> representing your proprietary backends or internal microservices. Once created, your custom service can immediately be queried and managed through the Dynamic API across your team's applications.

### Why Define a Custom Service Type in Aurinko?

***

Wrapping your private internal services into a custom Aurinko service type turns disparate backend systems into standardized, enterprise-grade infrastructure:

* **Canonical Access via Dynamic API:** Standardize how internal services present data. Dynamic API normalizes your custom endpoints behind unified RESTful patterns, ensuring clean object mapping and consistent response structures across all applications.
* **Streamlined Brightsync Activation:** Instead of building complex custom sync pipelines from scratch, defining your internal schema under a custom service type allows new teams to rapidly map their data models to **Aurinko Sync (Brightsync)**. This instantly activates pre-built activity capture, calendar, and contact synchronization capabilities.
* **Built-in Authorization & Token Management:** Offload access control. Your custom service automatically hooks into Aurinko's unified authentication infrastructure, handling token management, and session validation without requiring custom auth middleware.
* **Out-of-the-Box Rate Limiting & Throttling:** Guard internal backend services against traffic spikes and accidental infinite loops. Aurinko enforces configurable rate limits and request queuing at the gateway layer before traffic hits your servers.
* **Problematic Request & Endpoint Capture:** Gain instant operational visibility without digging through server logs. When a call fails, the developer UI automatically captures and displays the last problematic request, payload, giving your team immediate insight for fast root-cause analysis.
* **Automated Webhooks & Event Dispatching:** Avoid building bespoke event-processing logic. Aurinko standardizes event subscriptions and webhook delivery for updates originating from your internal services.
* **Unified Developer Experience:** Internal engineering teams use a single, familiar developer portal, data model, and SDK setup—whether they are interacting with third-party SaaS APIs or your internal proprietary tools.

{% hint style="info" %}
**Note:** The user interface for adding custom service types is currently in an early preview stage. Features, layout, and visual elements will evolve rapidly based on user feedback.
{% endhint %}


# Does Aurinko provide a shared verified Google OAuth application?

Aurinko chooses not to provide a shared verified Google Cloud OAuth application at this time.

Instead, each customer configures and uses their own Google OAuth application. This approach aligns with Google's OAuth verification model, where the organization operating an application is responsible for managing its own OAuth credentials, verification process (when required), and compliance with Google's API policies.

Using a customer-owned OAuth application provides:

* Full ownership of the Google Cloud project and OAuth credentials.
* Independent management of Google's verification lifecycle.
* Control over security and compliance requirements.
* No dependency on a shared OAuth client managed by a third party.

Although configuring a Google OAuth application requires additional setup, it gives organizations full control over their Google integration and authentication infrastructure.

{% hint style="info" icon="file-lines" %}
See the [**Google OAuth Setup**](https://docs.aurinko.io/authentication/google-oauth-setup) guide for configuration instructions.
{% endhint %}

{% hint style="info" icon="file-lines" %}
To learn more about why Aurinko does not provide a shared Google OAuth application, read our blog post: [**The Hidden Risk of Using Shared OAuth Apps (Nylas, Unipile, etc.)**](https://dev.to/aspantel/the-hidden-risk-of-using-shared-oauth-apps-nylas-unipile-etc-3p5f).
{% endhint %}


# How does Aurinko billing work?

Aurinko bills monthly based on the number of **active accounts**.

An account is considered **active** if, during a billing month, it exceeds either of the following thresholds:

* more than **10 API calls**, or
* more than **1 MB (1024 KB)** of transferred data.

Once an account becomes active during the billing month, it is included in that month's billing, even if it is disconnected or deleted before the end of the month.

### How are duplicate accounts billed?

***

Aurinko performs mailbox deduplication for billing purposes.

Multiple Aurinko accounts connected to the **same mailbox** are billed as a **single active account**.

*For example:*

* Connecting the same Gmail mailbox multiple times counts as **one** billable account.
* Connecting one Gmail mailbox and one Outlook mailbox counts as **two** billable accounts because they are different mailboxes.

### Can Aurinko mirror my application's free trial?

***

**Yes.**

Upon request, Aurinko can mirror your application's trial period. During the mirrored trial, newly connected accounts are not billed. Billing begins automatically once your application's trial has ended.

For more information about enabling billing and trial periods, see [**Subscribe to Aurinko**](https://docs.aurinko.io/getting-started/subscribe-to-aurinko).

### What pricing tiers are available?

***

| Plan          | Included APIs                                   | Monthly traffic | Price                              |
| ------------- | ----------------------------------------------- | --------------- | ---------------------------------- |
| Unified API   | Calendar, Contacts, or Tasks (one selected API) | Up to 1 GB      | **$1 / active account / month**    |
| Email / CRM   | Email (non-IMAP) or CRM (one selected API)      | Up to 1 GB      | **$1.50 / active account / month** |
| Full Platform | Any number of APIs, including IMAP              | Unlimited       | **$2 / active account / month**    |


# What is BrightSync?

BrightSync is Aurinko's sync solution for automating two-way sync of calendars, contacts, tasks, and one-way email logging between user mailboxes and business systems.

**BrightSync** is Aurnko's pre-built sync logic for business platform providers (i.e. CRM, ATS, Project Management) or platform add-on providers that want to automate calendar, email, contacts, tasks synchronization for their users. The sync logic is capable of

* Two-way calendar sync between a user mailbox and the business system
* One-way email logging to the business system with contact/opportunity matching
* Two-way contacts sync between a user mailbox and the business system
* Two-way tasks sync between a user mailbox and the business system

A platform connector for your business system is required to activate the sync logic.&#x20;

{% hint style="info" icon="file-lines" %}
Please see [CRM connector requirements](/brightsync/crm-connector-requirements).
{% endhint %}

{% hint style="info" icon="envelope-open-text" %}
Сontact us at <support@aurinko.io> to discuss details.
{% endhint %}

### Core Benefits

***

1. **Automated Data Handling**
   * **Handles Webhooks**: Automatically processes Aurinko webhooks as signals to initiate the sync process.
   * **API Logging**: Directly logs emails, creates calendar events, contacts, tasks to your CRM via your API.
   * **Thread Grouping**: Groups emails by a global thread, which is more robust than a single user's mailbox thread.
   * **Meeting Logging**: The calendar sync handles meeting data similarly to how email syncs email threads (groups by a global meeting is, de-duplicates, and matches/creates contacts).<br>
2. **Smart Contact and Company Matching**
   * **CRM Contact Matching**: Loads new emails and calendar events and actively searches for matching contacts in your CRM.
   * **Sync Cache**: Retains unmatched emails and meetings in a sync cache for one month and retries syncing daily, in case a contact is created later.
   * **Optional Auto-Creation**: Can be configured to auto-create contacts for external emails. It avoids logging internal communications by understanding your domain.
   * **Company Analysis**: Can analyze and auto-create companies if a corresponding domain is found (or not found) when creating new contacts.<br>
3. **Data Integrity and Efficiency**
   * **Email Deduplication**: Ensures only one copy of an email is logged to the CRM, even if received by multiple users (e.g., those who were CC'ed).
   * **Meeting Deduplication**: Ensures only one copy of a meeting is synced to the CRM, even if multiple users are attendees.
   * **Efficient Syncing**: By deduplicating, it schedules only one user for syncing that specific email or meeting, reducing unnecessary processing.
   * **Duplicate Prevention**: The contacts sync does similarity analysis to prevent migrating/creating similar contacts.


# CRM connector requirements

To activate BrightSync for your CRM, we need to add a new platform connector using your REST API. The connector requires authentication, users, accounts, contacts, and email sync methods.

To activate BrightSync (prebuilt CRM sync logic) for your CRM platform we need to add a new platform connector that will use your REST API. The CRM connector requires a number of API methods that we ask you to describe:

### **Authentication**

***

The connector needs to connect to your API on behalf of your user. How does your API authenticate?

* Using OAuth2 Bearer token
* Using Basic auth with an API token
* Using another auth method

### **CRM Users**

***

A User object represents a user in your CRM system (OrgId, UserId, Name, Email, Timezone). The connector needs to be able to receive information about the current user and optionally be able to find other user records:

* **getMe** - current user information (OrgId, UserId, Name, Email, Timezone)
* **getUsersByEmail** (email or list of emails) - good to have

### **Sync Specific API Requirements**

***

* [Email Sync](/brightsync/crm-connector-requirements/email-sync-api-requirements)
* [Calendar Sync](/brightsync/crm-connector-requirements/calendar-sync-api-requirements)


# Email Sync API Requirements

This document outlines the required API endpoints and data structures for integrating your CRM with BrightSync's Email Synchronization features.

BrightSync will interact with the following endpoints on your CRM connector to log, retrieve, and update email objects.

### Email Logging Object

***

BrightSync requires a CRM object (e.g., an Email, Activity, Task, or Note) that can store logged email content. Your API must be capable of receiving a payload containing the following or similar fields. At least subject and body should be supported.

<table data-header-hidden><thead><tr><th width="127.1087646484375"></th><th width="116.4698486328125"></th><th></th></tr></thead><tbody><tr><td>API Field</td><td>Data Type</td><td>Description</td></tr><tr><td><code>msgId</code></td><td>String</td><td>Unique identifier assigned to the logged message by a mailbox provider, i.e. Gmail or Outlook.</td></tr><tr><td><code>syncThreadId</code></td><td>String</td><td>BrightSync generated global thread ID to group related messages.</td></tr><tr><td><code>inReplyTo</code> </td><td>String</td><td>Message ID of the email this message is a reply to.</td></tr><tr><td><code>receivedAt</code></td><td>DateTime</td><td>Timestamp when the message was received.</td></tr><tr><td><code>rfc822MsgId</code> </td><td>String</td><td>The Internet Message ID (RFC822 header) </td></tr><tr><td><code>subject</code></td><td>String</td><td>Email subject.</td></tr><tr><td><code>fromAddress</code>, <code>fromName</code></td><td>String</td><td>Sender details.</td></tr><tr><td><code>toAddresses</code>, <code>ccAddresses</code>, <code>bccAddresses</code></td><td>List</td><td>Recipient lists.</td></tr><tr><td><code>textBody</code>, <code>htmlBody</code></td><td>String</td><td>Email content.</td></tr><tr><td><code>attachments</code></td><td>List&#x3C;Attachment></td><td>List of attachment objects.</td></tr><tr><td><code>relatedTo</code></td><td>RealtedTo</td><td>The CRM object(s) (Contact, Lead, etc.) this email is logged against.</td></tr></tbody></table>

### Email Sync API Endpoints

***

At minimum an API endpoint for creating an Email object should be provided:\
\
**Create New Email** - Endpoint for creating a new email record.\
`POST/api/v1/emails`

**Load Email by ID** - Endpoint to retrieve an email using the CRM's native record ID.\
`GET/api/v1/emails/{id}`

**Lookup by RFC822 Msg ID** - Endpoint to look up an existing email using the `rfc822MsgId`.\
`GET/api/v1/emails?rfc822MsgId={value}`

**Update Existing Email** - Endpoint for updating an existing email object. While rare, this is required for specific sync scenarios, such as linking the email to a newly created contact.\
`PATCH` or `PUT` `/api/v1/emails/{id}`

### Contact API Endpoints

***

Email Sync relies on the following lookups to match emails to existing records, or to facilitate the optional auto-creation process.

**Lookup Contact by Email** - Endpoint to look up a Contact record using one or more email addresses. BrightSync will pass a list of email addresses, or call the aPI multiple times and the API should return a list of matching Contact objects.\
`GET/api/v1/contacts/lookup?emails={list_of_emails}`

**Load Contact by ID** - Endpoint to retrieve a single Contact record using its unique ID.\
`GET/api/v1/contacts/{id}`

**Lookup Company by Domain** - Endpoint to look up a Company/Account record using a domain name (e.g., `aurinko.io`). This is used for auto-creation logic.\
`GET` `/api/v1/companies/lookup?domain={domain_name}`

The Contact Object provided by your API in lookup and load operations must include at least the following minimal fields for BrightSync to perform matching and logging operations:

| Field Name       | Data Type     | Purpose                                                                                                      |
| ---------------- | ------------- | ------------------------------------------------------------------------------------------------------------ |
| `id`             | String        | The unique identifier for the Contact in your CRM.                                                           |
| `firstName`      | String        | Contact's first name.                                                                                        |
| `lastName`       | String        | Contact's last name.                                                                                         |
| `emailAddresses` | List\<String> | A list of all known email addresses for the contact (Primary, Secondary, etc.). Required for email matching. |
| `companyId`      | String        | The ID of the associated Company/Account record (if applicable).                                             |


# Calendar Sync API Requirements

This document outlines the required API endpoints and data structures for integrating your CRM with BrightSync's Calendar Synchronization features.

BrightSync will interact with the following endpoints on your CRM connector to create, retrieve, and update calendar event objects.

### Calendar Event Object

***

BrightSync requires a CRM object (e.g., a Meeting or Calendar Event object) that can store the following or similar fields to facilitate two-way synchronization.&#x20;

| API Field        | Data Type       | Description                                                                              |
| ---------------- | --------------- | ---------------------------------------------------------------------------------------- |
| `id`             | String          | The unique identifier for the event in your CRM. Required for two-way sync.              |
| `subject`        | String          | The title of the calendar event.                                                         |
| `description`    | String          | The description or agenda of the meeting.                                                |
| `startTime`      | DateTime        | The start date and time of the event.                                                    |
| `endTime`        | DateTime        | The end date and time of the event.                                                      |
| `location`       | String          | The physical or virtual meeting location.                                                |
| `allDay`         | boolean         | Flag indicating if the event spans the entire day.                                       |
| `private`        | boolean         | Flag indicating if the event details should be hidden.                                   |
| `attendees`      | List\<Attendee> | A list of meeting participants (see structure below).                                    |
| `parentId`       | Long            | The ID of the parent meeting, for calendars that create child events for each attendee.  |
| `relatedTo`      | RealtedTo       | The CRM object(s) (Contact, Account, Opportunity) this meeting is linked/logged against. |
| `lastModifiedAt` | DateTime        | Timestamp of the last modification. Crucial for delta sync operations.                   |

#### Attendee Object Structure

***

The `Attendee` object within the event payload must support the following structure:

| API Field      | Data Type | Description                                                                  |
| -------------- | --------- | ---------------------------------------------------------------------------- |
| `userId`       | String    | The CRM user ID if the attendee is an internal system user.                  |
| `emailAddress` | String    | The email address of the attendee.                                           |
| `contactId`    | Long      | The ID of the associated Contact record in your CRM (if applicable).         |
| `status`       | String    | The RSVP status of the attendee (e.g., "Accepted," "Declined," "Tentative"). |

### Calendar Sync API Endpoints

***

Assuming one primary calendar. Additinal Calendar List API may be required if CRM supports multiple user calendars.

#### Read/Retrieve (Delta Sync) Endpoints

<table><thead><tr><th>Operation</th><th>Requirement</th><th width="82.7352294921875">Method</th><th>Endpoint Example</th></tr></thead><tbody><tr><td>Retrieve All in Interval</td><td>Endpoint to receive all events within a specified time range.</td><td><code>GET</code></td><td><code>/api/v1/events?startAt={timestamp}&#x26;endAt={timestamp}</code></td></tr><tr><td>Delta Sync (Modified/Changed)</td><td>Endpoint to retrieve events modified since a given timestamp (<code>lastModifiedAt</code>).</td><td><code>GET</code></td><td><code>/api/v1/events?since={timestamp}</code></td></tr><tr><td>Deleted Events Retrieval</td><td>Method to retrieve events that have been deleted (either via a <code>showDeleted=true</code> flag or a separate endpoint).</td><td><code>GET</code></td><td><code>/api/v1/deletedEvents?since={timestamp}</code></td></tr><tr><td>Load Event by ID</td><td>Standard endpoint to load a single event by its unique CRM ID.</td><td><code>GET</code></td><td><code>/api/v1/events/{id}</code></td></tr></tbody></table>

#### Write (CRUD) Endpoints

| Operation             | Requirement                                                           | Method           | Endpoint Example      |
| --------------------- | --------------------------------------------------------------------- | ---------------- | --------------------- |
| Create New Event      | Endpoint for creating a new calendar event in the CRM.                | `POST`           | `/api/v1/events`      |
| Update Existing Event | Endpoint for updating an existing calendar event based on its CRM ID. | `PATCH` or `PUT` | `/api/v1/events/{id}` |
| Delete Event          | Endpoint for deleting a calendar event based on its CRM ID.           |                  |                       |


# Getting Started with BrightSync API

BrightSync API lets developers manage Aurinko's sync logic between mailboxes and business platforms for seamless two-way calendar, contacts, and tasks sync.

BrightSync API allows developers to configure, activate, and manage Aurinko’s pre-built sync logic, which is a worker process migrating data between mailbox or email marketing providers and one business platform (also called “portal”):

* Two-way calendar sync between user mailboxes and a business platform
* One-way email logging to a business platform with contact/opportunity matching
* Two-way contacts sync between user mailboxes and a business platform
* Two-way tasks sync between user mailboxes and the business platform

#### **Prerequisites**:

1. A custom Aurinko connector for your business platform needs to be created by Yoxel. See [CRM Connector Requirements](https://docs.aurinko.io/brightsync/crm-connector-requirements).
2. You need to obtain appId & appSecret from Yoxel.

{% hint style="info" icon="envelope-open-text" %}
Please contact us at <support@aurinko.io> to discuss your integration.
{% endhint %}

### Signing up <a href="#h-signing-up-8" id="h-signing-up-8"></a>

***

BrightSync runs a sync job for every registered user so first step for your integration is to create a sync account for your user:\
POST user signup details to the [/signup](http://my.yoxel.com/testapi/v2/signup) endpoint:

```json
{  
    "appId": "{appId}",  
    "compExtId": "c1647588",  
    "companyName": "ABC Co.",  
    "instanceUrl": "https://api.myplatform.com",  
    "userExtId": "u886450",  
    "firstName": "John",  
    "lastName": "Smith",  
    "email": "jsmith@abc.co",   
    "admin": true,  
    "timeZoneInfo": "America/Los_Angeles",  
    "apiHash":"B5HIlStgADzu5VkN5/dSaagNgQ4CJa5ynwCvs2E6M59BanOQkvmA9YP4p1TlIhUR",  
    "requestTimestamp": 12234875958   
}
```

Where:

* **appId** - ID we assign to your integration, together with a secret key
* **compExtId** - Org/Tenant/Company ID that the user is associated with in your platform. BrightSync groups all users by their organizations.
* **companyName** - the name of the Org/Tenant/Company
* **instanceUrl** - API URL associated with the Org/Tenant/Company.
* **userExtId** - your platform’s user ID
* **apiHash** - HMAC signature using your app secret
* r**equestTimestamp** - time of the request, is used in the signature calculation

Here is the sample Java code to generate the apiHash:

```java
final Mac mac = Mac.getInstance("HmacSHA256");

mac.init(new SecretKeySpec("{appSecret}".getBytes(), "HmacSHA256")); 

signupRequest.setRequestTimestamp(System.currentTimeMillis());

signupRequest.setApiHash(new String(Base64.encodeBase64(mac.doFinal("OrgId:UserId:".concat(sr.getRequestTimestamp().toString()).getBytes()))));  
```

This call returns an access token for the user which should be used in all other API calls:

<mark style="color:red;">`{"accessToken":"djIjMjYxMCN2O...jIxNDU5"}`</mark>

### Access token <a href="#h-access-token-8" id="h-access-token-8"></a>

***

The access token returned by the signup call should be used to call all other API methods.

You need to use the <mark style="color:red;">`BASIC`</mark> HTTP authentication with <mark style="color:red;">`username={access_token}`</mark>, <mark style="color:red;">`password=X`</mark>.

<mark style="color:red;">`GET https://api.yoxel.com/v2/me`</mark>

*Response:*

```json
{
    "uid": 1,
    "name": "John Smith",
    "firstName": "John",
    "lastName": "Smith",
    "email": "jsmith@abc.co",
    "addedBy": 0,
    "extId": "u886450",
    "timeZoneInfo": "America/Los_Angeles",
    "disabled": false,
    "admin": false,
    "templCount": 0
}
```

{% hint style="warning" %}
*If you get the <mark style="color:red;">`401 - Unauthorized`</mark> HTTP status in response that means that the user access token is invalid and you need to repeat the* [*/signup*](http://my.yoxel.com/testapi/v2/signup)*.*
{% endhint %}

### Services <a href="#h-services-8" id="h-services-8"></a>

***

BrightSync needs to be able to connect to remote accounts which are called *services*.

First, check if services already exist for the current user as there are scenarios when some services are auto-populated during signup, i.e. if you’d configured Org wide sync templates (see about sync templates below).

<mark style="color:red;">`GET https://api.yoxel.com/v2/services`</mark>

Refer to the [/services API refs](https://sync-docs.aurinko.io/#tag/Services/operation/getServices) for more details. Here is an example of the key data returned:

```json
[
  {
    "id": 1,
    "type": "GOOGLE|OFFICE365|EXCHANGE|SFORCE|MYPLATFORM",
    "offline": true,
    "displayName": "My Google",
    "fullName": "John Smith",
    "email": "jsmith@abc.com",
    "server": "https://api.google.com",
    "syncData": {...},
    "scanEmail": true,
    "scanEmails": {...configuration options...},
    "fwdEmail": true,
    "fwdEmails": {...configuration options...},

    "importEvents": true,
    "calendar": {...configuration options...},    
    "importContacts": true,
    "contacts": {...configuration options...},
    "importTasks": true,
    "tasks": {...configuration options...},
    "authRedirectUrl": 
    "url if unauthorized",

    "templId": 0,    
    "templLocked": true,
    "authError": "string"
  },
  ...
  
]
```

{% hint style="warning" %}
*Non-null <mark style="color:red;">`authRedirectUrl`</mark> means the user has not authorized BrightSync to access this account yet or the access token has been lost. Direct your user to <mark style="color:red;">`authRedirectUrl`</mark> in a browser popup window to get a new authorization.*
{% endhint %}

#### **Creating a new service**

<mark style="color:red;">`POST https://api.yoxel.com/v2/services`</mark>

#### **Updating an existing service**

<mark style="color:red;">`GET https://api.yoxel.com/v2/services/{id}`</mark>

### Sync settings <a href="#h-sync-settings-7" id="h-sync-settings-7"></a>

***

The [/services/syncSettings](https://sync-docs.aurinko.io/#tag/Services/operation/getSyncSettings) endpoints allow you to configure a user sync between two services: one business platform (also called *portal*) and one mailbox (i.e. Google, Office 365,…) or an email marketing account (i.e. Hubspot, Constant Contact,…)

<mark style="color:red;">`GET https://api.yoxel.com/v2/services/syncSettings`</mark>

<mark style="color:red;">`PUT https://api.yoxel.com/v2/services/syncSettings`</mark>

*Here is an example of the key options you control:*

```json
{
    "logEmail": true,
    "emailSkipDomains": "string",
    "emailFetchAttachments": true,
    "emailCreateLeads": true,
    "emailCreateContacts": true,
    "emailAutoDetectDeal": true,
    "emailCreateCompany": true,
    ...

    "syncCalendar": true,
    "calSyncDirection": "BOTH|TO_PORTAL|FROM_PORTAL",
    "calSyncPrivate": true,
    "calFetchAttachments": true,
    "calMailboxSyncAll": true,
    "calMailboxSyncTags": "string",
    "calMailboxSyncMeetingsOnly": true,
    "calPastWeeks": 0,
    "calFutureWeeks": 0,
    ...

    "syncContacts": true,
    "contSyncDirection": "BOTH|TO_PORTAL|FROM_PORTAL",
    "contCreateCompany": true,
    "contPortalSyncAll": true,
    "contMailboxSyncAll": true,
    "contPortalSyncMine": true,
    "contPortalSyncTags": "string",
    "contMailboxSyncTags": "string",
    "contMailboxSyncDeleted": true,
    ...
    
    "syncTasks": true,
    "taskSyncDirection": "BOTH|TO_PORTAL|FROM_PORTAL",
    "taskMailboxSyncAll": true,
    "taskMailboxSyncTags": "string"
}
```

### Sync activation <a href="#h-sync-activation-7" id="h-sync-activation-7"></a>

***

Initially, BrightSync for a new user is in the “review” mode, except when locked templates are in place that auto-provision all user services (see below about the templates).

#### Call GET [/sync](https://sync-docs.aurinko.io/#tag/Sync/operation/getSyncInfo) to see the sync status:

```json
{
    "userSyncEnabled": true,
    "pkgCheckFailed": true,
    "userLastSynced": "2019-08-24T14:15:22Z",
    "syncState": "IDLE",
    "lastRequest": "2019-08-24T14:15:22Z",
    "needReview": ["CALENDAR", "EMAIL", "CONTACTS", "TASKS"]
}
```

{% hint style="warning" %}
*Non-empty <mark style="color:red;">`needReview`</mark> indicates if any of the sync modules are in the review mode.*
{% endhint %}

In this mode, you can run the sync but it will only load data from remote accounts without updating/creating anything:

<mark style="color:red;">`POST /sync`</mark>

*<mark style="color:blue;">Payload:</mark>*

```json
{'initial':'true'}
```

#### **To check progress:**

<mark style="color:red;">`GET /sync`</mark>

#### Check pre-sync reports while in the review mode:

<mark style="color:red;">`GET /rules/<type>/report`</mark>

#### Activate the sync completely by calling [/allowSync](https://sync-docs.aurinko.io/#tag/Sync/operation/allowRulesSync):

<mark style="color:red;">`PUT /rules/<type>/allowSync`</mark> or <mark style="color:red;">`PUT /allowSync`</mark>

*<mark style="color:blue;">Payload:</mark>*

```
{'CALENDAR', 'TASKS'}
```

#### Then run the sync:

<mark style="color:red;">`POST /sync`</mark>

*<mark style="color:blue;">Payload:</mark>*

```json
{'initial':'false'}
```

#### **To check progress:**

<mark style="color:red;">`GET /sync`</mark>

### Monitoring sync progress <a href="#h-monitoring-sync-progress-6" id="h-monitoring-sync-progress-6"></a>

***

The sync progress can be monitored by polling its [current status](https://sync-docs.aurinko.io/#tag/Sync/operation/getSyncInfo):

<mark style="color:red;">`GET /sync`</mark>

```json
{
    "userSyncEnabled": true,
    "pkgCheckFailed": true,
    "userLastSynced": "2019-08-24T14:15:22Z",
    "syncState": "IDLE",
    "lastRequest": "2019-08-24T14:15:22Z",

    "needReview": null,

    "errors": [],
    "errMessage": "string",
    "errTimestamp": "2019-08-24T14:15:22Z",
    "errSvcId": 0
}
```

Check <mark style="color:red;">`syncState`</mark>:

* **IDLE** - the sync is not currently running
* **REQUESTED** - a request for syncing was received but the sync is not running yet
* **QUEUED** - the sync is in a queue to be run
* **EXECUTING** - the sync is running

{% hint style="warning" %}
*Non-empty <mark style="color:red;">`needsReview`</mark> indicated that a sync module is not completely activated and the user needs to review the data that the synced prepared for syncing.*
{% endhint %}

### Sync templates <a href="#h-sync-templates-5" id="h-sync-templates-5"></a>

***

Sync templates are team-level configurations that can be assigned to sync users and result in auto-populating services and settings. Using the templates also disables the “review” steps and allows user sync to activate completely right away.

The [/templateGroups](https://sync-docs.aurinko.io/#tag/TemplateGroups/operation/getTemplateGroups) endpoints all you to manage multiple sync templates and their assignments to users.

<mark style="color:red;">`GET https://api.yoxel.com/v2/templateGroups`</mark>

<mark style="color:red;">`POST https://api.yoxel.com/v2/templateGroups`</mark>\ <mark style="color:red;">`PUT https://api.yoxel.com/v2/templateGroups/{gid}`</mark>

#### **Template services**

<mark style="color:red;">`GET https://api.yoxel.com/v2/templateGroups/{gid}/services`</mark>

Refer to the [/groupTemplates API refs](https://sync-docs.aurinko.io/#tag/TemplateGroups/operation/getGroupTemplates) for more details. Here is an example of the key data returned:

```json
[
  {
    "id": 1,

    "groupId": {gid},    
    "type": "GOOGLE|OFFICE365|EXCHANGE|SFORCE|MYPLATFORM",
    "offline": true,
    "displayName": "My Google",
    "fullName": "John Smith",
    "email": "jsmith@abc.com",
    "server": "https://api.google.com",
    "syncData": {...},
    "scanEmail": true,
    "scanEmails": {...configuration options...},
    "fwdEmail": true,
    "fwdEmails": {...configuration options...},
    "importEvents": true,
    "calendar": {...configuration options...},
    "importContacts": true,
    "contacts": {...configuration options...},
    "importTasks": true,
    "tasks": {...configuration options...},
    "authRedirectUrl": "url if unauthorized",
    "lockService": true,
    "authError": "string"
  },
  ...
  
]
```

BrightSync supports admin/app-level connectivity for Google, Office 365, MS Exchange, and Salesforce accounts which can be configured at the template level.

{% hint style="warning" %}
*Non-null authRedirectUrl means the Org admin has not authorized BrightSync to access this Org yet or the access token has been lost. Direct the admin user to <mark style="color:red;">`authRedirectUrl`</mark> in a browser popup window to get a new authorization.*
{% endhint %}

#### **Creating a new template service**

<mark style="color:red;">`POST https://api.yoxel.com/v2/templateGroups/{gid}/services`</mark>

#### **Updating an existing template service**

<mark style="color:red;">`GET https://api.yoxel.com/v2/templateGroups/{gid}services/{id}`</mark>

#### **Template sync settings**

The [/templateGroups/{gid}/syncSettings](https://sync-docs.aurinko.io/#tag/TemplateGroups/operation/getSyncSettings_1) endpoints allow you to prepare a sync configuration between two services: one business platform (also called *portal*) and one mailbox (i.e. Google, Office 365,…) or an email marketing account (i.e. Hubspot, Constant Contact,…)

<mark style="color:red;">`GET https://api.yoxel.com/v2/templateGroups/{gid}/syncSettings`</mark>\ <mark style="color:red;">`PUT https://api.yoxel.com/v2/templateGroups/{gid}/syncSettings`</mark>

Here is an example of the key options you control (very similar to the user-level sync settings):

```json
{
    "templGroupId": {gid},    
    "logEmail": true,
    "emailSkipDomains": "string",
    "emailFetchAttachments": true,
    "emailCreateLeads": true,
    "emailCreateContacts": true,
    "emailAutoDetectDeal": true,
    "emailCreateCompany": true,
    ...
    
    "syncCalendar": true,
    "calSyncDirection": "BOTH|TO_PORTAL|FROM_PORTAL",
    "calSyncPrivate": true,
    "calFetchAttachments": true,
    "calMailboxSyncAll": true,
    "calMailboxSyncTags": "string",
    "calMailboxSyncMeetingsOnly": true,
    "calPastWeeks": 0,
    "calFutureWeeks": 0,
    ...
    
    "syncContacts": true,
    "contSyncDirection": "BOTH|TO_PORTAL|FROM_PORTAL",
    "contCreateCompany": true,
    "contPortalSyncAll": true,
    "contMailboxSyncAll": true,
    "contPortalSyncMine": true,
    "contPortalSyncTags": "string",
    "contMailboxSyncTags": "string",
    "contMailboxSyncDeleted": true,
    ...
    
    "syncTasks": true,
    "taskSyncDirection": "BOTH|TO_PORTAL|FROM_PORTAL",
    "taskMailboxSyncAll": true,
    "taskMailboxSyncTags": "string"
}
```

### User management <a href="#h-user-management" id="h-user-management"></a>

***

With an admin user’s access token, it is possible to manage other users’ syncs.

*Additional documentation detailing the* [*/users*](https://sync-docs.aurinko.io/#tag/Users/operation/listUsers) *endpoints i being developed*.


