https://api.nuvia.ai com o prefixo /v1 e o header
Authorization: Bearer <sua-api-key> — veja Autenticação.
Configuração
Guarde a chave em uma variável de ambiente (NUVIA_API_KEY) — nunca no código.
export NUVIA_API_KEY="sua-api-key"
# base: https://api.nuvia.ai/v1
const BASE = "https://api.nuvia.ai/v1";
const KEY = process.env.NUVIA_API_KEY;
const headers = { Authorization: `Bearer ${KEY}` };
import os
BASE = "https://api.nuvia.ai/v1"
HEADERS = {"Authorization": f"Bearer {os.environ['NUVIA_API_KEY']}"}
<?php
$base = "https://api.nuvia.ai/v1";
$key = getenv("NUVIA_API_KEY");
$authHeader = "Authorization: Bearer {$key}";
package main
import "os"
const base = "https://api.nuvia.ai/v1"
var key = os.Getenv("NUVIA_API_KEY")
Requisição autenticada (GET)
Lista os agentes da empresa (GET /v1/agents, escopo agents:read).
curl "https://api.nuvia.ai/v1/agents" \
-H "Authorization: Bearer $NUVIA_API_KEY"
const res = await fetch("https://api.nuvia.ai/v1/agents", {
headers: { Authorization: `Bearer ${process.env.NUVIA_API_KEY}` },
});
const body = await res.json();
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
$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);
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)
}
POST com corpo JSON
Cria um contato (POST /v1/contacts, escopo contacts:create).
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" }'
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();
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
$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);
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()
}
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.
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
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;
}
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
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;
}
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
}
}
}
Tratamento de erros
Cheque o código de status. Erros de autenticação retornam{ statusCode, message, error }
(veja Autenticação): 401 (token inválido/expirado/revogado) e 403 (falta escopo).
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
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}`);
}
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
$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"));
}
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
}
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 —, então use um backoff exponencial
próprio.
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
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}` },
}),
);
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
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);
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
}
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).
Próximos passos
Exemplos de integração
Cenários ponta a ponta: mensagens, webhooks, campanhas e contatos.
Referência da API
Todos os endpoints, parâmetros e respostas.