Forum Discussion
Best practices for ingesting Marketo data into Microsoft Fabric using REST API / Bulk API
Hi Fabric Community,
We are building a data platform in Microsoft Fabric to ingest and store Marketo data in a Fabric Lakehouse.
For Salesforce, we can use the standard connector available in Microsoft Fabric. However, as far as we understand, there is currently no equivalent standard connector for Marketo.
Therefore, we are considering using the Marketo REST API / Bulk API to ingest Marketo data into Fabric.
We would appreciate any guidance on recommended implementation patterns or best practices for the following two scenarios.
1. Ingesting Marketo data using the REST API
We are considering ingesting Marketo data, such as Person data, into Microsoft Fabric. If possible, we would prefer a low-code / no-code implementation.
We are currently considering the following options:
- Calling the Marketo REST API from Dataflow Gen2
- Calling the Marketo REST API from a Fabric Data Pipeline
- Calling the Marketo REST API from a Fabric Notebook
For periodically retrieving Marketo data and storing it in a Fabric Lakehouse, which of these approaches would generally be recommended or considered a best practice?
We would prefer to use Dataflow Gen2 or another low-code approach if possible. However, considering requirements such as Marketo API authentication, pagination, and API rate limits, are there cases where a Notebook-based implementation would be more appropriate or necessary?
We also plan to use Marketo Activity Log data together with Salesforce Lead / Contact data.
In this scenario, are there any recommended approaches regarding which keys or fields should be retained from Marketo and how Marketo Person / Activity data should be linked with Salesforce Lead / Contact data in Fabric?
2. Ingesting large volumes of Activity Log data using the Marketo Bulk API
For high-volume data such as the Marketo Activity Log, we are considering using the Marketo Bulk Extract API.
As we understand it, the Bulk API exports data as files such as CSV. When ingesting this data into Fabric, we are considering two approaches:
Option A
Store the CSV files as-is in the Files area of the Lakehouse.
Option B
Transform the retrieved CSV data and store it directly as Delta tables.
Which approach would generally be recommended?
In particular, if we adopt a Medallion Architecture (Bronze / Silver / Gold), would it be a common or recommended pattern to:
rather than converting the data into tables immediately during ingestion?
Also, for continuously ingesting Marketo data via the Bulk API, are there any recommended Fabric implementation patterns using Data Pipeline, Notebook, or Dataflow Gen2, especially when considering incremental ingestion and Marketo API limits?
Any examples, architecture recommendations, or lessons learned from similar Marketo–Fabric integrations would be greatly appreciated.
Thank you!
#Microsoft Fabric #Data Factory #Dataflow Gen2 #Data Pipeline #REST API #Lakehouse #Data Integration #Marketo
Hi RMori95610,
Yes, that pattern would work, but for a straightforward upsert into a Silver Lakehouse table I don't think you necessarily need a Notebook anymore.
Fabric's current Lakehouse Copy Activity supports Upsert directly as the destination table action. You can specify one or more key columns, and Fabric will insert new rows or update matching existing rows.
So for something like Marketo Person data, I would consider:
Pipeline incremental extraction → Bronze → Copy Activity with Upsert → Silver Delta table
using the stable Marketo Person/Lead identifier as the key.
Your understanding of Dataflow Gen2 is also reasonable. Its incremental refresh currently uses a replace operation for the affected time buckets rather than providing a general key-based MERGE pattern.
I would move to a Notebook with Delta MERGE when the logic becomes more complex, for example conditional updates, deduplication, deletes/soft deletes, SCD handling, or other business rules that can't be expressed as a simple key-based upsert.
For append-oriented data such as Activity Logs, I would keep a separate pattern. If the records are immutable once created, append is simpler and avoids unnecessary merge work. If the source can revise existing events, then Upsert becomes appropriate there as well.
So broadly I would use:
1. Person/current-state data: Bronze → Copy Activity Upsert → Silver
2. Immutable activity/event data: Bronze → Append → Silver
3. Complex state/history logic: Bronze → Notebook MERGE → Silver
That keeps the architecture pipeline-first while only introducing Spark code where it is actually useful.AI-assisted drafting: AI was used to help structure and phrase this response. I reviewed and validated the technical content before posting.
9 Replies
- v-kathullac
Community Support
Hi RMori95610 ,
Thank you for reaching out to Microsoft Fabric Community Forum,Below are the few points which can resolve your issue.Let us know if you need any further assistance.
- There is no native Microsoft Fabric connector for Marketo; use the Marketo REST API or Bulk Extract API.
- Use Fabric Notebooks for production ingestion to handle authentication, pagination, retries, rate limits, and incremental loading.
- Use Data Pipelines for orchestration, scheduling, monitoring, and triggering notebook execution.
- Use the Bulk Extract API for high-volume data (such as Activity Logs) instead of the REST API.
- Follow the Medallion Architecture: store raw CSV files in Bronze and transform them into Delta tables in Silver.
- Separate ingestion from transformation to support reprocessing, auditing, and easier maintenance.
- Implement incremental loading using a watermark (last successful extraction time) to reduce API calls and improve performance.
- Retain Marketo Person ID along with Salesforce Lead/Contact IDs to establish reliable relationships between Marketo and Salesforce data..
- Secure API credentials using Fabric Variable Libraries or Azure Key Vault.
Thanks,
Chaithanya.
- ShivekMaharaj
Community Champion
Hi RMori95610,
I’d probably keep the architecture pipeline-first rather than defaulting to a notebook for all Marketo ingestion.
For the normal REST API, Fabric’s REST connector in Copy activity already supports GET/POST requests, pagination, additional headers and configurable intervals between requests. Marketo authentication is a client-credentials flow where you first obtain a short-lived access token from the Identity endpoint and then pass it as a Bearer token.
Because of that, one low-code pattern I would consider is:
Web activity → obtain Marketo token → REST/Copy activity → Lakehouse Bronze
and let the pipeline handle orchestration, retries, scheduling and watermarking.
I would move to a notebook when the API behaviour becomes awkward to express declaratively - for example complex pagination, custom retry/backoff logic, schema variation, or several dependent Marketo calls. I wouldn’t treat a notebook as mandatory just because there is no native Marketo connector.
For the Activity Log/Bulk Extract side, I would use a slightly different pattern:
Pipeline → create Bulk Extract job → enqueue → poll status → download completed file → Bronze Files → transform into Silver Delta tables
That maps quite naturally to how Marketo’s Bulk Extract API works because the exports are asynchronous.
I would definitely land the exported CSV unchanged in Bronze first, rather than converting it immediately during ingestion. Then parse/deduplicate/type it into Silver and expose business-ready datasets from Gold. That also aligns well with Microsoft’s recommended medallion pattern for Fabric.
One reason I would keep ingestion and transformation separate is Marketo’s own Bulk API limits. The default allocation is currently 500 MB/day, with only 2 export jobs processing concurrently and 10 jobs allowed in the queue. That makes incremental extraction and a reliable watermark/control table fairly important.
For example, I’d persist something like:
source | object/activity type | last_successful_watermark | job_id | status | extracted_at
and only advance the watermark after the file has landed successfully. That makes reruns much safer than deriving the next window purely from the pipeline execution time.
So my preference would be:
- Smaller/incremental REST extraction: Pipeline + REST/Web activities where practical.
- Complex REST behaviour: Notebook inside a pipeline.
- High-volume activities: Bulk Extract API, orchestrated by a pipeline.
- Storage: Raw response/files in Bronze → validated Delta tables in Silver → curated Gold as needed.
I’d also keep the Salesforce and Marketo ingestion paths separate at Bronze and join/conform them in Silver rather than coupling the source extractions together.
I really hope this helps. I think Fabric can handle this quite cleanly without requiring every Marketo interaction to become custom notebook code.
AI-assisted drafting: AI was used to help structure and phrase this response. I reviewed and validated the technical content before posting.
- v-kathullac
Community Support
Thankyou ShivekMaharaj for Addressing the issue.
Hi RMori95610 ,
As we haven’t heard back from you, we wanted to kindly follow up to check if the solution provided for the issue worked? or Let us know if you need any further assistance?
Regards,
Chaithanya
- v-kathullac
Community Support
Hi @RMori95610 ,
As we haven’t heard back from you, we wanted to kindly follow up to check if the solution provided for the issue worked? or Let us know if you need any further assistance?
Regards,
Chaithanya
- RMori95610
Advocate III
Apologies for the delayed response, as I was away on vacation.
Thank you both, v-kathullac and ShivekMaharaj, very much for your detailed responses. They were extremely helpful.
v-kathullac , your recommendation to use a Notebook to handle authentication, pagination, retries, API limits, and incremental loading, with a Pipeline handling scheduling and orchestration, helped clarify one possible production architecture.
ShivekMaharaj , your suggestion of taking a pipeline-first approach was also very helpful — using Web / REST / Copy activities where practical, and moving to a Notebook only when the API logic becomes more complex.
Based on both responses, for the standard Marketo REST API, we are considering first validating whether the ingestion can be implemented using Pipeline activities, and then using a Notebook where necessary, for example when complex pagination, custom retry/backoff logic, or other API-specific handling is required.
I also understand from both responses that for high-volume data such as Activity Logs, using the Bulk Extract API and landing the raw CSV files in Bronze before transforming them into Delta tables in Silver would be a good approach.
I have one additional question regarding how incrementally extracted data should be loaded into the Silver Delta tables.
I understand that a watermark can be used to retrieve only the Marketo data that has changed since the last successful extraction.
However, for data such as Marketo Person records, existing records may also be updated. Therefore, after retrieving the incremental data, we would need not only inserts but also updates (Upsert/MERGE) when loading the data into the existing Silver Delta table.
My understanding is that there are limitations around Upsert when using Dataflow Gen2 with a Lakehouse Delta table as the destination.
In a pipeline-first architecture, what would be the recommended approach for implementing Upsert/MERGE into the Silver Delta tables?
For example, would the following be a common pattern?
Pipeline incremental extraction → Bronze → MERGE using a Notebook (or another Fabric component) → Silver Delta table
Also, would you recommend using different Silver loading patterns for append-oriented data such as Activity Logs versus mutable data such as Person records?
Any guidance on the recommended Fabric pattern would be greatly appreciated.
Thank you again, for taking the time to provide such detailed guidance.
- ShivekMaharaj
Community Champion
Hi RMori95610,
Yes, that pattern would work, but for a straightforward upsert into a Silver Lakehouse table I don't think you necessarily need a Notebook anymore.
Fabric's current Lakehouse Copy Activity supports Upsert directly as the destination table action. You can specify one or more key columns, and Fabric will insert new rows or update matching existing rows.
So for something like Marketo Person data, I would consider:
Pipeline incremental extraction → Bronze → Copy Activity with Upsert → Silver Delta table
using the stable Marketo Person/Lead identifier as the key.
Your understanding of Dataflow Gen2 is also reasonable. Its incremental refresh currently uses a replace operation for the affected time buckets rather than providing a general key-based MERGE pattern.
I would move to a Notebook with Delta MERGE when the logic becomes more complex, for example conditional updates, deduplication, deletes/soft deletes, SCD handling, or other business rules that can't be expressed as a simple key-based upsert.
For append-oriented data such as Activity Logs, I would keep a separate pattern. If the records are immutable once created, append is simpler and avoids unnecessary merge work. If the source can revise existing events, then Upsert becomes appropriate there as well.
So broadly I would use:
1. Person/current-state data: Bronze → Copy Activity Upsert → Silver
2. Immutable activity/event data: Bronze → Append → Silver
3. Complex state/history logic: Bronze → Notebook MERGE → Silver
That keeps the architecture pipeline-first while only introducing Spark code where it is actually useful.AI-assisted drafting: AI was used to help structure and phrase this response. I reviewed and validated the technical content before posting.
- RMori95610
Advocate III
Hi ShivekMaharaj
Thank you very much for the detailed clarification. This was extremely helpful.I now understand that for a straightforward key-based upsert, we can use Copy Activity with Upsert directly into the Silver Lakehouse table, without necessarily introducing a Notebook.
The distinction between the three patterns — Upsert for current-state data such as Person, Append for immutable Activity/Event data, and Notebook/Delta MERGE for more complex logic — was especially helpful and makes the implementation approach much clearer.
We will use this as a basis for our Fabric architecture and further validate the implementation details.
Thank you again for taking the time to answer my follow-up question!
- v-kathullac
Community Support
Hi @RMori95610 ,
As we haven’t heard back from you, we wanted to kindly follow up to check if the solution provided for the issue worked? or Let us know if you need any further assistance?
Regards,
Chaithanya
- RMori95610
Advocate III
Hi, v-kathullac, ShivekMaharaj
We tested the recommended approach based on your guidance, and it worked successfully.
In particular, we were able to ingest Marketo data into Microsoft Fabric using a pipeline-based approach, land the data in the Bronze layer, and load it into the Silver Lakehouse table using Copy Activity with Upsert.
The distinction between using Upsert for mutable data such as Person records and Append for activity log data was also very helpful.
Thank you very much for providing such clear and practical guidance. We will continue validating the implementation based on this architecture as we move toward production.