MDF REST API
Market Development Funds is fully driveable from outside the portal. Everything the MDF screens do - programs, allocations, requests, approvals, claims, proof of performance, reimbursement, reporting and attribution - is reachable over the public REST API with a bearer token, with no portal session and no UI.
This module is in beta. Its API surface may change between releases. Pin your integration to a known-good release and re-test after upgrades.
Two Surfaces, Deliberately Split
| Surface | Carries |
|---|
/api/3.0/mdf/{resource}/{id} | Module behavior only - composite views, status transitions, the approval engine, reimbursement, reports and partner orchestration. 57 resources. |
/api/3.0/entity/{Entity}
/api/3.0/query | Standard record CRUD on the MDF entities, and MEQL querying. Deliberately not duplicated on the module surface. |
The split is intentional: validation and record security live on the entity layer so they apply to every code path, and the module surface adds only the behavior the entity layer cannot express.
Confirm entity-endpoint availability on your portal. Generic /api/3.0/entity/… access depends on the entity being API-enabled. If a call returns 404 for a valid record id, that is what it means - use the module surface, or ask for the entity to be enabled.
Authentication
Standard REST v3 bearer authentication - exchange a refresh token at POST /api/3.0/token and send the result as Authorization: Bearer …. There is nothing MDF-specific about it.
The dispatcher accepts GET, POST, PUT and DELETE, and content negotiation for JSON or XML.
What Every Request Passes Through
In this order, before any resource runs:
- Licence check. Without the MDF licence you get 403 and "MDF is not available for this license."
- Read gate. The caller must be able to access MDF at all - administrator, an internal user with the Enable MDF Management Access permission, or an employee holding at least one program-audience share. Otherwise 401.
- Impersonation context is seeded from
?asAccount= if present.
Individual resources then apply their own gate on top.
The permission levels
| Level | Means | Resources |
|---|
| Read | Passes the module read gate. The endpoint scopes its own data. | Most of the surface |
| Manage | Can manage all programs. | Activity type and template writes, test notifications |
| Admin | System administrator. | Saving settings and approval chains, enabling the module, migration, reimbursement and its reversal |
The endpoint gate is not the whole security story. Many resources sit behind the read gate and enforce authorization deeper - in the approval engine or the entity layer - which is where a caller with the wrong scope is refused. Do not infer from a Read gate that a resource is harmless: decide, submit and nudge all change state, and are scoped and validated below the endpoint.
Some resources also vary their behavior by caller. queue, decide and bulkdecide receive the caller's administrator status and scope their results by it, rather than refusing the call.
Acting on a Partner's Behalf
Add ?asAccount={accountId} to seed an impersonated partner account for the request. The partner-scoped resources - dashboard, myprograms, myrequests, myclaims and the rest of the my… family - then answer as that partner.
This is how a headless integration serves partners without holding partner credentials. Two constraints:
- Only MDF managers can use it meaningfully - an administrator, or a user with the Enable MDF Management Access permission.
- Downstream validation still applies. Impersonation changes whose data is in scope; it does not bypass the rules that govern it.
The context is per-request and flows across the whole logical request.
Errors
| Code | Meaning here |
|---|
| 401 | Failed the module read gate. |
| 403 | No MDF licence, or the module is not enabled for a write that needs it - "MDF module is not enabled." |
| 404 | Unknown resource or record - including an entity endpoint that is not API-enabled. |
| 405 | Wrong verb for a resource that requires a specific one. |
| 400 | Validation failure. The message names the rule and usually the numbers involved. |
Validation messages are written to be shown to a person - for example a rejected claim states the claim amount, the approved budget and the remainder. Surface them rather than replacing them with your own.
Rules the API Enforces
The module fails closed, so an integration cannot bypass what the interface applies:
- A claim cannot exceed its activity's approved amount - the approved figure, not the requested one.
- An approval cannot exceed the partner's remaining allocation.
- Approved percent must be between 0 and 100.
- A request cannot be finalized while any activity awaits a decision.
- Claims cannot be filed against an unapproved activity, or after the claim deadline.
- A reimbursed claim is immutable.
- Approval chains: 20 steps maximum, step names unique and 100 characters maximum, escalation user distinct from the approver, and a program-owner step requires an escalation user as fallback.
- Activity type name and code are unique case-insensitively, and a type in use cannot be deleted.
Design Notes
- Balances are derived, never stored. Write the transaction and read the balance back; never write a balance.
- Attribution figures recalculate when attributions change, not as leads and opportunities progress. An integration syncing CRM stage changes will not move MDF ROI figures until attributions on that activity are touched.
- Proof of performance hangs off the activity, not the claim.
- The module must be activated first. The CRM lookup fields do not exist until then, so most resources return nothing on an unactivated portal. Check
settings before assuming. - There is no OpenAPI document and no independent versioning for this surface. It moves with the platform release.
See More
<< MDF Data Model | Resource Reference >>