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:
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
- Open the Microsoft Entra admin center.
- Go to App registrations → New registration.
- Give the app a name.
- Under Supported account types, choose Single tenant only -
- Click Register.
3
Tenant & client IDs → AZURE_TENANT_ID / AZURE_CLIENT_ID
Go to App registrations → → Overview page, copy:
- Directory (tenant) ID →
AZURE_TENANT_ID - Application (client) ID →
AZURE_CLIENT_ID
4
Client secret → AZURE_CLIENT_SECRET
- Go to App registrations → → Certificates & secrets → New client secret.
- Add a description and expiration, then click Add.
- Copy the secret Value immediately. Use the Value, not the Secret ID, for
AZURE_CLIENT_SECRET.
5
Grant API permissions
- Go to App registrations → → API permissions → Add a permission.
- Select Microsoft Graph → Application permissions.
- Add
AiEnterpriseInteraction.Read.AllandUser.Read.All. - Click Grant admin consent for .
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