Reference: Metering service APIs - Microsoft commercial marketplace
Inconsistency in request data structures for "Marketplace metered billing APIs", between managed apps and SaaS offers
- When submitting a single event, the payload only seems to contain a
resourceId
, and the note says thatresourceId
has different meaning for SaaS app and for Managed app emitting custom meter.", being a resourceGroupID for managed apps, and the SaaS subscription GUID for SaaS. - When submitting multiple events in batch, the documentation suggests that there is now a
resourceUri
andresourceID
, and the JSON samples even haveresourceId
(with lower-case 'd').
which mixes a SaaS and managed app in single request:
{
"request": [ // list of usage events for the same or different resources of the publisher
{ // first event
"resourceUri": "<guid1>", // Unique identifier of the resource against which usage is emitted.
},
{ // next event
"resourceId": "<guid2>",
}
]
}
Using the resourceId
for both Managed Apps, and SaaS offers
{
"resourceId": "" // URL path for managed app, GUID for SaaS
"effectiveStartTime": ...
"planId": ...
"dimension": ...
"quantity": ...
}
{
"status": "Accepted", "messageTime": ...,
"usageEventId": ...,
"resourceId, effectiveStartTime, planId, dimension, quantity"
}
{
"code": "BadArgument", "message": "One or more errors have occurred.",
"target": "usageEventRequest",
"details": [
{
"code": "BadArgument", "message": "The resourceId is required.",
"target": "ResourceId"
}
]
}
{
"code": "Conflict", "message": "This usage event already exist.",
"additionalInfo": {
"acceptedMessage": {
"status": "Duplicate", "messageTime": ...,
"usageEventId": ...,
"resourceId, effectiveStartTime, planId, dimension, quantity"
}
}
}
Using resourceUri
for managed apps, and resourceID
(orresourceId
) for SaaS.
The text says
{
"request": [
{ "resourceId, effectiveStartTime, planId, dimension, quantity" },
{ "resourceId, effectiveStartTime, planId, dimension, quantity" }
]
}
{
"count": 2,
"result": [
{
"status": "Accepted", "messageTime": ...,
"usageEventId": ...
"resourceId, effectiveStartTime, planId, dimension, quantity"
},
{
"status": "Duplicate", "messageTime": ...
"resourceId, effectiveStartTime, planId, dimension, quantity"
"error": {
"code": "Conflict", "message": "This usage event already exist.",
"additionalInfo": {
"acceptedMessage": {
"status": "Duplicate",
"messageTime": ...,
"usageEventId": ...,
"resourceId, effectiveStartTime, planId, dimension, quantity"
}
}
}
}
]
}
Request = (resourceId|resourceUri)/effectiveStartTime/planId/dimension/quantity
CodeAndMessage = code/message
StatusAndTime = status/messageTime
SuccessResponse = StatusAndTime + usageEventId + Request
SingleConflictResponse = CodeAndMessage + SingleSuccessResponse
BatchErrorResponse = StatusAndTime + Request + SingleConflictResponse