AL Event Subscribers in Business Central: Complete Guide
Event subscribers are one of the most important extensibility patterns in Microsoft Dynamics 365 Business Central. They let you react to application events without modifying the original Microsoft or partner code. In this practical guide, you will learn how EventSubscriber works, how to subscribe to table and integration events, how to debug subscribers, and how to design maintainable event-driven AL solutions.
What is an event in Business Central?
An event represents something that happens in the application. A publisher exposes an event, and a subscriber listens for that event and runs custom logic when the event is raised. Business Central supports business, integration, internal, global and trigger events. Events help separate custom functionality from application business logic and can reduce the need to modify standard application code. Microsoft Learn: Events in AL
What is an Event Subscriber?
An event subscriber is an AL method that subscribes to a specific published event. The subscriber method is normally placed inside a codeunit and decorated with the EventSubscriber attribute. The runtime calls the subscriber when the corresponding event is raised.
Microsoft documents the attribute with six arguments:
ObjectType— the type of object that publishes the event.ObjectId— the object that contains the event.EventName— the event publisher or trigger event name.ElementName— the field name for applicable database trigger events.SkipOnMissingLicense— controls behavior when the required license is missing.SkipOnMissingPermission— controls behavior when required permission is missing.
See the current EventSubscriber attribute reference for the complete syntax.
Basic EventSubscriber syntax
[EventSubscriber(ObjectType::Table, Database::Customer,
'OnAfterInsertEvent', '', false, false)]
local procedure AfterCustomerInsert(var Rec: Record Customer; RunTrigger: Boolean)
begin
// Custom logic runs after a Customer record is inserted.
end;
This subscriber listens to the Customer table's OnAfterInsertEvent. The table trigger event is raised by the Business Central runtime after a record is inserted. For this event, the subscriber receives the record and the RunTrigger Boolean parameter. Microsoft Learn: OnAfterInsertEvent
Why use event subscribers?
- Extend standard Business Central behavior without changing base application code.
- Keep custom logic separate from Microsoft application logic.
- React to business or technical events such as inserts, validation and posting.
- Build integrations and notifications around existing application behavior.
- Make extensions easier to upgrade and maintain.
Events are especially useful when the requirement is to add behavior around an existing process rather than replace the entire process.
Table trigger events
Table trigger events are predefined runtime events. Common examples include:
OnBeforeInsertEventOnAfterInsertEventOnBeforeModifyEventOnAfterModifyEventOnBeforeDeleteEventOnAfterDeleteEventOnBeforeValidateEventOnAfterValidateEvent
Example: run logic after a Customer is inserted
codeunit 50120 "Dynexal Customer Events"
{
[EventSubscriber(ObjectType::Table, Database::Customer,
'OnAfterInsertEvent', '', false, false)]
local procedure CustomerAfterInsert(var Rec: Record Customer; RunTrigger: Boolean)
begin
Message('Customer %1 was created.', Rec."No.");
end;
}
This is useful for learning the pattern, but production code should avoid unnecessary user messages inside automatic business processes.
Example: subscribe to a field validation event
You can subscribe to a specific field's validation event by providing the field name as the fourth argument.
codeunit 50121 "Dynexal Validation Events"
{
[EventSubscriber(ObjectType::Table, Database::Customer,
'OnAfterValidateEvent', 'Name', false, false)]
local procedure CustomerNameValidated(var Rec: Record Customer; var xRec: Record Customer; CurrFieldNo: Integer)
begin
// Add custom validation-related logic here.
end;
}
The exact subscriber signature depends on the event being subscribed to. The safest approach in VS Code is to use IntelliSense or the event picker to insert the correct signature for your Business Central version.
Integration events
Integration events are published by application code using the IntegrationEvent attribute. They are useful when you own the publisher code and want other parts of the solution to react to a business or technical point without tightly coupling the publisher to subscribers.
codeunit 50122 "Dynexal Order Publisher"
{
[IntegrationEvent(false, false)]
procedure OnOrderProcessed(OrderNo: Code[20])
begin
end;
procedure ProcessOrder(OrderNo: Code[20])
begin
// Main processing logic.
OnOrderProcessed(OrderNo);
end;
}
A subscriber can then listen to the publisher:
codeunit 50123 "Dynexal Order Subscriber"
{
[EventSubscriber(ObjectType::Codeunit,
Codeunit::"Dynexal Order Publisher",
'OnOrderProcessed', '', false, false)]
local procedure HandleOrderProcessed(OrderNo: Code[20])
begin
// React to the event.
end;
}
Microsoft recommends passing the information subscribers need as event parameters rather than relying on global variable access. IntegrationEvent attribute reference
Business events vs integration events
Both are event publisher patterns, but they serve different purposes. Business events communicate meaningful business occurrences, while integration events are commonly used as extensibility points within application logic. The choice should reflect what the event represents and who needs to consume it.
For extensibility guidance and event quality considerations, see Microsoft's types of events for extensibility.
Multiple subscribers
More than one subscriber can listen to the same event. When an event is raised, subscriber methods are run one at a time, but you should not design your solution assuming a particular subscriber execution order. Microsoft explicitly notes that subscriber order cannot be specified.
How to find events in VS Code
You do not need to memorize every event name. The AL development environment provides tools for discovering events.
- Open your AL project in Visual Studio Code.
- Place the cursor inside a codeunit.
- Use the event discovery tools or IntelliSense to find the required event.
- You can also use
Shift + Alt + Eto open the event list in the AL editor. - Select an event to generate the subscriber pattern and then adjust the method name and logic.
Microsoft also documents the AL Explorer as a way to discover events and other extension points. AL Explorer
EventSubscriberInstance
The EventSubscriberInstance property controls how subscriber functions in a codeunit are bound to the events they subscribe to. StaticAutomatic is the default, while Manual can be used when subscriptions are bound through BINDSUBSCRIPTION.
codeunit 50124 "Dynexal Manual Subscriber"
{
EventSubscriberInstance = Manual;
[EventSubscriber(ObjectType::Codeunit,
Codeunit::"Dynexal Order Publisher",
'OnOrderProcessed', '', false, false)]
local procedure HandleOrderProcessed(OrderNo: Code[20])
begin
// Subscriber logic.
end;
}
For most beginner and standard extension scenarios, the default automatic behavior is sufficient. EventSubscriberInstance reference
Debugging Event Subscribers
When a subscriber does not appear to run, check the following:
- Confirm that the subscriber codeunit compiles and is published.
- Verify the object type, object name/ID and event name.
- Check the field name for validation events.
- Compare the subscriber parameter list with the selected event signature.
- Set a breakpoint inside the subscriber method.
- Perform the action that should raise the event.
- Check whether an error occurs before the event is reached.
- For permission/license-related behavior, review the last two EventSubscriber arguments.
Common EventSubscriber mistakes
- Putting
EventSubscriberon a method outside a codeunit. - Using the wrong object type or object name.
- Using
Table::Customerinstead of the documentedDatabase::Customerform for a table trigger event. - Forgetting the field name for a field-specific validation event.
- Using the wrong method parameters for the selected event.
- Assuming subscribers execute in a guaranteed order.
- Putting heavy processing into very frequently raised events without considering performance.
- Using events to work around a requirement that would be clearer as explicit application logic.
Best practices for event-driven AL
- Use events to extend behavior without modifying standard application code.
- Give subscriber procedures descriptive names such as
CustomerAfterInsertorSalesLineAfterValidate. - Keep subscribers small and delegate larger business processes to dedicated codeunits.
- Pass required data through event parameters instead of depending on global state.
- Avoid expensive processing in events that fire very frequently.
- Do not depend on an execution order among multiple subscribers.
- Use breakpoints and event discovery tools while developing and troubleshooting.
- Document important custom events and why they exist.
Real-world example: customer integration
Imagine an extension that needs to send selected customer information to an external application after a customer is created. A clean architecture can separate the responsibilities:
Customer table event
↓
Event Subscriber codeunit
↓
Customer Integration codeunit
↓
HTTPClient / API logic
↓
External application
The subscriber should detect the event and delegate the integration work. The API and authentication logic should remain in a dedicated integration layer. This makes the solution easier to test, reuse and change later.
Event Subscriber vs Page Extension trigger
A page extension is useful when the requirement is specifically about a page's user interface. An event subscriber is often better when the behavior should react to application activity regardless of which page or process caused it.
For example, if custom logic must run whenever a customer record is inserted from different processes, a table event is usually more appropriate than putting the logic only in the Customer Card page.
Quick checklist
- Do I have the correct event?
- Is the subscriber inside a codeunit?
- Did I use the correct EventSubscriber arguments?
- Does the method signature match the event?
- Can the logic be delegated to another codeunit?
- Could this event fire very frequently?
- Am I relying on subscriber execution order?
- Have I tested the subscriber with a breakpoint?
Frequently Asked Questions
Can EventSubscriber be used outside a codeunit?
No. The EventSubscriber attribute is applied to methods inside codeunits.
Can multiple subscribers listen to one event?
Yes. Multiple subscriber methods can subscribe to the same event, and their execution order should not be assumed.
What is the difference between a publisher and a subscriber?
The publisher exposes or raises the event. The subscriber listens for that event and contains the custom response logic.
Should I use events for everything?
No. Events are an extensibility mechanism. Use them when decoupling or reacting to application behavior provides a clear benefit. Direct, explicit business logic can be simpler when there is no extensibility requirement.
How do I find the correct EventSubscriber syntax?
Use the AL event discovery tools, IntelliSense or the event picker in Visual Studio Code. These tools help generate the correct event name and method signature for your environment.
What should you learn next?
Codeunits in Business Central — learn where reusable business logic and subscriber methods live.
Business Central API Integration — connect Business Central with external systems.
Shopify and Business Central Integration — explore a real-world e-commerce integration architecture.
Page Extensions in Business Central — extend standard pages with fields, actions and layout changes.
AL Tables in Business Central — understand the data model behind your AL solutions.