In this video, I show how to work with the AL Table Proxy Generator to create custom integration to Microsoft Dynamics 365 CRM/CE/For sales

The AL Table Proxy Generator (altpgen.exe) is the successor to the New-NavCrmTable command.
In this video, Erik demonstrates how to build a custom Dynamics 365 CRM integration in Business Central using the low-level technical connection layer. Rather than relying on the out-of-the-box assisted setup and standard integration mappings, he shows how to generate proxy tables using the AL Table Proxy Generator tool, read and write CRM data directly from AL code, and extend existing CRM table mappings with custom fields.
Understanding the Integration Layers
The integration between Business Central and Dynamics 365 CRM (also known as Dynamics 365 Customer Engagement for Sales, or Dataverse) is built in two layers:
- Technical layer — The low-level connection that enables Business Central to communicate with CRM.
- Microsoft’s built-in integration — Built on top of the technical layer, this handles data synchronization back and forth using table mappings, integration table mappings, and job queue entries.
In this video, Erik works exclusively with the technical layer. He connects Business Central to CRM by simply entering the CRM URL on the CDS Connection Setup page and enabling it — without running the assisted setup that generates synchronization jobs and mappings on both ends.
How CRM Proxy Tables Work
When you look at a CRM table in Business Central (such as “CDS Contacts”), it appears to be a normal table. You can open the page inspector and see it’s backed by a table object called CRM Contact. If you examine the source code in the base app, you’ll see it’s defined as a standard table object — but with one key difference: the table type is set to CRM (or CDS).
From an AL perspective, this is just a table. You can call FindSet, Insert, SetRange, and all the usual operations. However, the data is not stored in the SQL database — it lives in CRM. The table object acts as a proxy, translating AL operations into CRM API calls.
Each field in a CRM proxy table has additional properties beyond what a normal Business Central field requires:
- ExternalName — The actual field name in CRM
- ExternalType — The field type in CRM (e.g., a
Picklistin CRM becomes anOptionfield in AL)
The AL Table Proxy Generator
While you could manually write these proxy tables, doing so would be extremely tedious. Microsoft provides a tool called the AL Table Proxy Generator (altpgen.exe) that ships with the AL Language extension for VS Code.
You can find it in the extension’s installation directory:
C:\Users\{username}\.vscode\extensions\ms-dynamics-smb.al-{version}\bin\
In that bin folder, you’ll find several executables:
alc.exe— The AL compilerwebdeploy.exe— Used by the compiler for app deploymentMicrosoft.Dynamics.Nav.EditorServices.Host.exe— The editor service that powers IntelliSense and validationaltpgen.exe— The AL Table Proxy Generator
Generating a New Proxy Table
To generate a proxy table, you run altpgen from the command line with several parameters:
altpgen /project:. /serviceuri:https://yourorg.crm.dynamics.com /entities:contact /tabletype:CDS
The parameters are:
- /project — Path to your app.json file (use
.if you’re already in the project folder) - /serviceuri — The URL of your CRM instance
- /entities — Comma-separated list of CRM entities to generate
- /tabletype — Either
CRMorCDS
The tool will authenticate, read the metadata for the specified entities, and generate AL table objects. It will also produce warnings — but those are expected and will be addressed later.
Custom Fields Are Included
One of the great things about the proxy generator is that it picks up custom fields. Erik added a custom new_youtube field to the Contact entity in CRM before recording, and the generated table included that field automatically.
Creating a Page to View CRM Data
Once the proxy table is generated, you can create a standard list page to display the data. However, there’s one critical requirement: you must explicitly establish the CRM connection in the page’s OnInit trigger:
trigger OnInit()
begin
Codeunit.Run(Codeunit::"CRM Integration Management");
end;
This tells the Business Central server to connect the current session to CRM. This is different from the old NAV days where the connection was automatic — in Business Central, it’s on-demand.
With the connection established, the page displays live CRM data. You can even edit fields directly — changes are written back to CRM in real time. Erik demonstrated this by editing a contact’s YouTube field and first name, then confirming the changes appeared in CRM.
Table Extensions for Existing Entities
The base app already includes proxy tables for common CRM entities like Contact (with table type CRM). If you run the proxy generator for an entity that’s already mapped in the base app, something clever happens: instead of generating a full table, it generates a table extension.
altpgen /project:. /serviceuri:https://yourorg.crm.dynamics.com /entities:contact /tabletype:CRM
The generator recognizes that the Contact entity is already mapped in the base app and creates a table extension containing only the new/custom fields — in this case, the new_youtube field.
This approach has a significant advantage: you can add custom fields to the standard integration mappings. You don’t need to build a completely custom integration just because you added a field to an entity. You simply extend the existing proxy table and add your field to the standard synchronization setup.
Handling Entity Relationships and Warnings
The warnings generated by the proxy tool are mostly about missing related entities. For example, the Contact entity has an account_id field that references the Account entity. If Account isn’t included in your generation, you’ll see:
No table found for entity 'account'. Unable to create table relation for contact.account_id.
The solution is to include all related entities in a single call to the proxy generator:
altpgen /project:. /serviceuri:https://yourorg.crm.dynamics.com /entities:contact,account /tabletype:CDS
When entities are generated together, the tool creates proper table relations between them. For instance, the Contact table will have a TableRelation on the account_id field pointing to CDS Account."Account Id", and it will also generate a FlowField for the account name lookup — just like you’d expect in a normal Business Central table.
As you discover more dependencies, you’ll need to keep adding entities. You might need systemuser, businessunit, pricelevel, and so on. Erik recommends creating a script file that contains the full command with all required entities, so you can always regenerate everything consistently:
altpgen /project:. /serviceuri:https://yourorg.crm.dynamics.com /entities:contact,account,systemuser,businessunit,pricelevel /tabletype:CDS
Building Real Integrations with Pure AL Code
Erik emphasizes that his team has built multiple complex custom integrations using this approach — and it’s all just AL code. There are no Azure Functions, no external middleware, and no third-party tools. The entire integration runs in AL, typically triggered by job queue entries or standard Business Central events.
The process is straightforward:
- Connect — Set up the low-level CDS/CRM connection from Business Central
- Generate — Use the AL Table Proxy Generator to create proxy tables for the entities you need
- Code — Write standard AL code to read, write, and synchronize data using those proxy tables
Summary
The custom CRM integration approach in Business Central leverages the technical connection layer to treat CRM entities as if they were native Business Central tables. The AL Table Proxy Generator tool (altpgen.exe) automates the creation of proxy tables and table extensions, including support for custom fields added to CRM entities. By generating all related entities together, you get proper table relations and lookups. The result is a powerful integration capability that requires nothing more than standard AL code — no external services, no middleware — just Business Central talking directly to CRM through proxy tables.