Conseils sur la limitation des API pour les partenaires appelant les API du Centre des partenaires

Microsoft implémente la limitation des API pour permettre des performances plus cohérentes dans un intervalle de temps pour les partenaires appelant les API de l’Espace partenaires. La limitation restreint le nombre de requêtes pouvant être adressées à un service dans un laps de temps donné pour empêcher une surutilisation de ressources. Bien que l’Espace partenaires soit conçu pour gérer un gros volume de requêtes, si un petit nombre de partenaires exécute un nombre excessif de requêtes, la limitation permet de maintenir un niveau de performance et une fiabilité optimum pour tous les partenaires.

Les limites varient selon les scénarios. Par exemple, si vous effectuez un grand volume d’écritures, la possibilité de limitation est plus élevée que si vous effectuez uniquement des lectures.

Que se passe-t-il lorsque la limitation se produit ?

Quand un seuil de limitation est dépassé, l’Espace partenaires limite les requêtes supplémentaires en provenance du client pendant un certain temps. Le comportement de limitation dépend du type et du nombre de requêtes.

Scénarios de limitation courants

Les causes les plus courantes de la limitation des clients sont les suivantes :

  • Un grand nombre de demandes d’API par ID de locataire partenaire : pour certaines API de l’Espace partenaires, la limitation est déterminée par l’ID de locataire partenaire. Trop d’appels à ces API sur le même ID de locataire partenaire entraînent un dépassement du seuil de limitation.
  • Un grand nombre de demandes d’API par ID de locataire partenaire par ID de locataire client : pour d’autres API, la limitation est déterminée par l’ID de locataire partenaire/ID de locataire client ; dans ce cas, l’exécution d’un trop grand nombre d’appels sur le même ID client entraîne une limitation, tandis que les appels contre d’autres clients peuvent réussir.

Bonnes pratiques de gestion de la limitation

Les pratiques de programmation, telles que l’interrogation continue d’une ressource pour case activée des mises à jour et l’analyse régulière des collections de ressources pour case activée pour les ressources nouvelles ou supprimées, sont plus susceptibles d’entraîner une limitation et une dégradation des performances globales. Les appels d’API simultanés peuvent entraîner un nombre élevé de requêtes par heure unitaire, ce qui entraîne la limitation des requêtes. Vous devez utiliser plutôt le suivi des modifications et les notifications de modification. En outre, vous devez être en mesure d’utiliser les journaux d’activité pour détecter les modifications. Pour plus d’informations, consultez les journaux d’activité de l’Espace partenaires. Nous recommandons vivement aux partenaires d’utiliser l’API du journal d’activité pour plus d’efficacité et d’éviter la limitation. Consultez également l’exemple d’utilisation des journaux d’activité, ci-dessous.

Bonnes pratiques de gestion de la limitation

Voici les meilleures pratiques pour gérer la limitation :

  • Réduisez le degré de parallélisme.
  • Réduisez la fréquence des appels.
  • Évitez les nouvelles tentatives immédiates car toutes les requêtes exécutées sont comptées dans vos limites d’utilisation.

Lorsque vous implémentez la gestion des erreurs, utilisez le code d’erreur HTTP 429 pour détecter la limitation. La réponse ayant échoué comprend l’en-tête de réponse Retry-After. La méthode la plus rapide pour effectuer une récupération suite à une limitation consiste à reporter les requêtes à l’aide du délai Retry-After.

Pour utiliser le délai de nouvelle tentative :

  1. Attendez le nombre de secondes spécifiées dans l’en-tête Retry-After.
  2. Relancez la requête.
  3. Si la requête échoue à nouveau avec un code d’erreur 429, vous êtes toujours limité. Réessayez avec l’interruption exponentielle, utilisez le délai de nouvelle tentative recommandé et réessayez la requête jusqu’à ce qu’elle réussisse.
  4. Si vous utilisez le Kit de développement logiciel (SDK), vous recevez une exception avec le code d’état 429 lorsque votre demande est limitée. Utilisez la propriété RetryAfter dans l’exception et réessayez la requête une fois le temps écoulé.

API actuellement affectées par la limitation

À la fin, chaque API de l’Espace partenaires qui appelle le point de terminaison « api.partnercenter.microsoft.com/ » est limitée. Actuellement, les limites de limitation sont appliquées uniquement aux API répertoriées ci-dessous. L’Espace partenaires collecte les données de télémétrie sur chacune des API et ajuste dynamiquement les limites de limitation. Le tableau suivant répertorie les API où la limitation est actuellement appliquée.

Opération Documentation sur l'Espace partenaires
{baseURL}/v1/customers/{customer_id}/orders créer une commande
{baseURL}/v1/customers/{customer-tenant-id}/subscriptions/{id-for-subscription}/upgrades transition d’un abonnement
{baseURL}/v1/customers/{customer-tenant-id}/orders/{order-id} acheter un module complémentaire à un abonnement
{baseURL}/v1/customers/{customer-id}/carts/{cart-id} créer un panier
{baseURL}/v1/customers/{customer-id}/carts/{cart-id}/case activée out case activée out d’un panier
{baseURL}/v1/customers/{customer-id}/carts/{cart-id} mettre à jour un panier
{baseURL}/v1/customers/{customer-id}/subscriptions/{subscription-id}/registrations inscrire un abonnement
{baseURL}/v1/productupgrades créer une entité de mise à niveau de produit
{baseURL}/v1/customers/{customer-id}/subscriptions/{subscription-id}/conversions convertir un abonnement d’essai en abonnement payant
{baseURL}/v1/customers/{customer-tenant-id} obtenir un client par ID
{baseURL}/v1/productUpgrades/éligibilité obtenir l’éligibilité pour la mise à niveau du produit
{baseURL}/v1/customers/{customer-tenant-id}/subscriptions/{id-for-subscription} gérer l’abonnement
{baseURL}/v1/customers/{customer_id}/subscriptions get-all-of-a-customer-s-subscriptions
{baseURL}/v1/customers/{customer_id}/subscriptions/{subscription_id} Obtenir un abonnement par ID
{baseURL}/v1/customers/{customer_id}/orders Obtenir toutes les commandes client
{baseURL}/v1/customers/{customer_id}/orders/{order_id} Obtenir une commande par ID
{baseURL}/v1/customers/{customer_id}/orders/{order_id}/provisioningstatus Obtenir l’état de provisionnement d’un abonnement
{baseURL}/v1/customers/{customer_id}/subscriptions/{subscription_id} Gérer les commandes et gérer un abonnement
{baseURL}/v1/customers/{customer_id}/subscriptions/{subscription_id}/addons Obtenir la liste des extensions d’un abonnement
{baseURL}/v1/customers/{customer_id}/subscriptions/{subscription_id}/azureEntitlements Obtenir la liste des droits Azure d’un abonnement
{baseURL}/v1/customers/{customer_id}/subscriptions/{subscription_id}/registrationstatus Obtenir l’état d’inscription d’un abonnement
{baseURL}/v1/customers/{customer-tenant-id}/transfers Obtenir tous les transferts d’un client
{baseURL}/v1/productUpgrades/{upgrade-id}/status Obtenir l’état de mise à niveau du produit
{baseURL}/v1/customers/{customer-id}/subscriptions/{subscription-id}/conversions Obtenir la liste des offres de conversion d’essai
{baseURL}/v1/customers/{customer-tenant-id}/migrations/newcommerce/validate Valider un abonnement pour la migration
{baseURL}/v1/customers/{customer-tenant-id}/migrations/newcommerce Créer une migration commerciale
{baseURL}/v1/customers/{customerId}/promotionEligibilities Vérifier l’éligibilité d’une promotion

Réponse du code d’erreur :

HTTP/1.1 429 Too Many Requests 

Content-Length: 84 

Content-Type: application/json 

Retry-After: 57 

Date: Tue, 21 Jul 2020 04:10:58 GMT 

{ "statusCode": 429, "message": "Rate limit is exceeded. Try again in 57 seconds." } 

Exemple de journal d’activité

Pour une bonne pratique d’analyse des modifications quotidiennes, nous vous recommandons d’interroger l’enregistrement d’audit pour une journée spécifique.

Dans la réponse, vous obtenez un résultat avec des modifications apportées au type d’opération spécifique. Vous pouvez filtrer en fonction de l’opération à laquelle vous vous intéressez. Par exemple, si vous êtes intéressé par un client nouvellement créé, vous pouvez examiner operationType = « add_customer ».

Vous trouverez la liste des opérations/ressources dans ces documents d’API.

Exemple de réponse

Demande :

Http Get call: https://api.partnercenter.microsoft.com/v1/auditrecords?startDate=2020-09-02&endDate=2020-09-02&size=50 

Authorization: Bearer <token> 

Accept: application/json 

MS-RequestId: 127facaa-e389-41f8-8bb7-1d1af99db893 

MS-CorrelationId: de9c2ccc-40dd-4186-9660-65b9b64c3d14 

X-Locale: en-US 

Host: api.partnercenter.microsoft.com 

Connection: Keep-Alive 

Réponse :

{ 

    "totalCount": 17, 

    "items": [ 

        { 

            "id": "9daaeb1c-4195-4db5-9f1d-509eb70c8c2d_e905b566-4779-4e57-944c-7b1b5312705b_updatecustomeruserlicenses_637346859797753934", 

            "partnerId": "9daaeb1c-4195-4db5-9f1d-509eb70c8c2d", 

            "participants": [ 

                "9daaeb1c-4195-4db5-9f1d-509eb70c8c2d" 

            ], 

            "customerId": "e905b566-4779-4e57-944c-7b1b5312705b", 

            "userPrincipalName": "admin@testsw09.onmicrosoft.com", 

            "applicationId": "FulfillmentService", 

            "resourceType": "license", 

            "operationType": "update_customer_user_licenses", 

            "operationDate": "2020-09-02T23:26:19.7753934Z", 

            "operationStatus": "succeeded", 

            "customizedData": [ 

                { 

                    "key": "CustomerUserId", 

                    "value": "933808c7-b165-496c-a24e-1a4b7846fab4" 

                } 

            ], 

            "attributes": { 

                "objectType": "AuditRecord" 

            } 

        }, 

        { 

            "id": "9daaeb1c-4195-4db5-9f1d-509eb70c8c2d_86bddccf-9a53-40c6-907c-08067a3f8da7_ia80zlkxp6ewoqpp35pbqjlhqv9iigvz1_createorder_637346662909268372", 

            "partnerId": "9daaeb1c-4195-4db5-9f1d-509eb70c8c2d", 

            "participants": [ 

                "9daaeb1c-4195-4db5-9f1d-509eb70c8c2d" 

            ], 

            "customerId": "86bddccf-9a53-40c6-907c-08067a3f8da7", 

            "customerName": "CustomMetersStagingTest", 

            "userPrincipalName": "admin@testsw09.onmicrosoft.com", 

            "applicationId": "4990cffe-04e8-4e8b-808a-1175604b879f", 

            "resourceType": "order", 

            "resourceNewValue": "{\"Id\":\"Ia80ZLkXp6eWOqpp35pBQJLhqv9IiGVZ1\",\"AlternateId\":\"64144d300bde\",\"ReferenceCustomerId\":\"86bddccf-9a53-40c6-907c-08067a3f8da7\",\"BillingCycle\":\"monthly\",\"CurrencyCode\":\"USD\",\"CurrencySymbol\":\"$\",\"LineItems\":[{\"LineItemNumber\":0,\"ProvisioningContext\":null,\"OfferId\":\"DZH318Z0C964:0001:DZH318Z0BZDG\",\"SubscriptionId\":\"f428d44a-d08b-348b-579e-ce92a6362c7b\",\"ParentSubscriptionId\":null,\"TermDuration\":\"P1M\",\"TransactionType\":\"New\",\"FriendlyName\":\"SaaS custom meter offer - Bronze\",\"Quantity\":1,\"Pricing\":null,\"PartnerIdOnRecord\":null,\"RenewsTo\":null,\"Links\":{\"Product\":{\"Uri\":\"/products/DZH318Z0C964?country=US\",\"Method\":\"GET\",\"Body\":null,\"Headers\":[]},\"Sku\":{\"Uri\":\"/products/DZH318Z0C964/skus/0001?country=US\",\"Method\":\"GET\",\"Body\":null,\"Headers\":[]},\"Availability\":{\"Uri\":\"/products/DZH318Z0C964/skus/0001/availabilities/DZH318Z0BZDG?country=US\",\"Method\":\"GET\",\"Body\":null,\"Headers\":[]},\"ActivationLinks\":{\"Uri\":\"/customers/86bddccf-9a53-40c6-907c-08067a3f8da7/orders/Ia80ZLkXp6eWOqpp35pBQJLhqv9IiGVZ1/lineitems/0/activationlinks\",\"Method\":\"GET\",\"Body\":null,\"Headers\":[]}}}],\"CreationDate\":\"2020-09-02T17:58:01.7755853Z\",\"Status\":\"pending\",\"TransactionType\":\"UserPurchase\",\"Links\":{\"Self\":{\"Uri\":\"/customers/86bddccf-9a53-40c6-907c-08067a3f8da7/orders/Ia80ZLkXp6eWOqpp35pBQJLhqv9IiGVZ1\",\"Method\":\"GET\",\"Body\":null,\"Headers\":[]},\"ProvisioningStatus\":{\"Uri\":\"/customers/86bddccf-9a53-40c6-907c-08067a3f8da7/orders/Ia80ZLkXp6eWOqpp35pBQJLhqv9IiGVZ1/provisioningstatus\",\"Method\":\"GET\",\"Body\":null,\"Headers\":[]},\"PatchOperation\":{\"Uri\":\"/customers/86bddccf-9a53-40c6-907c-08067a3f8da7/orders/Ia80ZLkXp6eWOqpp35pBQJLhqv9IiGVZ1\",\"Method\":\"PATCH\",\"Body\":null,\"Headers\":[]}},\"Client\":{\"marketplaceCountry\":\"US\",\"deviceFamily\":\"UniversalStore-PartnerCenter\",\"name\":\"Partner Center Web\"},\"Attributes\":{\"ObjectType\":\"Order\"}}", 

            "operationType": "create_order", 

            "originalCorrelationId": "96514ebe-c1b2-4865-cb46-2c2d20a2e911", 

            "operationDate": "2020-09-02T17:58:10.9268372Z", 

            "operationStatus": "succeeded", 

            "customizedData": [ 

                { 

                    "key": "OrderId", 

                    "value": "Ia80ZLkXp6eWOqpp35pBQJLhqv9IiGVZ1" 

                }, 

                { 

                    "key": "AlternateId", 

                    "value": "64144d300bde" 

                }, 

                { 

                    "key": "BillingCycle", 

                    "value": "Monthly" 

                }, 

                { 

                    "key": "OfferId-0", 

                    "value": "DZH318Z0C964:0001:DZH318Z0BZDG" 

                }, 

                { 

                    "key": "SubscriptionId-0", 

                    "value": "f428d44a-d08b-348b-579e-ce92a6362c7b" 

                }, 

                { 

                    "key": "SubscriptionName-0", 

                    "value": "SaaS custom meter offer - Bronze" 

                }, 

                { 

                   "key": "Quantity-0", 

                    "value": "1" 

                }, 

                { 

                    "key": "PartnerOnRecord-0", 

                    "value": null 

                } 

            ], 

            "attributes": { 

                "objectType": "AuditRecord" 

            } 

        }, 

                           { 

            "id": "9daaeb1c-4195-4db5-9f1d-509eb70c8c2d_86bddccf-9a53-40c6-907c-08067a3f8da7_86bddccf-9a53-40c6-907c-08067a3f8da7_addcustomer_637346648528069005", 

            "partnerId": "9daaeb1c-4195-4db5-9f1d-509eb70c8c2d", 

            "participants": [ 

                "9daaeb1c-4195-4db5-9f1d-509eb70c8c2d" 

            ], 

            "customerId": "86bddccf-9a53-40c6-907c-08067a3f8da7", 

            "customerName": "CustomMetersStagingTest", 

            "userPrincipalName": "admin@testsw09.onmicrosoft.com", 

            "applicationId": "4990cffe-04e8-4e8b-808a-1175604b879f", 

            "resourceType": "customer", 

            "resourceNewValue": "{\"Id\":\"86bddccf-9a53-40c6-907c-08067a3f8da7\",\"CommerceId\":\"9dd78b4f-f98a-44b4-a2fa-2b82ac58d24c\",\"CompanyProfile\":{\"TenantId\":\"86bddccf-9a53-40c6-907c-08067a3f8da7\",\"Domain\":\"CustomMetersStagingTest.onmicrosoft.com\",\"CompanyName\":\"CustomMetersStagingTest\",\"Address\":null,\"Email\":null,\"OrganizationRegistrationNumber\":null,\"Links\":{\"Self\":{\"Uri\":\"/customers/86bddccf-9a53-40c6-907c-08067a3f8da7/profiles/company\",\"Method\":\"GET\",\"Body\":null,\"Headers\":[]}},\"Attributes\":{\"ObjectType\":\"CustomerCompanyProfile\"}},\"BillingProfile\":{\"Id\":\"4beafd7b-cdab-5bdc-52ed-02e16edf2e7a\",\"FirstName\":\"CustomMetersStagingTest\",\"LastName\":\"CustomMetersStagingTest\",\"Email\":\"CustomMetersStagingTest@CustomMetersStagingTest.com\",\"Culture\":\"en-US\",\"Language\":\"en\",\"CompanyName\":\"CustomMetersStagingTest\",\"DefaultAddress\":{\"Id\":null,\"Country\":\"US\",\"Region\":null,\"City\":\"Seattle\",\"State\":\"WA\",\"District\":null,\"AddressLine1\":\"CustomMetersStagingTest\",\"AddressLine2\":null,\"AddressLine3\":null,\"PostalCode\":\"98122\",\"FirstName\":\"CustomMetersStagingTest\",\"LastName\":\"CustomMetersStagingTest\",\"EmailAddress\":null,\"PhoneNumber\":null,\"MiddleName\":null},\"Attributes\":{\"Etag\":\"-2279334701316321663\",\"ObjectType\":\"CustomerBillingProfile\"}},\"RelationshipToPartner\":\"reseller\",\"AllowDelegatedAccess\":true,\"UserCredentials\":{\"userName\":\"admin\",\"password\":\"\"},\"AssociatedPartnerId\":null,\"CustomDomains\":null,\"Attributes\":{\"ObjectType\":\"Customer\"}}", 

            "operationType": "add_customer", 

            "originalCorrelationId": "7550d9ea-e64a-416f-e49b-3670c516cf69", 

            "operationDate": "2020-09-02T17:34:12.8069005Z", 

            "operationStatus": "succeeded", 

            "customizedData": [ 

                { 

                    "key": "PrimaryDomainName", 

                    "value": "CustomMetersStagingTest.onmicrosoft.com" 

                }, 

                { 

                    "key": "Relationship", 

                    "value": "Reseller" 

                } 

            ], 

            "attributes": { 

                "objectType": "AuditRecord" 

            } 

        }, 

                            

        ... 

    ], 

    "links": { 

        "self": { 

            "uri": "/auditrecords?startDate=2020-09-02&endDate=2020-09-02&size=50", 

            "method": "GET", 

            "headers": [] 

        } 

    }, 

    "attributes": { 

        "objectType": "Collection" 

    } 

}