API Guide for MCA Partner Attestation
Overview
Microsoft has announced a new flow for MCA Partner Attestation.
API will usually be utilized in processes where automating a process is the goal.
Because of this we are introducing a function that allows brokers to automatically finalize attestations by removing the need to provide acceptance in the attestation flow when using our API’s.
Keep in mind that in any case of attestation, sufficient evidence of customer acceptance should be collected and this is particularly important if automatic finalization via API is used.
Note that the resulting attestation with Microsoft will still have acceptance provided as if a human user had accessed the generated agreement and provided acceptance if automatic finalization is used.
To support the new attestation flow we have to introduce changes to our API.
Please make sure you review the changes and make the needed adjustments.
Microsoft announced the currently support version of attestation will be deprecated the 05 January 2026.
Attestation process stages
Creation of attestation object
Acceptance
Finalization of attestation

Attestation API endpoints functionality
Start partner attestation - Creates the MCA attestation object and initiates the customer agreement signing process
Get status of an attestation - Allows to get the current status of an ongoing attestation
Finalize attestation - Finalizes an attestation where agreement is accepted
Get customer acceptance status - Gets the acceptance state of a customer. If acceptance exist in some way, no further acceptance (via direct or attestation) is needed.
Create MCA Attestations (auto-accepted & finalized) - Allows brokers to create attestations that does not require human input but will be automatically accepted and finalized. The attestation will be automatically finalized without the requirement to manually provide acceptance.
Note that automatic finalization method assumes strong evidence of customers acceptance is already collected by the partner
Example Use Case
In case you are using the API to onboard customers and add subscriptions today you are probably utilizing the /api/resellers/{resellerId}/organizations/{organizationId}/services/Csp to add CSP service to organizations.
If you are working with this endpoint and attestations you will have to change your integration.
If you want to use automatic finalization, just update your integration according to automatic attestation section and make sure to use automaticFlow=true and populate all required values.
If you want to use manual acceptance, start attestation and send the agreementlink to the intended recipient. Check for acceptance via the get partner attestation and verify status=2 (pending finalization). Once status=2 for the attestation (meaning acceptance has been provided via the link), continue with the call to finalize attestation.
Start Partner attestation
POST /api/resellers/{resellerId:guid}/organizations/{organizationId:guid}/services/csp/mca/attestation
Request body:
{
"signer": {
"firstName": "string",
"lastName": "string",
"emailAddress": "string",
"phoneNumber": "string"
},
"language": "string_language_code", // optional, 'en-US' will be picked as a default. Standard: IETF BCP 47 - https://learn.microsoft.com/en-us/globalization/locale/standard-locale-names
"country": "string_country_code", // Customer's country code (ISO 3166-1 alpha-2)
"acceptanceDate": "datetime"
}
In case of successful request:
HTTP Code 200 - OK
Response body:
{
"attestationId": "string",
"agreementLink": "string_url",
"expiresAt": "datetime"
}
In case of issue while starting Partner attestation:
Error-related HTTP Code
Response body (RFC 9457 “Problem Details for HTTP APIs”, see: Problem Details RFC9457 – Doing API Errors Well | Swagger):
{
"type": "string", // A URI reference that identifies the problem type. It's intended to provide human operators with a place to find more information about the error. If not present or applicable, it’s assumed to be “about:blank”
"status": int, // The HTTP status code generated by the origin server for this occurrence of the problem.
"title": "string", // A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization.
"detail": "string", // A human-readable explanation specific to this occurrence of the problem. Unlike the title, this field's content can vary by occurrence.
"instance": "string", //A URI reference that identifies the specific occurrence of the problem. It may or may not yield further information if dereferenced.
"code": "string", // Extension. Error code
"errors":[ // Extension. Error details collection
{
"detail":"The body property {name} is required",
"pointer":"/name"
}
]
}
Get Partner attestation
GET /api/resellers/{resellerId:guid}/organizations/{organizationId:guid}/services/csp/mca/attestation
In case Partner attestation exists for End-Customer:
HTTP Code - 200 OK
Response body:
{
"attestationId": "string",
"signer": {
"firstName": "string",
"lastName": "string",
"emailAddress": "string",
"phoneNumber": "string"
},
"mcaInfo": {
"language": "string_language_code",
"country": "string_country_code",
"templateId": "string"
},
"acceptanceDate": "datetime",
"status": int // Unspecified = 0, PendingAgreementAcceptance = 1, PendingFinalization = 2
"agreementLink": "string_url",
"expiresAt": "datetime"
}
In case Partner attestation does not exist for End-Customer:
HTTP Code - 404 Not Found
In case of issue while retrieving Partner Attestation:
Error-related HTTP Code
Response body (RFC 9457 “Problem Details for HTTP APIs”, see: Problem Details RFC9457 – Doing API Errors Well | Swagger):
{
"type": "string", // A URI reference that identifies the problem type. It's intended to provide human operators with a place to find more information about the error. If not present or applicable, it’s assumed to be “about:blank”
"status": int, // The HTTP status code generated by the origin server for this occurrence of the problem.
"title": "string", // A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization.
"detail": "string", // A human-readable explanation specific to this occurrence of the problem. Unlike the title, this field's content can vary by occurrence.
"instance": "string", //A URI reference that identifies the specific occurrence of the problem. It may or may not yield further information if dereferenced.
"code": "string", // Extension. Error code
"errors":[ // Extension. Error details collection
{
"detail":"The body property {name} is required",
"pointer":"/name"
}
]
}
Finalize Partner attestation
PUT /api/resellers/{resellerId:guid}/organizations/{organizationId:guid}/services/csp/mca/attestation/finalize
In case of successful request:
HTTP Code - 200 OK
In case of issue while finalizing Partner Attestation:
Error-related HTTP Code
Response body (RFC 9457 “Problem Details for HTTP APIs”, see: Problem Details RFC9457 – Doing API Errors Well | Swagger):
{
"type": "string", // A URI reference that identifies the problem type. It's intended to provide human operators with a place to find more information about the error. If not present or applicable, it’s assumed to be “about:blank”
"status": int, // The HTTP status code generated by the origin server for this occurrence of the problem.
"title": "string", // A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization.
"detail": "string", // A human-readable explanation specific to this occurrence of the problem. Unlike the title, this field's content can vary by occurrence.
"instance": "string", //A URI reference that identifies the specific occurrence of the problem. It may or may not yield further information if dereferenced.
"code": "string", // Extension. Error code
"errors":[ // Extension. Error details collection
{
"detail":"The body property {name} is required",
"pointer":"/name"
}
]
}
Get End-Customer’s acceptance state
GET /api/resellers/{resellerId:guid}/organizations/{organizationId:guid}/services/csp/mca/acceptance
In case of successful request (both Direct Acceptance and Acceptance via Partner Attestation are present):
HTTP Code - 200 OK
Response body:
{
"accepted": true,
"acceptedVia": ["CustomerDirectAcceptance", "PartnerAttestation"],
"acceptanceViaPartnerAttestation":
{
"signer": {
"firstName": "string",
"lastName": "string",
"emailAddress": "string",
"phoneNumber": "string"
},
"mcaInfoTemplateId": "templateId": "string",
"acceptanceDate": "datetime"
},
"lastSyncDate": "datetime"
}
In case of successful request (only Direct Acceptance is present):
HTTP Code - 200 OK
Response body:
{
"accepted": true,
"acceptedVia": ["CustomerDirectAcceptance"],
"lastSyncDate": "datetime"
}
In case of successful request (only Acceptance via Partner Attestation is present):
HTTP Code - 200 OK
Response body:
{
"accepted": true,
"acceptedVia": ["PartnerAttestation"],
"acceptanceViaPartnerAttestation":
{
"signer": {
"firstName": "string",
"lastName": "string",
"emailAddress": "string",
"phoneNumber": "string"
},
"mcaInfoTemplateId": "templateId": "string",
"acceptanceDate": "datetime"
},
"lastSyncDate": "datetime"
}
In case of successful request (no Acceptance is present):
HTTP Code - 200 OK
Response body:
{
"accepted": false,
"acceptedVia": [],
"lastSyncDate": "datetime"
}
In case of issue retrieving End-Customer’s acceptance state:
Error-related HTTP Code
Response body (RFC 9457 “Problem Details for HTTP APIs”, see: Problem Details RFC9457 – Doing API Errors Well | Swagger):
{
"type": "string", // A URI reference that identifies the problem type. It's intended to provide human operators with a place to find more information about the error. If not present or applicable, it’s assumed to be “about:blank”
"status": int, // The HTTP status code generated by the origin server for this occurrence of the problem.
"title": "string", // A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization.
"detail": "string", // A human-readable explanation specific to this occurrence of the problem. Unlike the title, this field's content can vary by occurrence.
"instance": "string", //A URI reference that identifies the specific occurrence of the problem. It may or may not yield further information if dereferenced.
"code": "string", // Extension. Error code
"errors":[ // Extension. Error details collection
{
"detail":"The body property {name} is required",
"pointer":"/name"
}
]
}
Refresh End-Customer’s acceptance state
POST /api/resellers/{resellerId:guid}/organizations/{organizationId:guid}/services/csp/mca/acceptance/refresh
In case of successful request:
HTTP Code - 202 Accepted
In case End-Customer’s sync is already ongoing
HTTP Code - 429 Too Many Requests
Response body (RFC 9457 “Problem Details for HTTP APIs”, see: Problem Details RFC9457 – Doing API Errors Well | Swagger):
{
"type": "string", // A URI reference that identifies the problem type. It's intended to provide human operators with a place to find more information about the error. If not present or applicable, it’s assumed to be “about:blank”
"status": int, // The HTTP status code generated by the origin server for this occurrence of the problem.
"title": "string", // A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization.
"detail": "string", // A human-readable explanation specific to this occurrence of the problem. Unlike the title, this field's content can vary by occurrence.
"instance": "string", //A URI reference that identifies the specific occurrence of the problem. It may or may not yield further information if dereferenced.
"code": "string", // Extension. Error code
"errors":[ // Extension. Error details collection
{
"detail":"The body property {name} is required",
"pointer":"/name"
}
]
}
In case of issue while requesting “Refresh End-Customer’s acceptance state”
Error-related HTTP Code
Response body (RFC 9457 “Problem Details for HTTP APIs”, see: Problem Details RFC9457 – Doing API Errors Well | Swagger):
{
"type": "string", // A URI reference that identifies the problem type. It's intended to provide human operators with a place to find more information about the error. If not present or applicable, it’s assumed to be “about:blank”
"status": int, // The HTTP status code generated by the origin server for this occurrence of the problem.
"title": "string", // A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization.
"detail": "string", // A human-readable explanation specific to this occurrence of the problem. Unlike the title, this field's content can vary by occurrence.
"instance": "string", //A URI reference that identifies the specific occurrence of the problem. It may or may not yield further information if dereferenced.
"code": "string", // Extension. Error code
"errors":[ // Extension. Error details collection
{
"detail":"The body property {name} is required",
"pointer":"/name"
}
]
}
Add CSP Service and Automatic attestation finalization (OrganizationCsp endpoint)
The current endpoint used to add the CSP service to an organization allows for creating MCA Attestation. This endpoint will change and support for automatic finalization is introduced.
If “partnerAttestation” section is provided in this call, “automaticFlow” has to be set to “true”.
POST api/resellers/{reseller_id:guid}/organizations/{organization_id:guid}/services/Csp
Request body:
{
"id": "string",
"currencyCode": "string",
"organizationNumber": "string",
"contactEmail": "string",
"contactFirstName": "string",
"contactLastName": "string",
"contactPhone": "string",
"city": "string",
"address": "string",
"postalCode": "string",
"domainPrefix": "string",
},
"partnerAttestation": { // optional
"automaticFlow": true, // mandatory field (if "partnerAttestation" is provided), if automaticFlow = true, then the whole Partner Attestation flow will be done by Cloudmore platform, otherwise exception will thrown
"signer": {
"firstName": "string",
"lastName": "string",
"emailAddress": "string",
"phoneNumber": "string"
},
"language": "string_language_code", // optional, 'en-US' will be picked as a default. Standard: IETF BCP 47 - https://learn.microsoft.com/en-us/globalization/locale/standard-locale-names
"country": "string_country_code", // Customer's country code (ISO 3166-1 alpha-2)
"acceptanceDate": "datetime"
}
}