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

# Primeiros passos

> Crie uma chave de API e faça a primeira chamada em menos de 5 minutos.

Neste guia você cria uma chave, faz a primeira chamada e lê a resposta. Você precisa de acesso de
**administrador** à conta Zouti e de um terminal com `curl` (ou Node.js 18+, Python 3 ou PHP).

<Steps>
  <Step title="Crie uma chave de API">
    No dashboard da Zouti, abra **Configurações → Chaves de API** e clique em **Criar chave**. Só
    um administrador da conta cria chaves.

    * **Nome da chave**: diga onde ela vai ser usada, como `ERP` ou `Planilha financeira`.
    * **Expiração (opcional)**: no mínimo 1 hora a partir de agora. Sem data, a chave não expira.

    A chave (`zt_live_...`) aparece **uma única vez**, no painel **Chave de API criada**. Copie e
    guarde num cofre de segredos: a Zouti guarda só um hash e não consegue mostrá-la de novo.
  </Step>

  <Step title="Guarde a chave numa variável de ambiente">
    ```bash theme={null}
    export ZOUTI_API_KEY="zt_live_..."
    ```

    Troque `zt_live_...` pela chave copiada. Todos os exemplos desta documentação leem a chave de
    `ZOUTI_API_KEY`. Não escreva a chave no código.
  </Step>

  <Step title="Faça a primeira chamada">
    Peça o pedido mais recente da conta:

    ```bash theme={null}
    curl -i "https://api.zouti.com.br/v1/orders?limit=1" \
      -H "Authorization: Bearer $ZOUTI_API_KEY"
    ```

    A mesma chamada em Node.js, Python e PHP está ao lado. Uma chave recém-criada leva cerca de
    1 segundo para valer: se a primeira chamada receber `401`, espere alguns segundos e repita.
  </Step>

  <Step title="Leia a resposta">
    A resposta é uma página de pedidos:

    * `object` é `"list"`.
    * `data` traz os pedidos, do mais novo para o mais antigo. `data[0]` é um
      [objeto pedido](/api-reference/order-object).
    * `has_more` diz se há mais páginas. Quando é `true`, envie `next_cursor` no parâmetro
      `cursor` para ler a próxima. Veja [Paginação](/concepts/pagination).

    Os headers também importam:

    * `Request-Id` identifica a requisição (`req_...`). Guarde-o no log e informe-o ao suporte.
    * `RateLimit-Limit`, `RateLimit-Remaining` e `RateLimit-Reset` mostram quanto do limite da
      conta ainda está disponível. Veja [Limites de requisição](/concepts/rate-limits).

    Se a conta ainda não tem pedidos, `data` vem vazio e `has_more` vem `false`.
  </Step>
</Steps>

## Se algo der errado

| Resposta | Causa provável | O que fazer |
| - | - | - |
| `401` `invalid_api_key` | Chave errada, com espaço sobrando, revogada ou expirada. | Copie a chave de novo, sem espaço nem quebra de linha. Veja [Autenticação](/concepts/authentication). |
| `400` em texto puro | A chamada foi em `http://`. | Use `https://`. Revogue a chave que trafegou por HTTP. |
| `429` | Limite de requisições excedido. | Espere os segundos do header `Retry-After`. |

Os demais códigos estão em [Erros](/concepts/errors).

## Próximos passos

<CardGroup cols={2}>
  <Card title="Autenticação" icon="key" href="/concepts/authentication">
    Guardar a chave, trocá-la sem parar a integração e revogá-la.
  </Card>

  <Card title="Sincronização de pedidos" icon="arrows-rotate" href="/concepts/sync">
    Manter uma cópia local dos pedidos novos e alterados.
  </Card>

  <Card title="Objeto pedido" icon="receipt" href="/api-reference/order-object">
    Todos os campos do pedido e o significado de cada valor.
  </Card>

  <Card title="Erros" icon="triangle-exclamation" href="/concepts/errors">
    O que fazer com cada `code` e quando repetir.
  </Card>
</CardGroup>

<RequestExample>
  ```bash cURL theme={null}
  # -i mostra os headers (Request-Id, RateLimit-*) antes do corpo.
  curl -i "https://api.zouti.com.br/v1/orders?limit=1" \
    -H "Authorization: Bearer $ZOUTI_API_KEY"
  ```

  ```javascript Node.js theme={null}
  // Node.js 18+ (fetch nativo, sem dependência). Salve como primeira-chamada.mjs e rode
  // `node primeira-chamada.mjs`.
  const response = await fetch('https://api.zouti.com.br/v1/orders?limit=1', {
    headers: { Authorization: `Bearer ${process.env.ZOUTI_API_KEY}` },
  });

  console.log(`HTTP ${response.status} · Request-Id ${response.headers.get('Request-Id')}`);
  console.log(`RateLimit-Remaining ${response.headers.get('RateLimit-Remaining')}`);

  const body = await response.json();
  if (!response.ok) {
    console.error(`${body.error.code}: ${body.error.message}`);
    process.exit(1);
  }

  const [order] = body.data;
  console.log(order ? `${order.id} · ${order.status} · ${order.amount_total} centavos` : 'Nenhum pedido ainda.');
  console.log(`has_more: ${body.has_more}`);
  ```

  ```python Python theme={null}
  # Python 3 com requests (pip install requests).
  import os

  import requests

  response = requests.get(
      "https://api.zouti.com.br/v1/orders",
      params={"limit": 1},
      headers={"Authorization": f"Bearer {os.environ['ZOUTI_API_KEY']}"},
      timeout=30,
  )

  print(f"HTTP {response.status_code} · Request-Id {response.headers.get('Request-Id')}")
  print(f"RateLimit-Remaining {response.headers.get('RateLimit-Remaining')}")

  body = response.json()
  if not response.ok:
      raise SystemExit(f"{body['error']['code']}: {body['error']['message']}")

  if body["data"]:
      order = body["data"][0]
      print(f"{order['id']} · {order['status']} · {order['amount_total']} centavos")
  else:
      print("Nenhum pedido ainda.")
  print(f"has_more: {body['has_more']}")
  ```

  ```php PHP theme={null}
  <?php
  // PHP 7.4+ com a extensão curl.
  $headers = [];
  $ch = curl_init('https://api.zouti.com.br/v1/orders?limit=1');
  curl_setopt_array($ch, [
      CURLOPT_RETURNTRANSFER => true,
      CURLOPT_TIMEOUT => 30,
      CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('ZOUTI_API_KEY')],
      CURLOPT_HEADERFUNCTION => function ($ch, $line) use (&$headers) {
          $parts = explode(':', $line, 2);
          if (count($parts) === 2) {
              $headers[strtolower(trim($parts[0]))] = trim($parts[1]);
          }
          return strlen($line);
      },
  ]);
  $raw = curl_exec($ch);
  if ($raw === false) {
      fwrite(STDERR, curl_error($ch) . PHP_EOL);
      exit(1);
  }
  $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
  $body = json_decode($raw, true);

  printf("HTTP %d · Request-Id %s\n", $status, $headers['request-id'] ?? '-');
  printf("RateLimit-Remaining %s\n", $headers['ratelimit-remaining'] ?? '-');

  if ($status !== 200) {
      fwrite(STDERR, sprintf("%s: %s\n", $body['error']['code'], $body['error']['message']));
      exit(1);
  }

  $order = $body['data'][0] ?? null;
  echo $order
      ? sprintf("%s · %s · %d centavos\n", $order['id'], $order['status'], $order['amount_total'])
      : "Nenhum pedido ainda.\n";
  printf("has_more: %s\n", $body['has_more'] ? 'true' : 'false');
  ```
</RequestExample>

<ResponseExample>
  ```json 200 theme={null}
  {
    "object": "list",
    "data": [
      {
        "object": "order",
        "id": "ord_8k2m4q6s1v3x5z7b9d0f2h",
        "role": "OWNER",
        "status": "PAID",
        "currency": "BRL",
        "amount_total": 27730,
        "amount_subtotal": 29700,
        "amount_in_brl": 27730,
        "created_at": "2026-10-14T13:05:22.418Z",
        "paid_at": "2026-10-14T13:05:24.902Z",
        "canceled_at": null,
        "updated_at": "2026-10-14T13:05:25.117Z",
        "customer": {
          "name": "Maria Oliveira",
          "email": "maria.oliveira@example.com",
          "phone": "+5511999998888",
          "document": "12345678909",
          "document_type": "CPF"
        },
        "shipping_address": {
          "line1": "Rua das Flores",
          "line2": "123",
          "line3": "Apto 45",
          "neighborhood": "Centro",
          "city": "São Paulo",
          "state": "SP",
          "country": "BR",
          "postal_code": "01001000",
          "full_name": "Maria Oliveira"
        },
        "payment": {
          "method": "CREDIT_CARD",
          "status": "PAID",
          "installments": 1,
          "amount": 27730,
          "interest_amount": 0,
          "discount_amount": 1970,
          "fee": 1386,
          "amount_refunded": 0,
          "refunded_at": null,
          "decline_code": null,
          "decline_message": null,
          "card": {
            "brand": "MASTERCARD",
            "last4": "4242"
          }
        },
        "items": [
          {
            "product_id": "prod_3n7p1r5t9w2y4a6c8e0g1j",
            "name": "Curso Completo de Fotografia",
            "quantity": 1,
            "unit_price": 19700,
            "sub_total": 19700,
            "currency": "BRL",
            "offer_id": "prod_offer_5d1f3h7k9m2p4r6t8v0x2z",
            "plan_id": null,
            "order_bump_id": null
          },
          {
            "product_id": "prod_6b8d0f2h4k6m8p0r2t4v6x",
            "name": "Pacote de Presets",
            "quantity": 1,
            "unit_price": 10000,
            "sub_total": 10000,
            "currency": "BRL",
            "offer_id": null,
            "plan_id": null,
            "order_bump_id": "ob_2c4e6g8j0l2n4q6s8u0w2y"
          }
        ],
        "offer": {
          "id": "prod_offer_5d1f3h7k9m2p4r6t8v0x2z",
          "name": "Oferta de lançamento"
        },
        "promocode": {
          "code": "BEMVINDO10",
          "description": "10% de desconto no curso",
          "amount": -1970
        },
        "utm": {
          "utm_source": "instagram",
          "utm_medium": "social",
          "utm_campaign": "lancamento-outubro",
          "utm_term": null,
          "utm_content": "stories"
        },
        "tracking": {
          "sck": "parceiro-123",
          "src": "bio"
        },
        "navigator": {
          "user_agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 18_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 Instagram 350.0.0",
          "referer": "https://www.instagram.com/",
          "device": "Mobile",
          "browser": "Instagram",
          "origin": "instagram.com"
        },
        "metadata": {}
      }
    ],
    "has_more": true,
    "next_cursor": "eyJ2IjoxLCJyIjoib3JkZXJzIiwicyI6ImNyZWF0ZWRfYXRfZGVzYyJ9.k3X9vQ2mT7bR1wL5yN8pZg"
  }
  ```
</ResponseExample>


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