Dynamics 365 CRM Python Client

raw JSON →
1.0.2 verified Fri May 01 auth: no python

An API wrapper for Microsoft Dynamics 365 CRM that provides Python bindings for CRM operations. Current version 1.0.2 supports Python 3.7-3.11. The library is stable with no recent updates; it wraps OData REST endpoints for entity CRUD and batch operations.

pip install dynamics365crm-python
error ImportError: cannot import name 'Dynamics365Client' from 'dynamics365crm'
cause Incorrect import path; the library uses a flat structure, not submodules.
fix
Use 'from dynamics365crm import Dynamics365Client'
error AttributeError: 'str' object has no attribute 'id'
cause The create method in batch mode returns a string ID, not an object. Using .id on a string fails.
fix
If using batch, access the ID directly (the return value is the ID string). For single entity creation, use the non-batch method which returns an Entity object with .id.
error requests.exceptions.HTTPError: 401 Client Error: Unauthorized
cause Authentication failure due to wrong tenant, client id, or secret. Often environment variables are missing or expired.
fix
Double-check CLIENT_ID, CLIENT_SECRET, TENANT_ID. Ensure the app registration has CRM permissions (Dynamics CRM user_impersonation) and grant admin consent.
breaking In version 1.0.0, the constructor changed from positional arguments to keyword-only arguments for client_id, client_secret, etc. Older code using positional args will break.
fix Update calls to use keyword arguments: Dynamics365Client(client_id='...', client_secret='...')
deprecated The 'create', 'update', 'delete' methods still expect entity data as a list of dictionaries for batch operations, but the non-batch methods are preferred. Batch methods may be removed in a future release.
fix Use single entity methods for single operations: client.create(entity_name, data)
gotcha The resource_url must not include a trailing slash. Many users include '/api/data/v9.1/' which is default, but mistakenly add a slash at the end, causing 404 errors.
fix Ensure resource_url ends without a slash, e.g., 'https://org.crm.dynamics.com/api/data/v9.1'

Initialize client with Azure AD auth and create a new contact entity.

from dynamics365crm import Dynamics365Client
import os

client = Dynamics365Client(
    client_id=os.environ.get('CLIENT_ID', ''),
    client_secret=os.environ.get('CLIENT_SECRET', ''),
    tenant_id=os.environ.get('TENANT_ID', ''),
    resource_url=os.environ.get('CRM_URL', '')
)
# Create a contact
contact = client.create('contacts', {'fullname': 'John Doe', 'emailaddress1': 'john@example.com'})
print('Created contact:', contact.id)