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

# Exemplos de código

> Snippets reutilizáveis da API da Nuvia em cURL, JavaScript, Python, PHP e Go

Padrões de uso prontos para copiar e adaptar, nas linguagens mais comuns. Para a lista completa de
endpoints, use a [Referência da API](/api-reference); para obter uma chave, veja o
[Guia de API Key](/guia-api-key).

Todas as chamadas usam a base `https://api.nuvia.ai` com o prefixo `/v1` e o header
`Authorization: Bearer <sua-api-key>` — veja [Autenticação](/autenticacao).

## Configuração

Guarde a chave em uma variável de ambiente (`NUVIA_API_KEY`) — nunca no código.

<CodeGroup>
  ```bash cURL theme={null}
  export NUVIA_API_KEY="sua-api-key"
  # base: https://api.nuvia.ai/v1
  ```

  ```javascript JavaScript theme={null}
  const BASE = "https://api.nuvia.ai/v1";
  const KEY = process.env.NUVIA_API_KEY;
  const headers = { Authorization: `Bearer ${KEY}` };
  ```

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

  BASE = "https://api.nuvia.ai/v1"
  HEADERS = {"Authorization": f"Bearer {os.environ['NUVIA_API_KEY']}"}
  ```

  ```php PHP theme={null}
  <?php
  $base = "https://api.nuvia.ai/v1";
  $key = getenv("NUVIA_API_KEY");
  $authHeader = "Authorization: Bearer {$key}";
  ```

  ```go Go theme={null}
  package main

  import "os"

  const base = "https://api.nuvia.ai/v1"

  var key = os.Getenv("NUVIA_API_KEY")
  ```
</CodeGroup>

## Requisição autenticada (GET)

Lista os agentes da empresa (`GET /v1/agents`, escopo `agents:read`).

<CodeGroup>
  ```bash cURL theme={null}
  curl "https://api.nuvia.ai/v1/agents" \
    -H "Authorization: Bearer $NUVIA_API_KEY"
  ```

  ```javascript JavaScript theme={null}
  const res = await fetch("https://api.nuvia.ai/v1/agents", {
    headers: { Authorization: `Bearer ${process.env.NUVIA_API_KEY}` },
  });
  const body = await res.json();
  ```

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

  res = requests.get(
      "https://api.nuvia.ai/v1/agents",
      headers={"Authorization": f"Bearer {os.environ['NUVIA_API_KEY']}"},
  )
  body = res.json()
  ```

  ```php PHP theme={null}
  <?php
  $ch = curl_init("https://api.nuvia.ai/v1/agents");
  curl_setopt_array($ch, [
      CURLOPT_RETURNTRANSFER => true,
      CURLOPT_HTTPHEADER => ["Authorization: Bearer " . getenv("NUVIA_API_KEY")],
  ]);
  $body = json_decode(curl_exec($ch), true);
  curl_close($ch);
  ```

  ```go Go theme={null}
  package main

  import (
  	"encoding/json"
  	"net/http"
  	"os"
  )

  func main() {
  	req, _ := http.NewRequest("GET", "https://api.nuvia.ai/v1/agents", nil)
  	req.Header.Set("Authorization", "Bearer "+os.Getenv("NUVIA_API_KEY"))

  	res, err := http.DefaultClient.Do(req)
  	if err != nil {
  		panic(err)
  	}
  	defer res.Body.Close()

  	var body map[string]any
  	json.NewDecoder(res.Body).Decode(&body)
  }
  ```
</CodeGroup>

## POST com corpo JSON

Cria um contato (`POST /v1/contacts`, escopo `contacts:create`).

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST "https://api.nuvia.ai/v1/contacts" \
    -H "Authorization: Bearer $NUVIA_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{ "firstname": "Maria", "lastname": "Silva", "phone": "+5511999999999", "email": "maria@empresa.com" }'
  ```

  ```javascript JavaScript theme={null}
  const res = await fetch("https://api.nuvia.ai/v1/contacts", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.NUVIA_API_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      firstname: "Maria",
      lastname: "Silva",
      phone: "+5511999999999",
      email: "maria@empresa.com",
    }),
  });
  const contact = await res.json();
  ```

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

  res = requests.post(
      "https://api.nuvia.ai/v1/contacts",
      headers={"Authorization": f"Bearer {os.environ['NUVIA_API_KEY']}"},
      json={
          "firstname": "Maria",
          "lastname": "Silva",
          "phone": "+5511999999999",
          "email": "maria@empresa.com",
      },
  )
  contact = res.json()
  ```

  ```php PHP theme={null}
  <?php
  $payload = json_encode([
      "firstname" => "Maria",
      "lastname" => "Silva",
      "phone" => "+5511999999999",
      "email" => "maria@empresa.com",
  ]);

  $ch = curl_init("https://api.nuvia.ai/v1/contacts");
  curl_setopt_array($ch, [
      CURLOPT_RETURNTRANSFER => true,
      CURLOPT_POST => true,
      CURLOPT_POSTFIELDS => $payload,
      CURLOPT_HTTPHEADER => [
          "Authorization: Bearer " . getenv("NUVIA_API_KEY"),
          "Content-Type: application/json",
      ],
  ]);
  $contact = json_decode(curl_exec($ch), true);
  curl_close($ch);
  ```

  ```go Go theme={null}
  package main

  import (
  	"bytes"
  	"encoding/json"
  	"net/http"
  	"os"
  )

  func main() {
  	payload, _ := json.Marshal(map[string]string{
  		"firstname": "Maria",
  		"lastname":  "Silva",
  		"phone":     "+5511999999999",
  		"email":     "maria@empresa.com",
  	})

  	req, _ := http.NewRequest("POST", "https://api.nuvia.ai/v1/contacts", bytes.NewReader(payload))
  	req.Header.Set("Authorization", "Bearer "+os.Getenv("NUVIA_API_KEY"))
  	req.Header.Set("Content-Type", "application/json")

  	res, err := http.DefaultClient.Do(req)
  	if err != nil {
  		panic(err)
  	}
  	defer res.Body.Close()
  }
  ```
</CodeGroup>

## Paginação

Endpoints de listagem retornam `{ data, meta }`, com `meta` contendo `page`, `rowsPerPage`,
`totalCount`, `hasNextPage` e `hasPreviousPage`. Use os query params `page` (começa em 1) e
`rowsPerPage`, e itere enquanto `meta.hasNextPage` for `true`.

<CodeGroup>
  ```bash cURL theme={null}
  page=1
  while : ; do
    resp=$(curl -s "https://api.nuvia.ai/v1/contacts?page=$page&rowsPerPage=50" \
      -H "Authorization: Bearer $NUVIA_API_KEY")
    echo "$resp" | jq '.data[]'
    [ "$(echo "$resp" | jq -r '.meta.hasNextPage')" = "true" ] || break
    page=$((page + 1))
  done
  ```

  ```javascript JavaScript theme={null}
  async function listAllContacts() {
    const all = [];
    let page = 1;
    while (true) {
      const res = await fetch(
        `https://api.nuvia.ai/v1/contacts?page=${page}&rowsPerPage=50`,
        { headers: { Authorization: `Bearer ${process.env.NUVIA_API_KEY}` } },
      );
      const { data, meta } = await res.json();
      all.push(...data);
      if (!meta.hasNextPage) break;
      page++;
    }
    return all;
  }
  ```

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

  def list_all_contacts():
      headers = {"Authorization": f"Bearer {os.environ['NUVIA_API_KEY']}"}
      all_items, page = [], 1
      while True:
          res = requests.get(
              "https://api.nuvia.ai/v1/contacts",
              headers=headers,
              params={"page": page, "rowsPerPage": 50},
          )
          body = res.json()
          all_items += body["data"]
          if not body["meta"]["hasNextPage"]:
              break
          page += 1
      return all_items
  ```

  ```php PHP theme={null}
  <?php
  function listAllContacts(): array {
      $all = [];
      $page = 1;
      do {
          $url = "https://api.nuvia.ai/v1/contacts?page={$page}&rowsPerPage=50";
          $ch = curl_init($url);
          curl_setopt_array($ch, [
              CURLOPT_RETURNTRANSFER => true,
              CURLOPT_HTTPHEADER => ["Authorization: Bearer " . getenv("NUVIA_API_KEY")],
          ]);
          $body = json_decode(curl_exec($ch), true);
          curl_close($ch);
          $all = array_merge($all, $body["data"]);
          $page++;
      } while ($body["meta"]["hasNextPage"]);
      return $all;
  }
  ```

  ```go Go theme={null}
  package main

  import (
  	"encoding/json"
  	"fmt"
  	"net/http"
  	"os"
  )

  type page struct {
  	Data []map[string]any `json:"data"`
  	Meta struct {
  		HasNextPage bool `json:"hasNextPage"`
  	} `json:"meta"`
  }

  func listAllContacts() ([]map[string]any, error) {
  	var all []map[string]any
  	for p := 1; ; p++ {
  		url := fmt.Sprintf("https://api.nuvia.ai/v1/contacts?page=%d&rowsPerPage=50", p)
  		req, _ := http.NewRequest("GET", url, nil)
  		req.Header.Set("Authorization", "Bearer "+os.Getenv("NUVIA_API_KEY"))

  		res, err := http.DefaultClient.Do(req)
  		if err != nil {
  			return nil, err
  		}
  		var body page
  		json.NewDecoder(res.Body).Decode(&body)
  		res.Body.Close()

  		all = append(all, body.Data...)
  		if !body.Meta.HasNextPage {
  			return all, nil
  		}
  	}
  }
  ```
</CodeGroup>

## Tratamento de erros

Cheque o código de status. Erros de autenticação retornam `{ statusCode, message, error }`
(veja [Autenticação](/autenticacao)): `401` (token inválido/expirado/revogado) e `403` (falta escopo).

<CodeGroup>
  ```bash cURL theme={null}
  code=$(curl -s -o resp.json -w "%{http_code}" "https://api.nuvia.ai/v1/agents" \
    -H "Authorization: Bearer $NUVIA_API_KEY")
  if [ "$code" -ge 400 ]; then
    echo "Erro $code:"; cat resp.json
  fi
  ```

  ```javascript JavaScript theme={null}
  const res = await fetch("https://api.nuvia.ai/v1/agents", {
    headers: { Authorization: `Bearer ${process.env.NUVIA_API_KEY}` },
  });
  if (!res.ok) {
    const err = await res.json();
    throw new Error(`${res.status}: ${err.message}`);
  }
  ```

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

  res = requests.get(
      "https://api.nuvia.ai/v1/agents",
      headers={"Authorization": f"Bearer {os.environ['NUVIA_API_KEY']}"},
  )
  if not res.ok:
      err = res.json()
      raise RuntimeError(f"{res.status_code}: {err.get('message')}")
  ```

  ```php PHP theme={null}
  <?php
  $ch = curl_init("https://api.nuvia.ai/v1/agents");
  curl_setopt_array($ch, [
      CURLOPT_RETURNTRANSFER => true,
      CURLOPT_HTTPHEADER => ["Authorization: Bearer " . getenv("NUVIA_API_KEY")],
  ]);
  $raw = curl_exec($ch);
  $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
  curl_close($ch);

  if ($code >= 400) {
      $err = json_decode($raw, true);
      throw new RuntimeException("{$code}: " . ($err["message"] ?? "erro"));
  }
  ```

  ```go Go theme={null}
  package main

  import (
  	"encoding/json"
  	"fmt"
  	"net/http"
  	"os"
  )

  func fetchAgents() error {
  	req, _ := http.NewRequest("GET", "https://api.nuvia.ai/v1/agents", nil)
  	req.Header.Set("Authorization", "Bearer "+os.Getenv("NUVIA_API_KEY"))

  	res, err := http.DefaultClient.Do(req)
  	if err != nil {
  		return err
  	}
  	defer res.Body.Close()

  	if res.StatusCode >= 400 {
  		var e struct {
  			Message string `json:"message"`
  		}
  		json.NewDecoder(res.Body).Decode(&e)
  		return fmt.Errorf("%d: %s", res.StatusCode, e.Message)
  	}
  	return nil
  }
  ```
</CodeGroup>

## Retry com backoff em `429`

Alguns fluxos respondem `429 Too Many Requests`. As respostas **não** incluem headers de rate limit
(nem `Retry-After`) — veja [Rate limits](/guias/rate-limits) —, então use um backoff exponencial
próprio.

<CodeGroup>
  ```bash cURL theme={null}
  url="https://api.nuvia.ai/v1/agents"
  for attempt in 1 2 3 4 5; do
    code=$(curl -s -o /dev/null -w "%{http_code}" "$url" \
      -H "Authorization: Bearer $NUVIA_API_KEY")
    [ "$code" != "429" ] && break
    sleep $((2 ** (attempt - 1)))   # 1s, 2s, 4s, 8s...
  done
  ```

  ```javascript JavaScript theme={null}
  async function withRetry(fn, max = 5) {
    for (let attempt = 0; attempt < max; attempt++) {
      const res = await fn();
      if (res.status !== 429) return res;
      await new Promise((r) => setTimeout(r, 2 ** attempt * 1000));
    }
    throw new Error("Limite de tentativas atingido (429)");
  }

  const res = await withRetry(() =>
    fetch("https://api.nuvia.ai/v1/agents", {
      headers: { Authorization: `Bearer ${process.env.NUVIA_API_KEY}` },
    }),
  );
  ```

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

  def with_retry(make_request, max_attempts=5):
      for attempt in range(max_attempts):
          res = make_request()
          if res.status_code != 429:
              return res
          time.sleep(2 ** attempt)  # 1s, 2s, 4s, 8s...
      raise RuntimeError("Limite de tentativas atingido (429)")

  headers = {"Authorization": f"Bearer {os.environ['NUVIA_API_KEY']}"}
  res = with_retry(lambda: requests.get("https://api.nuvia.ai/v1/agents", headers=headers))
  ```

  ```php PHP theme={null}
  <?php
  function withRetry(callable $makeRequest, int $max = 5) {
      for ($attempt = 0; $attempt < $max; $attempt++) {
          [$body, $code] = $makeRequest();
          if ($code !== 429) {
              return $body;
          }
          sleep(2 ** $attempt); // 1s, 2s, 4s, 8s...
      }
      throw new RuntimeException("Limite de tentativas atingido (429)");
  }

  // closure que faz a requisição e retorna [corpo, código HTTP]
  $makeRequest = function (): array {
      $ch = curl_init("https://api.nuvia.ai/v1/agents");
      curl_setopt_array($ch, [
          CURLOPT_RETURNTRANSFER => true,
          CURLOPT_HTTPHEADER => ["Authorization: Bearer " . getenv("NUVIA_API_KEY")],
      ]);
      $body = curl_exec($ch);
      $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
      curl_close($ch);
      return [$body, $code];
  };

  $body = withRetry($makeRequest);
  ```

  ```go Go theme={null}
  package main

  import (
  	"net/http"
  	"time"
  )

  func withRetry(makeRequest func() (*http.Response, error), max int) (*http.Response, error) {
  	var res *http.Response
  	var err error
  	for attempt := 0; attempt < max; attempt++ {
  		res, err = makeRequest()
  		if err != nil {
  			return nil, err
  		}
  		if res.StatusCode != http.StatusTooManyRequests {
  			return res, nil
  		}
  		res.Body.Close()
  		time.Sleep(time.Duration(1<<attempt) * time.Second) // 1s, 2s, 4s, 8s...
  	}
  	return res, nil
  }
  ```
</CodeGroup>

<Note>
  Estes snippets de retry são exemplos mínimos. Em produção, adicione **jitter** (aleatoriedade no
  tempo de espera) e um **teto de espera**, para evitar que vários clientes tentem de novo ao mesmo
  tempo (*thundering herd*).
</Note>

## Próximos passos

<CardGroup cols={2}>
  <Card title="Exemplos de integração" icon="plug" href="/guias/exemplos-integracao">
    Cenários ponta a ponta: mensagens, webhooks, campanhas e contatos.
  </Card>

  <Card title="Referência da API" icon="code" href="/api-reference">
    Todos os endpoints, parâmetros e respostas.
  </Card>
</CardGroup>
