Skip to main content
The Microsoft 365 Copilot integration is a self-hosted utility script that pulls Copilot Enterprise interactions from the Microsoft Graph API and ingests each prompt/response pair into Nebuly as an Interaction. The data flow is: Microsoft Graph (licensed users → interactions) → pair conversion → Nebuly ingestion The script is incremental and resumable: it tracks a local SQLite cache of already-synced coverage windows, so you can re-run it safely at any time without creating duplicates. The source repository is available here.

Prerequisites

  • A Microsoft 365 tenant with Copilot Enterprise licenses, and an admin who can grant tenant-wide API consent.
  • Python ≥ 3.12 and Poetry installed on the machine that runs the script.

Install & run

Clone the integration examples repository, install dependencies, configure your .env file, and run the sync:
Follow the guide below to retrieve the necessary credentials. For the complete environment variable reference, available CLI flags, payload customization and resumable-cache details, check the project README.

Get your credentials

The script requires four environment variables. Follow the steps below to obtain each one: NEBULY_API_KEY, AZURE_TENANT_ID, AZURE_CLIENT_ID, and AZURE_CLIENT_SECRET.
1

Nebuly secret key → NEBULY_API_KEY

In Nebuly, go to Settings → Projects → View Nebuly keys → Secret keys and copy the secret key for the project you want to sync.
2

Register an app in Microsoft Entra

  1. Open the Microsoft Entra admin center.
  2. Go to App registrations → New registration.
  3. Give the app a name.
  4. Under Supported account types, choose Single tenant only -
  5. Click Register.
3

Tenant & client IDs → AZURE_TENANT_ID / AZURE_CLIENT_ID

Go to App registrations → → Overview page, copy:
  • Directory (tenant) IDAZURE_TENANT_ID
  • Application (client) IDAZURE_CLIENT_ID
4

Client secret → AZURE_CLIENT_SECRET

  1. Go to App registrations → → Certificates & secrets → New client secret.
  2. Add a description and expiration, then click Add.
  3. Copy the secret Value immediately. Use the Value, not the Secret ID, for AZURE_CLIENT_SECRET.
Client secrets expire, so choose an expiration policy you can rotate before it lapses.
5

Grant API permissions

  1. Go to App registrations → → API permissions → Add a permission.
  2. Select Microsoft Graph → Application permissions.
  3. Add AiEnterpriseInteraction.Read.All and User.Read.All.
  4. Click Grant admin consent for .
The permissions are application permissions, not delegated permissions, because the script uses the client-credentials flow. Before running the sync, confirm each permission’s Status reads Granted for with green checks. If it does not, a Global Administrator must approve tenant-wide consent.

FAQ

Where does the synced data appear?
Conversations imported by the script show up on the Interactions page in your Nebuly project.
When will my data appear?
There can be a delay of up to 30 minutes between the moment data is available in Microsoft Graph and when it becomes visible in Nebuly. Subsequent updates follow the same polling interval.
Is it safe to re-run the script?
Yes. The script maintains a local SQLite cache at .cache/sync_state.db that tracks per-user coverage windows. Re-running it will pick up only new data and will not create duplicates.
How can I see what would be sent without triggering ingestion?
Pass the --dry-run flag. The script will fetch and convert data but will skip the POST to Nebuly’s ingestion endpoint, printing a summary instead.
Are token, cost, and conversation metrics included?
Microsoft Graph does not expose per-trace token or cost metrics, so those fields are not synced. Excel and PowerPoint turns may also not group properlyinto multi-turn conversations due to the way the data is structured.

Resources

Microsoft 365 Copilot Nebuly integration

Full install guide, env-var table, CLI flags, and customization docs

Export Microsoft Teams Copilot content

Microsoft’s official guide to exporting Copilot interaction data

Nebuly Interaction API

API reference for the Interaction ingestion endpoint