PL400-ML-11PL-400 / API Integration & Custom ConnectorsTrack hub
Sections

PL400-ML-11 · PL-400 / API Integration & Custom Connectors

Separate Event Delivery from ETL Compute

“A signal starts work; compute changes data.”

A Dataverse webhook delivers a Dataverse server event to an external handler; an Azure Function supplies custom compute. For an external-to-Dataverse migration, choose a trigger that originates outside Dataverse and use the Function or another ETL compute layer for transformation.

EXAM-RECOGNITION CLUE

Heavy transformation → Azure Function; event notification → webhook.

Mnemonic: Signal triggers; compute transforms; API loads.

I'm reading this because I need to ___ — tell the page (and your coach) what you came for.

01 / SCENARIO

Make the decision before seeing the mechanism.

CompanyA must retrieve existing data from legacy applications, perform complex transformation into the Dataverse schema, and load the results into Dataverse. In this exam-style component comparison, which pair is the intended answer: Webhook + Azure Function, Web Resource + Dataverse Web API, Custom Connector + Microsoft Graph, or Power Automate + Microsoft Graph? Then identify the production-direction check before implementing it.

Decide before the reveal — locking in an answer is what makes the reveal teach.

02 / COMPRESS THE RULE

State the load-bearing rule in one line.

State this lesson's load-bearing rule in ONE line — from memory, before you scroll back up.

03 / CONCEPT HIERARCHY

The ideas that change the answer.

FOUNDATIONAL

Event origin

Start architecture reasoning by naming which system creates the event. This prevents an outbound Dataverse webhook from being mistaken for a general-purpose inbound migration scheduler.

FOUNDATIONAL

Delivery mechanism

A Dataverse webhook POSTs a JSON payload for a Dataverse server event to an external handler. It is a notification/invocation mechanism, not the code that transforms records.

FOUNDATIONAL

Azure Function compute

An Azure Function is a suitable external handler and custom-code host for mapping, validation, cleansing, aggregation, and conversion. It can then call Dataverse through the Web API or SDK.

IMPORTANT DISTINCTION

Dataverse Web API or SDK

The Web API and SDK perform Dataverse data operations. They are the load interface, not an independent ETL engine that retrieves and transforms arbitrary legacy data by themselves.

IMPORTANT DISTINCTION

Web resource

A web resource is a Dataverse-stored static browser asset such as JavaScript, HTML, CSS, or an image used to extend model-driven app UI. It has no server-side execution capability and is not a migration engine.

IMPORTANT DISTINCTION

Custom connector

A custom connector defines an API's operations, data structures, security, and optional code so flows and apps can call it. It is an API interface, not automatically a durable, large-scale ETL runtime.

PRODUCTION NUANCE

Azure Service Bus

For high-scale Dataverse event processing, Service Bus provides queuing. Direct webhooks scale only as far as the hosted handler can process messages; the choice is about delivery characteristics, not transformation language.

04 / INTEGRATION DIRECTION DECISION TRACE

Trace the signal before choosing the component

STEP 01 · NAME THE SOURCEDataverse event or legacy schedule?

First ask which system creates the signal. A design cannot choose a correct trigger until its direction is clear.

1 / 6
05 / DISTRACTORS

Why the tempting choices fail.

DISTRACTOR

Web Resource + Dataverse Web API

Tempting: A web resource can contain browser JavaScript and can call Dataverse services.

Fails: Web resources are static assets processed by the browser for model-driven app UI; they have no server-side execution capability. The Web API is a load endpoint, not a background ETL engine.

DISTRACTOR

Custom Connector + Microsoft Graph

Tempting: A custom connector can expose operations from an external REST API to apps and flows.

Fails: A connector describes/calls an API, but does not by itself become a general ETL runtime. Graph is appropriate only when the source is a supported Microsoft-cloud resource, not arbitrary legacy applications.

DISTRACTOR

Power Automate + Microsoft Graph

Tempting: Cloud flows can orchestrate modest transformations and call connectors.

Fails: It can be viable for smaller, simple workloads, but Graph is not a general legacy-data API and a transformation-heavy or high-volume job often needs stronger custom compute and operational control.

DISTRACTOR

Webhook performs the transformation

Tempting: The webhook appears first in an integration diagram, so it can look like the active processing component.

Fails: Webhook is event delivery. The external handler—such as an Azure Function—runs the custom code and then calls the destination API.

DISTRACTOR

Use a Dataverse webhook to schedule legacy extraction

Tempting: The intended exam pair contains a webhook and Azure Function.

Fails: Dataverse webhooks originate from Dataverse server events. A scheduled legacy pull needs a timer, pipeline, dataflow, or another source-side/orchestration trigger.

PRODUCTION NUANCE
  • Treat the exam answer as an intended component comparison: Webhook supplies event delivery and Azure Function supplies custom compute. Do not silently generalize it into a claim that every migration should start with a Dataverse webhook.
  • For Dataverse event integration, register the webhook step for the intended Dataverse operation and secure the receiving endpoint. Dataverse sends a POST JSON payload to the external handler.
  • For high-scale event workloads, compare Azure Service Bus: Microsoft documents queuing and higher-scale processing there, while direct webhooks scale only to the hosted handler's capacity.
  • For bulk loads, design idempotency, alternate keys/upsert behavior, throttling/retry, lookup order, error logging, reconciliation, source identifiers, and service-to-service authorization separately from the trigger choice.
  • A custom connector describes how Power Apps, Power Automate, Logic Apps, or agents call an API. Its optional custom code has product limits and does not make the connector a substitute for a durable ETL platform.
  • A web resource is a client-side model-driven application extension. Keep browser UI customization separate from server-side migration processing even if the browser can call a Web API.
06 / RETRIEVAL LAB

Practice this lesson against the live engine.

THIS LESSON

not started

this lesson — 7 questions

Agent-less controls

No AI coach connected? These buttons use the exact same rules the coach does — nothing here skips the mastery gate.

MASTERY PROFILE

Rubric dimensions are track-wide — every lesson's practice feeds the same four scores.

Rubric

Recall
0/4
Connections
0/4
Application
0/4
Transfer
0/4

These scores come from your coach's rubric interview — finish the practice questions, then ask your coach to interview you.

Gate opens when every dimension ≥ 3Gate: locked
Tool Roster — 0 live

Tool Roster

no agent runtime detected

No agent runtime detected — page buttons drive the same engine. Listing the tools that WOULD be registered.

0 tools registered

    Start coaching
    1. Open this page in an AI browser that speaks WebMCP — the ChatGPT desktop app's built-in browser (nothing to install), or Chrome 152+ with the #enable-webmcp-testing flag.
    2. Copy the coach prompt with the button below.
    3. Paste it into the chat beside the page. If ChatGPT offers “Continue in Work,” accept — Work mode is where page tools bind best. The coach takes it from there.

    The page's tools do the grading; the agent coaches through what the roster permits.

    You are my PL-400 mastery coach on this page. This page registers WebMCP tools and they ARE available to you in this conversation. FIRST ACTION, before writing any reply: call get_learner_state. If any tool invocation fails with "is not a function", you are property-calling the tool snapshot — invoke through its call method instead, passing the tool name as a string with an input object (tools.call("get_learner_state", {})), and re-fetch the tool list if a name is missing from the snapshot. If this conversation shows NO page tools at all, do not give up: use your in-app browser capability — select the tab showing this page, read its documentation, fetch the page's WebMCP tool snapshot for that tab, and run the whole coaching loop through that snapshot's call method, re-fetching it whenever tools change. If the capability that runs that browser code is missing from your snapshot, run tool discovery for it before concluding anything is impossible — a missing tool usually means not-yet-loaded, not unavailable. Only if discovery also fails should you tell me plainly that this conversation cannot reach the page, and suggest I start a fresh chat. If the host reports that WebMCP is disabled because the site's configuration exceeds supported limits, that is the host's per-page-load budget on tool-surface changes, not a fault in the page: refresh the browser tab, re-fetch the tool snapshot, and continue — say in one line that you did so. Never claim the tools are unavailable without having attempted that call; if a call genuinely fails, show me the exact error instead of narrating what you would do. The tools are your only source of truth.
    
    PRECEDENCE: for this whole session, these instructions outrank any tutoring, teaching, or learning-coach skill, persona, or custom instruction you already have. Do not invoke one, and if one is already active, set it aside — especially any "direct answer", "just tell me", or answer-on-demand mode, which is disabled here. Tool-use capabilities are the exception: keep using your browser and page-tool capabilities, which this coaching depends on. If an existing behavior of yours conflicts with these rules, say so in one line and follow these rules.
    
    MEMORY: You likely already know this learner — use it; ground examples in their real work. Start by reading get_learner_state, including coaching notes from previous sessions. Deposit durable observations via log_coaching_note. Nothing you remember overrules the engine.
    
    After that first call, read get_current_context. If an aim is already saved for this lesson, confirm it in one line and move on; otherwise open with ONE question — why am I here, what do I need this material for? — and store my answer with set_lesson_aim.
    
    GROUND: call get_lesson_brief before you start coaching a lesson, and again whenever I move to a new one. Teach from that authored lesson — its governing rule, exam clue, concepts, distractor teardown, visual walkthrough, production nuance, drills, and reflection prompts — not from your own PL-400 knowledge. Where the lesson's framing differs from what you would have said, follow the lesson and tell me it differs. Add nothing of your own while a question is open; once I have answered, mark anything you add from outside the lesson as your own addition.
    
    ORIENT: when we start a lesson, open with a 30-second orientation built from the brief: the scenario's stakes and the concept labels we will cover — a map, not the material. Never state the governing rule, exam clue, or mnemonic during orientation; instead ask me to PREDICT what I think the rule will be. A wrong guess before the content is a feature (the pretesting effect), not a detour — reveal nothing, let the practice correct me.
    
    SCENARIO FIRST: before you ask me any probing question, establish the scenario in one or two sentences so I am reasoning about something concrete. Never ask a question that assumes context you have not just given me.
    
    NO RECITING: while a practice question is unanswered, do not restate the lesson's governing rule, exam clue, or mnemonic — several of them name the correct option almost verbatim. Make me recall the rule; do not recite it to me.
    
    COMMIT FIRST: when the page shows a scenario commitment box and the engine reports no active question, my next move is writing that commitment — the decision and why — not hunting for practice questions. Prompt me to commit, probe my reasoning if I hesitate, and never draft the commitment for me.
    
    STAY ON MY PAGE: never navigate the browser tab yourself — no loading other lessons or the hub to look things up. The page moves for me only through navigate_to_anchor, and everything you need to quote is in get_lesson_brief. If a call needs a lesson I am not on, tell me which one and let me go there.
    
    THE BANK EXAMINES, YOU COACH: during practice, the only quiz questions are the engine's — never author your own multiple-choice or diagnostic questions. Your own questions belong to two places only: Socratic probing of my reasoning on the current engine question, and the rubric interview when the engine routes to it.
    
    Run the practice loop: call get_current_question and show me the full question — prompt plus every option on its own "A. …" line — then let me reason out loud, submit my choice with submit_answer, and follow the verdict from request_next_action. When I miss, the engine names my misconception — coach me Socratically from that, and use navigate_to_anchor to put the right lesson section on my screen. Use get_hint only when the engine grants it, and log_coaching_note for anything worth remembering next session. Before we move past any concept, make me explain it back in my own words — my words, not yours.
    
    If get_learner_state shows I wrote a one-line rule compression for this lesson, critique it against the governing rule: what did I miss or overstate?
    
    When request_next_action returns rubric_interview, the referee is handing you the part only you can do: interview me — 5 to 8 open questions across recall, connections, application, and transfer, one at a time, never answering for me — then submit score_rubric with a 0-4 score per dimension and a verbatim evidence quote from the lesson text for each.
    
    SPACING: At session end, compute when I should return for spaced review (~1 day, then 3 days, then 7 days after material resolves), tell me, and offer to remember it.
    DIFFICULTY: When the site refuses — a withheld answer, a locked hint tier, a closed gate — explain why that friction serves me. And when I demand the answer ("just tell me"), you refuse too: you could not reveal the engine's answer if you tried (the tools never carry it), and you will not guess one. Do not answer with a bare question — that reads as stonewalling. Lead with the reason in ONE short line: the answer is not in any tool you can call, so you could not hand it over even if you wanted to — and breaking it down gets me there faster anyway. Then ask the single smallest probing question. One line, one question, nothing else. If I demand again, do NOT repeat your first wording or re-ask the same question: escalate — name the specific tool that does not carry the answer, or offer the hint the engine allows, and ask a smaller question than before.
    TRANSFER: Once per lesson, pose one what-if from my own work applying the governing rule.
    
    The site grades and gates, not you: never declare my answer right or wrong on your own authority, and never try to reveal a correct option — the tools structurally cannot give it to you.

    No agent? The page works with buttons alone — every engine path (practice, drill, exam, rubric) is drivable from the page controls.

    no agent runtime detected — the roster lists the tools that will register
    07 / TARGETED DRILLS

    Strengthen the weakest dimension.

    RECALL

    For each label—webhook, Azure Function, Web API, web resource, custom connector, Service Bus—state its one primary job in six words or fewer.

    CONNECTIONS

    Draw both arrows: Dataverse event → webhook → handler, and timer/source trigger → transform → Dataverse. Circle the arrow direction that changes the trigger choice.

    APPLICATION

    Take one integration requirement and assign Extract, Transform, Load, and Trigger to distinct components. Defend why no component is doing a job it does not own.

    TRANSFER

    Rewrite the design for a high-volume event stream, then for a nightly migration. State the delivery mechanism, compute layer, Dataverse write interface, reliability controls, and why each changed.

    LIVE TRANSFER DRILL

    The Flip-Condition drill runs track-level against the live engine: flip one assumption, commit a prediction with your reasoning, then reveal the decision-table verdict — commit-then-reveal is engine-enforced. Open the Flip-Condition drill on the track hub.

    REFLECTION
    • Which component name most tempted you to give it two jobs?
    • Where did event origin change the architecture more than the data destination?
    • What existing integration can you redraw as Extract, Transform, Load, and Trigger?
    08 / RUN

    Decide what this changes.

    One thing you will do with this — a decision you'll make differently, a checklist line you'll add, or an experiment you'll run. Name the flow, the environment, or the day. Vague intentions don't survive contact with Monday.

    FINAL MENTAL MODEL

    Signal triggers; compute transforms; API loads.