Orientações de limitação de API para parceiros que chamam as APIs do Partner Center

A Microsoft está implementando a limitação de API para permitir um desempenho mais consistente dentro de um período de tempo para parceiros que chamam as APIs do Partner Center. A limitação restringe o número de solicitações para um serviço por um determinado período para evitar o uso excessivo de recursos. Embora o Partner Center seja criado para lidar com um alto volume de solicitações, se um número excessivo delas ocorrer por alguns parceiros, a limitação ajudará a manter o desempenho ideal e a confiabilidade para todos os parceiros.

Limites de limitação variam de acordo com o cenário. Por exemplo, se você estiver executando um grande volume de gravações, a possibilidade de limitação será maior do que se você estiver executando apenas leituras.

O que acontece quando ocorre a limitação?

Quando uma limitação restritiva é excedida, o Partner Center limita todas as solicitações subsequentes do cliente em questão por um determinado período. O comportamento de limitação depende do tipo e do número de solicitações.

Cenários comuns de limitação

As causas mais comuns de limitação de clientes incluem:

  • Um grande número de solicitações de uma API por ID de Locatário do Parceiro: para algumas APIs do Partner Center, a limitação é determinada pela ID do Locatário do Parceiro. Muitas chamadas para essas APIs na mesma ID de locatário do parceiro resultam na excedência do limite de limitação.
  • Um grande número de solicitações de uma API por ID de locatário de parceiro por ID de locatário do cliente: para outras APIs, a limitação é determinada pela combinação de ID de locatário de parceiro/ID de locatário do cliente; nesses casos, fazer muitas chamadas na mesma ID de locatário do cliente resulta em limitação, enquanto as chamadas em outros clientes podem ser bem-sucedidas.

Práticas recomendadas para evitar a limitação

As práticas de programação, como sondar continuamente um recurso para verificar se há atualizações e verificar regularmente as coleções de recursos para verificar se há recursos novos ou excluídos, têm maior probabilidade de levar à limitação e degradar o desempenho geral. Chamadas simultâneas à API podem levar a um alto número de solicitações por unidade de tempo, o que faz com que as solicitações sejam limitadas. Em vez disso, você deve usar o controle de alterações e as notificações de alterações. Além disso, você deve ser capaz de usar logs de atividades para detectar alterações. Para obter mais informações, consulte Logs de atividades do Partner Center. É altamente recomendável que os parceiros considerem o uso da API do log de atividades para obter mais eficiência e evitar a limitação. Veja também o exemplo de uso de logs de atividades, abaixo.

Práticas recomendadas para tratamento de limitação

Veja a seguir as práticas recomendadas para lidar com a limitação:

  • Reduzir o grau de paralelismo.
  • Reduzir a frequência de chamadas.
  • Evitar novas repetições imediatas, pois todas as solicitações se acumulam em relação aos seus limites de uso.

Quando você implementa o tratamento de erro, use o código de erro HTTP 429 para detectar a limitação. A resposta com falha inclui o cabeçalho de resposta de Retry-After. Retirar solicitações usando o atraso de Retry-After é a maneira mais rápida de se recuperar da limitação.

Para usar o atraso de repetição após:

  1. Aguarde o número de segundos especificado no cabeçalho Retry-After.
  2. Tente novamente a solicitação.
  3. Se a solicitação falhar novamente com um código de status 429, você ainda estará sendo limitado. Tente novamente com a retirada exponencial, use o atraso Retry-After recomendado e repita a solicitação até que ela seja bem-sucedida.
  4. Se você estiver usando o SDK, receberá uma exceção com o código de status 429 quando sua solicitação estiver sendo limitada. Use a propriedade RetryAfter na exceção e repita a solicitação depois que o tempo tiver decorrido.

APIs atualmente afetadas pela limitação

No final, cada API do Partner Center que chama o ponto de extremidade "api.partnercenter.microsoft.com/" é limitada. Atualmente, os limites de limitação são aplicados apenas nas APIs listadas abaixo. O Partner Center está coletando a telemetria em cada uma das APIs e ajusta dinamicamente os limites de limitação. A tabela a seguir lista as APIs em que a limitação é imposta no momento.

Operação Documentação do Partner Center
{baseURL}/v1/customers/{ID_do_cliente}/orders Criar um pedido
{baseURL}/v1/customers/{customer-tenant-id}/subscriptions/{id-for-subscription}/upgrades Fazer a transição de uma assinatura
{baseURL}/v1/customers/{customer-tenant-id}/orders/{order-id} Comprar um complemento para uma assinatura
{baseURL}/v1/customers/{customer-id}/carts/{cart-id} Criar um carrinho
{baseURL}/v1/customers/{customer-id}/carts/{cart-id}/checkout Finalize a compra de um carrinho
{baseURL}/v1/customers/{customer-id}/carts/{cart-id} Atualizar um carrinho
{baseURL}/v1/customers/{customer-id}/subscriptions/{subscription-id}/registrations Registre uma assinatura
{baseURL}/v1/productupgrades Criar entidade de atualização de produto
{baseURL}/v1/customers/{ID-do-cliente}/subscriptions/{ID-da-assinatura}/conversions Converter uma assinatura de avaliação em paga
{baseURL}/v1/customers/{customer-tenant-id} obter um cliente por ID
{baseURL}/v1/customers?size={size} Obtenha uma lista de clientes
{baseURL}/v1/productUpgrades/eligibility Obtenha qualificação para atualização do produto
{baseURL}/v1/customers/{customer-tenant-id}/subscriptions/{id-for-subscription} Gerenciar assinatura
{baseURL}/v1/customers/{ID_do_cliente}/subscriptions obter todas as assinaturas de um cliente
{baseURL}/v1/customers/{ID_do_cliente}/subscriptions/{ID_da_assinatura} Obter uma assinatura por ID
{baseURL}/v1/customers/{ID_do_cliente}/orders Obter todos os pedidos de clientes
{baseURL}/v1/customers/{ID_do_cliente}/orders/{ID_do_pedido} Obtenha um pedido por ID
{baseURL}/v1/customers/{ID_do_cliente}/orders/{ID_do_pedido}/provisioningstatus Obter o status de provisionamento da assinatura
{baseURL}/v1/customers/{ID_do_cliente}/subscriptions/{ID_da_assinatura} Gerenciar pedidos e uma assinatura
{baseURL}/v1/customers/{ID_do_cliente}/subscriptions/{ID_da_assinatura}/addons Obter uma lista de complementos de uma assinatura
{baseURL}/v1/customers/{ID_do_cliente}/subscriptions/{ID_da_assinatura}/azureEntitlements Obter uma lista de direitos do Azure para uma assinatura
{baseURL}/v1/customers/{ID_do_cliente}/subscriptions/{ID_da_assinatura}/registrationstatus Obter o status de registro de assinatura
{baseURL}/v1/customers/{ID-do-locatário-do-cliente}/transfers Obter todas as transferências de um cliente
{baseURL}/v1/productUpgrades/{ID-da-atualização}/status Obter o status de atualização do produto
{baseURL}/v1/customers/{ID-do-cliente}/subscriptions/{ID-da-assinatura}/conversions Obter uma lista de ofertas de conversão de avaliação
{baseURL}/v1/customers/{customer-tenant-id}/migrations/newcommerce/validate Validar uma assinatura para migração
{baseURL}/v1/customers/{customer-tenant-id}/migrations/newcommerce Criar uma migração de comércio
{baseURL}/v1/customers/{customerId}/promotionEligibilidades Verificar a qualificação de uma promoção

Resposta do código de erro:

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." } 

Exemplo de registro de atividades

Para obter as melhores práticas na análise de alterações diárias, recomendamos que você consulte o registro de auditoria de um dia específico.

Na resposta, você obtém um resultado com alterações no tipo de operação específico. Você pode filtrar com base na operação que lhe interessa. Por exemplo, se você estiver interessado em um cliente recém-criado, poderá examinar operationType = "add_customer".

A lista de operationtype/resources pode ser encontrada nestes documentos da API.

Exemplo de resposta

Solicitação:

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: aaaa0000-bb11-2222-33cc-444444dddddd 

X-Locale: en-US 

Host: api.partnercenter.microsoft.com 

Connection: Keep-Alive 

Resposta:

{ 

    "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": "aaaabbbb-0000-cccc-1111-dddd2222eeee", 

            "customerName": "CustomMetersStagingTest", 

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

            "applicationId": "00001111-aaaa-2222-bbbb-3333cccc4444", 

            "resourceType": "order", 

            "resourceNewValue": "{\"Id\":\"Ia80ZLkXp6eWOqpp35pBQJLhqv9IiGVZ1\",\"AlternateId\":\"64144d300bde\",\"ReferenceCustomerId\":\"aaaabbbb-0000-cccc-1111-dddd2222eeee\",\"BillingCycle\":\"monthly\",\"CurrencyCode\":\"USD\",\"CurrencySymbol\":\"$\",\"LineItems\":[{\"LineItemNumber\":0,\"ProvisioningContext\":null,\"OfferId\":\"DZH318Z0C964:0001:DZH318Z0BZDG\",\"SubscriptionId\":\"aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e\",\"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/aaaabbbb-0000-cccc-1111-dddd2222eeee/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/aaaabbbb-0000-cccc-1111-dddd2222eeee/orders/Ia80ZLkXp6eWOqpp35pBQJLhqv9IiGVZ1\",\"Method\":\"GET\",\"Body\":null,\"Headers\":[]},\"ProvisioningStatus\":{\"Uri\":\"/customers/aaaabbbb-0000-cccc-1111-dddd2222eeee/orders/Ia80ZLkXp6eWOqpp35pBQJLhqv9IiGVZ1/provisioningstatus\",\"Method\":\"GET\",\"Body\":null,\"Headers\":[]},\"PatchOperation\":{\"Uri\":\"/customers/aaaabbbb-0000-cccc-1111-dddd2222eeee/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": "aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e" 

                }, 

                { 

                    "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": "aaaabbbb-0000-cccc-1111-dddd2222eeee", 

            "customerName": "CustomMetersStagingTest", 

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

            "applicationId": "00001111-aaaa-2222-bbbb-3333cccc4444", 

            "resourceType": "customer", 

            "resourceNewValue": "{\"Id\":\"aaaabbbb-0000-cccc-1111-dddd2222eeee\",\"CommerceId\":\"9dd78b4f-f98a-44b4-a2fa-2b82ac58d24c\",\"CompanyProfile\":{\"TenantId\":\"aaaabbbb-0000-cccc-1111-dddd2222eeee\",\"Domain\":\"CustomMetersStagingTest.onmicrosoft.com\",\"CompanyName\":\"CustomMetersStagingTest\",\"Address\":null,\"Email\":null,\"OrganizationRegistrationNumber\":null,\"Links\":{\"Self\":{\"Uri\":\"/customers/aaaabbbb-0000-cccc-1111-dddd2222eeee/profiles/company\",\"Method\":\"GET\",\"Body\":null,\"Headers\":[]}},\"Attributes\":{\"ObjectType\":\"CustomerCompanyProfile\"}},\"BillingProfile\":{\"Id\":\"bbbbcccc-1111-dddd-2222-eeee3333ffff\",\"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" 

    } 

}