Learn how Dataverse activity tables really work — the Activity base table, Activity Party model, and Regarding polymorphic lookup — and build a fully configured Timeline control for your model-driven app, including custom activity types and security-aware visibility. This is the lesson that turns the Timeline from a mystery into a deliberate design choice.

You've built a clean Dataverse data model, configured your forms and views, and your model-driven app is taking shape. But there's a gap that almost every business application needs to fill: how do you capture the history of what happened with a record? A sales opportunity isn't just a set of field values — it's a series of conversations, scheduled calls, follow-up tasks, and sent proposals. A support case isn't closed the moment it's created; it's resolved through a chain of email exchanges and appointments. Without a structured way to track that activity history, your app is a database, not a business tool.
Dataverse has a purpose-built answer to this problem: the activity table architecture. Activities are a special category of Dataverse table — Email, Task, Appointment, Phone Call, and others — that are designed from the ground up to be associated with any other record in the system. They share a common base called the Activity Party model, they appear in a unified Timeline control on forms, and they can trigger Power Automate flows, Outlook sync, and Teams integration without any custom plumbing. When you understand how activities work at the structural level, you stop fighting the platform and start using it as intended.
By the end of this lesson you'll have a complete, working understanding of the activity architecture in Dataverse, how to enable activity tracking on your custom tables, how to configure the Timeline control on model-driven forms, and how to build a custom activity type when the out-of-the-box options aren't enough.
What you'll learn:
You should be comfortable with Dataverse table basics, including how tables, columns, and relationships work. If you need a refresher, Dataverse Fundamentals: Tables, Columns, and Rows Explained for Power Apps Makers is a solid starting point. You should also know how model-driven forms are structured — particularly tabs, sections, and subgrids, which are covered in Designing Model-Driven Forms: Sections, Tabs, Subgrids, and Quick View Forms. Some familiarity with security roles is helpful for the final section.
Before you touch any configuration, you need a clear mental model of what Dataverse activities actually are under the hood. This isn't just academic — if you misunderstand the structure, you'll make design decisions that are hard to undo.
Every activity type in Dataverse — Email, Task, Appointment, Phone Call, Letter, Fax, and any custom activity you create — is a child of a system table called Activity (schema name: activitypointer). This is a real table in your environment. You can query it directly. It holds the fields that are common to all activity types: subject, status, status reason, start/end times, and — critically — the Regarding lookup.
The Regarding column (regardingobjectid) is a polymorphic lookup that can point to any activity-enabled table in your system. When a sales rep logs a phone call against an opportunity, that phone call record's Regarding field stores a reference to the opportunity. When a support agent creates a task against a case, that task's Regarding field stores a reference to the case. The Timeline control you see on a form is essentially a filtered view of the Activity table scoped to the record you're currently looking at.
Key insight
The Timeline control doesn't use a traditional one-to-many relationship between your table and a specific activity table. It uses the polymorphic Regarding lookup on the Activity base table to find all activities associated with the current record — across all activity types simultaneously. This is why enabling "Activities" on a table is a single toggle, not a relationship you configure per activity type.
Many activities involve more than one person. An email has a sender, recipients, CC'd parties, and BCC'd parties. An appointment has an organizer, required attendees, and optional attendees. Dataverse handles this through the Activity Party table (activityparty), which is a many-to-many junction between an activity record and a party (typically a User, Contact, Account, Lead, or any other party-enabled table).
Each activity party record has a participation type that indicates the party's role: From, To, CC, BCC, Required Attendee, Optional Attendee, Organizer, and so on. When you send an email from within a model-driven app and the email appears on a contact's timeline, it's because a party record was created linking that email activity to that contact.
You rarely need to interact with the Activity Party table directly as a maker — but knowing it exists explains why activities can appear on multiple records' timelines simultaneously.
Here's a nuance that trips up many practitioners. A phone call might have:
That phone call will appear on the timeline of the Opportunity record (because of Regarding). It may also be visible from Marcus Rivera's Contact record if your org has configured party-based relationship filtering. The Regarding relationship is the primary association — what the activity is "about." Party associations are secondary.
Not every Dataverse table tracks activities by default. Standard tables like Account, Contact, Lead, Opportunity, and Case all have activities enabled out of the box. But if you've built a custom table — say, a Project table, a Service Request table, or a Supplier Contract table — you need to explicitly enable activity tracking.
To enable activities on a table, navigate to your solution in the Power Apps maker portal, open the table's properties, and look for the Advanced options section. You'll find a checkbox labeled Activities. Check it and save.
Warning
Enabling activities on a table is irreversible. Once you save the table with Activities enabled, you cannot disable it later. Dataverse creates the underlying infrastructure for the Regarding relationship as part of this operation. Make this decision deliberately — but for almost any table that represents a real-world entity your team interacts with (customer, project, asset, contract), enabling activities is the right call.
When activities are enabled, Dataverse does three things behind the scenes:
regardingobjectid lookup on the Activity base tableAfter enabling activities, you can verify the change by opening the Activity table's metadata and confirming your table is listed as an allowed target for regardingobjectid. In practice, you'll notice this immediately when you open the "Create a new Email" dialog — your table's records will appear in the Regarding lookup dropdown.
With activities enabled on your table, the next step is making the activity history visible on the form. The Timeline control is the component responsible for rendering this history — it's not a subgrid, it's a dedicated control with its own configuration surface.
Open the form editor for your table's main form. In the component panel on the left (or via Insert > Timeline if you're in the classic editor), drag the Timeline control onto the form canvas. The Timeline is typically placed in a one-column section on its own tab — most production apps have an Activity History or Timeline tab for exactly this purpose. This keeps the primary data fields on the Summary tab clean and gives the activity history the vertical space it needs.
Tip
If you're designing a new form from scratch and following the tab structure described in Designing Model-Driven Forms: Sections, Tabs, Subgrids, and Quick View Forms, create a dedicated "Timeline" tab with a single section spanning the full width. Set the section to have no label visible and no padding. The Timeline control will expand to fill this space, giving you a clean, uncluttered activity log.
Selecting the Timeline control in the form editor opens a properties panel with several configuration options. Let's walk through each one meaningfully.
Record Types to Show
This multi-select setting controls which activity types appear in the Timeline. By default all activity types are shown: Email, Task, Appointment, Phone Call, Letter, Fax, and any custom activities you've registered. For most business applications, you'll want to restrict this to the types that are actually relevant.
For a Project management table, for example, you might show only Tasks, Appointments, and a custom "Status Update" activity. Emails might belong on the related Contact or Account timeline rather than the project itself. Cluttering the project timeline with emails that were Regarding the project incidentally makes the timeline harder to scan.
Notes
The Timeline can also display notes (annotations). Notes are slightly different from activities — they're records in the annotation table and don't appear in the Activity base table. But they show up in the Timeline as if they were activities, giving users a way to attach plain text or file attachments to a record without creating a formal activity. Toggle this on unless you have a specific reason to hide notes.
Wall Posts
Wall posts are a social collaboration feature — users can post plain-text messages to a record's timeline without creating a structured activity. These are stored in the post table. In most business applications, wall posts are either genuinely useful (as a lightweight internal comment mechanism) or create noise alongside proper activities. Decide deliberately. If your team has a discipline around logging activities properly, posts can create a parallel informal channel that undermines that discipline.
Sort Order
You can configure whether the Timeline displays activities in ascending or descending chronological order. Descending (newest first) is the default and is correct for most use cases — users want to see the most recent interaction immediately.
Number of records
This controls how many activity records the Timeline loads initially. The default is typically 10. For high-volume records like cases that accumulate dozens of interactions, you may want to increase this or rely on the "Load more" functionality the control provides. Be aware that loading large numbers of records affects form load performance.
Note
The Timeline control uses a separate data fetch from the main form record — it loads activity data asynchronously after the record itself loads. This is intentional and means a slow activity timeline doesn't block the user from seeing the primary record fields. However, if users are reporting that timelines feel slow, look at the number of records configured and consider whether you can filter more aggressively by record type.
Once the Timeline is on the form and the form is published, users will see a command bar above the timeline that lets them create new activities. Let's look at how this works in practice so you can configure it correctly.
When a user clicks the + button in the Timeline toolbar, they see a menu of available activity types. Selecting one opens a Quick Create form for that activity type. Quick Create forms are a separate form class from Main forms — they're the compact side panel that opens without navigating away from the current record.
The activity being created automatically inherits the Regarding field from the record the user is currently viewing. This is the magic of the timeline — the user doesn't need to manually set "this task is regarding this project." It happens automatically.
Tip
If you want to restrict which activity types users can create from the Timeline (as opposed to which ones are displayed), you need to do this through security role configuration, not the Timeline properties panel. The activity types that appear in the + menu are determined by what the user has Create privileges for. This gives you fine-grained control: a standard user role might have Create on Task and Appointment but not Email, for example.
You can customize the Quick Create forms for each activity type to pre-populate default values, set field visibility, or enforce required fields. Navigate to the activity table (e.g., Task) in your solution, open its forms, and find the Quick Create form. Add the fields you want visible and apply any business rules in Dataverse to enforce field requirements or set defaults based on context.
A common configuration for the Task Quick Create form in a project management app: show Subject (required), Due Date (required), Priority, and a custom "Category" choice column. Hide the Regarding field entirely — it's already populated by the Timeline context and showing it just clutters the form.
Sometimes the standard activity types don't fit your business process. A field service company might need to track "Site Visit" activities. A financial services firm might need "Compliance Review" activities that have specific required fields and a different lifecycle than generic tasks. Dataverse lets you create custom activity tables.
In the Power Apps maker portal, create a new table and — before saving — open the Advanced options section. You'll see a Table type dropdown. Change this from "Standard" to Activity. This single setting transforms the table into an activity type that participates in the full activity infrastructure: it gets the standard activity columns (subject, status, regarding, etc.), it appears in the Timeline control, and it can be used with activity-related Power Automate triggers.
Let's use a concrete example. Say you're building an app for a wealth management firm. You need to track "Investment Review" activities against Client records. An Investment Review has:
Your table configuration:
After creating the table with type Activity, you'll notice it automatically has a set of columns inherited from the Activity base: Activity ID, Subject, Status, Status Reason, Scheduled Start, Scheduled End, Actual Start, Actual End, Duration, Priority, Regarding, and Owner. Add your custom columns on top of these inherited columns.
Warning
Custom activity tables have some limitations compared to standard tables. They cannot have their own relationships configured as "Regarding" targets — meaning you can't make a custom activity the target of another custom activity's Regarding lookup. They also have a fixed form pattern for the Quick Create form. Plan your custom activity schema carefully before building forms around it.
A custom activity's Main form works identically to any other table's Main form. Build it using the standard form editor, add your custom columns in appropriate sections, and consider adding a Timeline control to the form itself — yes, you can track notes and other activities against a custom activity record if the business logic warrants it (for an Investment Review, you might want to attach follow-up task records directly to the review).
The form for your Investment Review table might look like:
Header: Subject (read-only — typically set by user on create), Owner, Status Tab 1 - Review Details:
Tab 2 - Notes:
Tab 3 - Timeline (if you want activity notes separate from the review details timeline):
Custom activity tables automatically appear in the Timeline of any activity-enabled table once they're created as an Activity table type. When a user navigates to a Client record and opens the Timeline tab, Investment Review activities will appear alongside Tasks and Appointments — as long as the user has Read privileges on the wsd_investmentreview table.
To control the display, go back to the Timeline control properties on the Client table's Main form, and in the Record Types to Show list, verify your Investment Review is included (it should be by default). You can selectively hide it if it's not relevant.
The basic configuration gets the Timeline working. These additional settings make it production-ready.
If your organization uses Outlook and has Server-Side Synchronization configured, emails sent and received by users will automatically sync back to Dataverse as Email activity records. These emails will appear on the Timeline of any record in their Regarding field — automatically, without the user manually logging anything.
The Timeline respects these synced emails exactly like manually created ones. From a maker perspective, no special configuration is needed for this to work — but you should verify with your system administrator that Server-Side Sync is enabled and that mailbox records are approved for the users who will be working with your app. If users are complaining that emails don't appear on timelines, this is almost always a Server-Side Sync configuration issue, not a form configuration issue.
The Timeline control's built-in filter (the funnel icon users see at runtime) lets users filter by activity type, date range, and activity status. But you can pre-configure the default filter state in the Timeline properties.
For most record types, showing Open activities prominently and historical Completed activities de-emphasized is the right approach. Some apps configure two Timeline controls side by side: one filtered to open activities (titled "Upcoming & Open") and one filtered to completed activities (titled "History"). This is a pattern from Dynamics 365 Sales that works well for high-velocity records.
To achieve this, add two Timeline controls to the form in separate sections and configure each with a different status filter. This is one of those cases where form design skill (covered in Designing Model-Driven Forms: Sections, Tabs, Subgrids, and Quick View Forms) directly impacts how useful the activity history becomes.
When users create activities from outside the Timeline (e.g., from an Activities view, or by navigating directly to the Task table), they need to manually set the Regarding field. The Regarding lookup searches across all activity-enabled tables. If your environment has dozens of activity-enabled tables, the search results can be noisy.
You can improve this by configuring the Quick Find view on each activity-enabled table to include the most useful identifying columns. When a user types in the Regarding field, Dataverse runs a Quick Find query against each eligible table. Making sure those Quick Find views return meaningful search results (project name, account number, case reference) makes the Regarding field much more usable in practice.
Activities participate in the same security model as all other Dataverse tables. But there are some nuances worth understanding.
Each activity type has its own row in the security role privilege grid. A user needs:
The Append / Append To pair is the one that trips people up. If a user can create tasks but keeps seeing an error when they try to save a task with a Regarding value pointing to a Project, check their Append privilege on Task and their Append To privilege on Project. Both are required.
For a thorough walkthrough of how privilege levels work, Configuring Dataverse Table Permissions in Model-Driven Apps covers this pattern in detail.
Key insight
The Activity base table (activitypointer) has its own privilege row in security roles. This controls access to the unified activity view and certain cross-activity operations. In most configurations, users need at least User-level Read on activitypointer to see the Timeline control render correctly. If a user has Read on Task and Appointment but not on activitypointer, the Timeline may appear blank or return errors.
Suppose your Investment Review custom activity contains sensitive financial data. You want all advisors to see Investment Reviews on the Client timeline, but support staff should only see Tasks and Appointments — not Investment Reviews. Implement this through the security role: grant advisors Read access to wsd_investmentreview at the appropriate organizational level, and do not grant this privilege to support staff roles. The Timeline control respects these privileges — users without Read access to an activity type simply won't see those records in the Timeline, even if the Timeline control is configured to show that type.
This is a clean, low-maintenance approach to activity-level data access. You don't need separate forms or configurations — the security model handles the filtering transparently. For more on building layered security configurations, Dataverse Security: Business Units, Security Roles, and Teams is worth reading alongside this lesson.
One pattern worth knowing: sometimes you want to see activities that aren't directly Regarding a record, but are Regarding a related record. For example, you might want to see all emails that were sent about any Contact that belongs to an Account — not just emails that were directly about the Account.
The Timeline control doesn't support this natively — it only shows activities where the Regarding field points directly to the current record. There are two approaches for handling this:
Option 1: Use a rollup column to count or summarize activity-related data. If you add a rollup column to your Account table that counts the number of open tasks across related Contacts, you get a summary without needing to see the individual activities on the Account timeline. Configuring Dataverse Calculated Columns and Multi-Table Rollup Columns in Model-Driven Apps covers exactly this technique.
Option 2: Use a subgrid configured to show a related table's activities. Add a subgrid to the Account form that targets the Activity table and filters by a relationship (e.g., show tasks where the task's related contact is a contact of this account). This requires a more complex view filter but gives users the full activity details.
For most use cases, Option 1 (rollup summary on the parent) combined with Option 2 (subgrid drill-down for detail) gives you the best of both worlds.
Let's put this all together. You'll build a complete custom activity setup from scratch.
Scenario: You're building a model-driven app for wealth management advisors. Advisors manage Client records and need to track formal Investment Reviews against each client.
If you have an existing Client table without activities enabled, open it in your solution, go to Properties, expand Advanced options, and check Activities. Save and publish the table.
If you're creating the Client table fresh: during table creation, in Advanced options, check Activities before saving.
Create a new table in your solution:
Save the table. Then add these columns:
wsd_reviewdate: Date and Time, Requiredwsd_portfoliovalueatreview: Currencywsd_recommendedaction: Choice (values: Rebalance, Hold, Increase Allocation, Reduce Allocation)wsd_advisornotes: Multiple Lines of Textwsd_followuprequired: Yes/No (default: No)Open the Investment Review table's forms. Edit the Main form:
Header row: Subject (required), Owner, Status, Status Reason
Tab: Review Details (2 columns):
Set a business rule on this form: if Follow-up Required = Yes, make Advisor Notes required (so the advisor must document what the follow-up is about).
Tab: Timeline: Add a Timeline control in a single full-width section. This allows notes to be attached to the Investment Review itself.
Save and publish the form.
Find the Quick Create form for the Investment Review table. Configure it to show:
Hide the Regarding field on this form (it's auto-populated from the Client record context).
Save and publish.
Open the Client table's Main form. Add a new tab labeled Activity History. Inside it, create a single full-width section (no label). Drop the Timeline control into this section.
In the Timeline control properties:
Save and publish the form.
In your solution, edit the security role(s) for advisors:
For support staff roles, grant only Read (None) on Investment Review — meaning they see no Investment Reviews in the timeline.
Navigate to a Client record in your model-driven app. Open the Activity History tab. Click the + button in the Timeline and confirm "Investment Review" appears in the list. Select it — the Quick Create form should open with Subject and Review Date ready to fill in. The Regarding field should already be set to the current Client. Save the review. It should appear immediately in the Timeline.
Open the Investment Review record directly (from the Timeline, click the subject link). Verify the Main form renders all fields and the nested Timeline is present.
"Activities" option is greyed out on the table settings panel
This usually means you're looking at the properties of a system table that Microsoft controls, or you're in a managed layer where the table is locked. If it's your own custom table, make sure you're editing the unmanaged customization layer in your own solution. Import the table into an unmanaged solution in your dev environment and make the change there.
Custom activity doesn't appear in the Timeline's + menu
Two likely causes: (1) the Timeline control's Record Types to Show list doesn't include your custom activity — edit the form and check the Timeline properties; (2) the current user doesn't have Create privilege on your custom activity table. Check the security role.
Timeline is blank even though activity records exist
Check the activitypointer Read privilege on the user's security role. Without at least User-level Read on the base activity table, the Timeline control fails silently. Also confirm the Regarding field on the activity records actually points to the record you're viewing — if someone created activities without setting Regarding correctly, they won't appear.
The Regarding lookup in an activity form doesn't show my custom table as an option
Activities on the table are not enabled. Go back to the table properties and enable Activities. Remember this is a one-way operation.
Duplicate activities appearing after enabling Server-Side Sync
If email sync is configured and users are also manually logging emails, you'll get duplicates. Establish a clear process: either use Server-Side Sync exclusively (no manual logging), or use manual logging only and don't sync. The platform supports both, but mixing them creates data quality issues.
Warning
If you're migrating activity data from another system using dataflows or API imports, be aware that importing into the activitypointer table directly isn't supported. You must import into each specific activity type table (Task, PhoneCall, etc.) and set the Regarding field using the correct entity reference format. The Importing and Migrating Data into Dataverse article covers the import mechanics, but activity imports require extra attention to the polymorphic Regarding field.
Custom activity not available in Power Automate triggers
Custom activity tables with type "Activity" should be available in Dataverse triggers in Power Automate (e.g., "When a row is added, modified or deleted"). If your custom activity table doesn't appear, confirm it was saved with Table type = Activity (not Standard). If you created it as Standard and tried to change it later, this isn't possible — you'd need to recreate the table.
Activities are one of Dataverse's most powerful and most underused features. The architecture — a common Activity base table with typed child tables, polymorphic Regarding relationships, and the Activity Party model — gives you a lot for free: unified history across activity types, automatic Outlook sync, Timeline rendering, and a consistent security model. Your job as a maker is mostly configuration: enabling activities on the right tables, picking up the Timeline control and pointing it at the right activity types, and optionally extending the system with custom activity tables when the standard types don't fit.
The key design decisions to revisit as you apply this to your own apps:
From here, natural next topics are building Power Automate flows that trigger on activity creation to automate follow-ups, configuring auditing on activity tables to meet compliance requirements, and exploring how dashboards can surface activity metrics — like overdue tasks or activities by type — across your dataset.