> ## Documentation Index
> Fetch the complete documentation index at: https://muveya.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Webhooks

> Os webhooks ainda não estão disponíveis. Como manter seus sistemas em dia consultando a API periodicamente dentro do seu limite de uso.

<Warning>
  O muveya ainda não envia webhooks. Não há operação para registrar uma URL, nenhum evento é enviado aos seus sistemas e não há segredo de assinatura para gerenciar. Para acompanhar as mudanças, consulte a API periodicamente como descrito nesta página.
</Warning>

Se sua integração precisa de notificações automáticas, escreva para [team@muveya.com](mailto:team@muveya.com) descrevendo os eventos de que precisa. Quando os webhooks estiverem disponíveis, eles serão anunciados nas [novidades](/docs/pt/changelog).

## O que consultar

| Para saber quando | Consulte | Escopo | Como detectar a mudança |
| - | - | - | - |
| Um pedido novo é criado | `GET /v1/orders` (todas as páginas) | `orders:read` | Um `orderId` que você ainda não viu. Pedidos novos aparecem no fim, porque a lista vai do mais antigo para o mais recente. |
| Um pedido muda de status | `GET /v1/orders?status=...` ou `GET /v1/orders/{orderId}` | `orders:read` | Um `status` diferente. A `version` do pedido também aumenta toda vez que o status muda. |
| Uma entrega avança | `GET /v1/fulfillments?status=...` | `fulfillment:read` | Um `status` diferente ou um `updatedAt` posterior. |
| Eventos de custódia de um pedido | `GET /v1/fulfillments/{orderId}` | `fulfillment:read` | Novas entradas em `movements`, ou o surgimento de `delivery`, `receipt` ou `closure`. |
| O estoque de uma caixa muda | `GET /v1/inventory/boxes/{boxId}/balance` ou `.../movements` | `inventory:read` | `onHand` ou `reserved` diferentes, ou um `movementId` novo. |
| Os níveis de estoque de um depósito mudam | `GET /v1/inventory/balances?warehouseId=...` | `inventory:read` | `onHand`, `reserved` ou `available` diferentes por `boxId`. |
| Algo precisa de atenção | `GET /v1/analytics/exceptions` | `analytics:read` | Um `total` diferente, ou uma exceção cujo `drillDownId` você ainda não viu. |
| Uma exportação ficou pronta | `GET /v1/analytics/exports/{exportId}` | `analytics:read` | `status` passa para `ready` ou `failed`. |

## Planeje seu orçamento de consultas

Cada chave tem **120 requisições a cada 60 segundos**, compartilhadas por todas as operações (veja [Limites de uso](/docs/pt/api-reference/rate-limits)). O orçamento de uma integração poderia ficar assim:

| Processo | Frequência | Requisições por execução |
| - | - | - |
| Exceções operacionais | A cada minuto | 1 |
| Pedidos aguardando aprovação: `GET /v1/orders?status=pending_approval&limit=200` | A cada 5 minutos | 1 a cada 200 pedidos correspondentes |
| Entregas em trânsito: `GET /v1/fulfillments?status=dispatched&limit=200` | A cada 5 minutos | 1 a cada 200 entregas correspondentes |
| Varredura completa de pedidos: `GET /v1/orders?limit=200` | A cada hora | 1 a cada 200 pedidos |
| Unidades, depósitos e catálogo | Uma vez por dia | 4 |

Deixe margem para novas tentativas e para consultas manuais com a mesma chave, ou dê a cada processo sua própria chave.

## Boas práticas

* **Filtre por status** para ler apenas os pedidos ou entregas que você está esperando, em vez de varrer tudo.
* **Lembre-se do que você viu.** Guarde cada `orderId` com seu último `status` e `version`, e cada atendimento com seu último `updatedAt`. Aja apenas quando mudarem.
* **Conte com ver uma mudança mais de uma vez, ou com atraso.** Faça o processamento idempotente: tratar o mesmo status duas vezes não pode causar problemas.
* **Leia as listas inteiras com `limit=200`** e siga `nextCursor` até o fim (veja [Paginação](/docs/pt/api-reference/pagination)).
* **Não sobreponha execuções.** Comece a próxima consulta apenas quando a anterior terminar.
* **Espere diante de um `429`.** Aguarde o `Retry-After` antes da próxima requisição.

## Exemplo: detectar mudanças de status de pedidos

<CodeGroup>
  ```javascript JavaScript theme={null}
  const BASE_URL = "https://api.muveya.com";
  const headers = { Authorization: `Bearer ${process.env.MUVEYA_API_KEY}` };
  const seen = new Map(); // orderId -> version; keep it in your database

  async function pollOrders(status) {
    let cursor;
    do {
      const url = new URL("/v1/orders", BASE_URL);
      url.searchParams.set("limit", "200");
      url.searchParams.set("status", status);
      if (cursor) url.searchParams.set("cursor", cursor);

      const response = await fetch(url, { headers });
      if (response.status === 429) {
        const wait = Number(response.headers.get("retry-after") ?? "1");
        await new Promise((resolve) => setTimeout(resolve, wait * 1000));
        continue;
      }
      if (!response.ok) throw new Error(`HTTP ${response.status}`);
      const page = await response.json();

      for (const order of page.data) {
        if (seen.get(order.orderId) !== order.version) {
          seen.set(order.orderId, order.version);
          console.log(`Order #${order.number} is ${order.status}`);
        }
      }
      cursor = page.hasMore ? page.nextCursor : undefined;
    } while (cursor);
  }

  await pollOrders("pending_approval");
  ```

  ```python Python theme={null}
  import os
  import time
  import requests

  BASE_URL = "https://api.muveya.com"
  session = requests.Session()
  session.headers["Authorization"] = f"Bearer {os.environ['MUVEYA_API_KEY']}"
  seen = {}  # orderId -> version; keep it in your database

  def poll_orders(status):
      cursor = None
      while True:
          params = {"limit": 200, "status": status}
          if cursor:
              params["cursor"] = cursor
          response = session.get(f"{BASE_URL}/v1/orders", params=params, timeout=30)
          if response.status_code == 429:
              time.sleep(int(response.headers.get("Retry-After", "1")))
              continue
          response.raise_for_status()
          page = response.json()
          for order in page["data"]:
              if seen.get(order["orderId"]) != order["version"]:
                  seen[order["orderId"]] = order["version"]
                  print(f"Order #{order['number']} is {order['status']}")
          if not page["hasMore"]:
              return
          cursor = page["nextCursor"]

  poll_orders("pending_approval")
  ```
</CodeGroup>

## Páginas relacionadas

* [Paginação](/docs/pt/api-reference/pagination)
* [Limites de uso](/docs/pt/api-reference/rate-limits)
* [Escopos](/docs/pt/api-reference/scopes)
* [Entregas: visão geral](/docs/pt/deliveries/overview)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.