Enviando requisições com curl e Postman

As duas ferramentas que você vai usar todo dia, e quando escolher cada uma.

Até agora você enviou requisições pelo navegador e pelos botões Enviar destas páginas. Isso funciona para GETs simples e mais nada. Para escolher o método, definir cabeçalhos ou enviar um corpo, você precisa de um cliente de verdade. Quase todo mundo que testa APIs acaba usando dois: o curl na linha de comando e um cliente gráfico como o Postman. Esta lição cobre o suficiente de cada um para você seguir o resto do tutorial.

curl

O curl é um programa de linha de comando que envia uma requisição e imprime a resposta. Ele já vem instalado no macOS, na maioria dos sistemas Linux e no Windows 10 e 11. Confira com curl --version. Ele também é o formato que os desenvolvedores usam para compartilhar requisições: documentações de API, as ferramentas de desenvolvedor do navegador e o Postman conseguem mostrar ou exportar uma requisição como comando curl, então você vai precisar lê-los mesmo que prefira outra ferramenta.

Sem opções, o curl imprime só o corpo. Adicione -i para incluir a linha de status e os cabeçalhos de resposta, o que você quase sempre quer ao testar:

Terminal
curl -i https://api.testingapis.com/api/health
Saída
HTTP/1.1 200 OK
content-type: application/json; charset=utf-8
date: Sun, 11 Oct 2026 11:47:45 GMT
server: Kestrel
x-powered-by: TestingAPIs
transfer-encoding: chunked

{"status":"healthy","uptimeSeconds":76890,"timestamp":"2026-10-11T11:47:46Z"}

Para mais detalhes, -v (verbose) também imprime a requisição que o curl enviou, marcada com >, e os cabeçalhos de resposta, marcados com <. As linhas que começam com * descrevem a conexão. Use quando uma requisição não se comportar como você espera e você quiser ver exatamente o que passou pelo fio.

Terminal
curl -v https://api.testingapis.com/api/health
Saída (cortada)
* Host api.testingapis.com:443 was resolved.
* IPv4: 135.13.233.203
* Established connection to api.testingapis.com (135.13.233.203 port 443)
* using HTTP/1.x
> GET /api/health HTTP/1.1
> Host: api.testingapis.com
> User-Agent: curl/8.18.0
> Accept: */*
>
* Request completely sent off
< HTTP/1.1 200 OK
< content-type: application/json; charset=utf-8
< date: Sun, 11 Oct 2026 11:49:47 GMT
< transfer-encoding: chunked
...

O curl adicionou três cabeçalhos que você não pediu: Host, User-Agent e Accept. Todo cliente adiciona alguns padrões, e cada cliente adiciona outros. Quando a mesma requisição funciona no Postman e falha no curl, um cabeçalho padrão muitas vezes é o motivo.

Método, cabeçalhos e corpo

Três opções cobrem a maioria das requisições. -X define o método. -H adiciona um cabeçalho e pode ser repetido. -d envia um corpo. Isto envia um POST com corpo JSON para um endpoint que devolve o que recebeu:

Terminal
curl -X POST https://api.testingapis.com/api/methods/post \
  -H "Content-Type: application/json" \
  -d '{"name":"Asha","role":"tester"}'
Saída
{"method":"POST","message":"POST request received","path":"/api/methods/post","query":{},"contentType":"application/json","bodyLength":31,"bodyTruncated":false,"body":"{\"name\":\"Asha\",\"role\":\"tester\"}","timestamp":"2026-09-30T18:31:16Z"}

A barra invertida no fim de cada linha deixa o comando continuar na linha seguinte no bash e no zsh. O corpo fica entre aspas simples para o shell não mexer nas aspas duplas de dentro. Se você esquecer o cabeçalho Content-Type, o curl envia application/x-www-form-urlencoded, porque o -d foi feito para formulários HTML, e muitas APIs vão recusar o corpo.

O curl 7.82 e posteriores têm um atalho, --json, que envia o corpo, define Content-Type: application/json e Accept: application/json, e troca o método para POST. Este cria uma tarefa de verdade:

Terminal
curl --json '{"title":"Learn curl","completed":false,"userId":1}' \
  https://api.testingapis.com/api/Todos
Saída
{"message":"Todo created successfully","data":{"id":31,"userId":1,"title":"Learn curl","completed":false,"priority":"medium","dueDate":""}}

O ID que você receber será diferente, porque outras pessoas também criam tarefas. Para PUT ou PATCH, adicione -X PUT ou -X PATCH junto com --json.

Tempos e scripts

-w imprime valores que o curl mediu, depois da resposta. Junto com -s (silencioso, sem barra de progresso) e -o /dev/null (descarta o corpo), ele dá um resumo numa linha:

Terminal
curl -s -o /dev/null \
  -w "status %{http_code}  total %{time_total}s  size %{size_download} bytes\n" \
  https://api.testingapis.com/api/Products
Saída
status 200  total 0.382512s  size 5846 bytes

No Windows, use -o NUL em vez de -o /dev/null. time_total inclui a consulta de DNS, a conexão e o TLS, então a primeira requisição costuma ser mais lenta que as seguintes. A lição de desempenho destrincha esse número.

curl no Windows

O Windows precisa de uma seção só dele, porque o mesmo comando pode se comportar de três jeitos dependendo do shell.

No Windows PowerShell 5.1 (a versão que vem com o Windows), curl não é o curl. É um alias para Invoke-WebRequest, um comando do PowerShell com outras opções, então curl -i falha com um erro confuso. Digite curl.exe para rodar o programa de verdade. O PowerShell 7 removeu o alias, mas digitar curl.exe funciona nos dois, então é um bom hábito.

As aspas são o segundo problema. O Windows PowerShell 5.1 remove as aspas duplas de dentro dos argumentos ao passá-los para programas como o curl.exe. O comando abaixo parece certo, e o servidor recebe um JSON quebrado:

PowerShell 5.1
PS> curl.exe -s -X POST https://api.testingapis.com/api/methods/post -H "Content-Type: application/json" -d '{"name":"Asha"}'
{"method":"POST", ... "bodyLength":11, ... "body":"{name:Asha}", ...}

O corpo chegou como {name:Asha}, que não é JSON. O PowerShell 7.3 e posteriores passam as aspas corretamente. Em versões mais antigas, a solução menos dolorosa é colocar o corpo num arquivo e apontar o curl para ele com @. As aspas em volta de "@body.json" impedem o PowerShell de tratar o @ como sintaxe própria.

PowerShell
# body.json contains {"name":"Asha","role":"tester"}
curl.exe -s --json "@body.json" https://api.testingapis.com/api/methods/post

No antigo Prompt de Comando (cmd.exe), aspas simples não significam nada, então envolva o corpo em aspas duplas e escape as de dentro com barra invertida. O caractere de continuação de linha é ^ em vez da barra invertida:

Prompt de Comando
curl -X POST https://api.testingapis.com/api/methods/post ^
  -H "Content-Type: application/json" ^
  -d "{\"name\":\"Asha\",\"role\":\"tester\"}"

Postman e outros clientes gráficos

Um cliente gráfico faz o mesmo trabalho que o curl com um formulário em vez de um comando: você escolhe o método numa lista, digita a URL, preenche cabeçalhos e corpo em abas e clica em Send. A resposta aparece embaixo, formatada, com o status, o tempo e o tamanho. O Postman é o mais usado. Insomnia e Bruno funcionam do mesmo jeito, e o Bruno guarda tudo como arquivos de texto, o que algumas equipes preferem porque as requisições podem ficar no mesmo repositório Git que o código. As ideias abaixo valem para todos, com os nomes do Postman.

Coleções

Uma coleção é um grupo salvo de requisições, geralmente uma por API, com pastas dentro. É o motivo para escolher um cliente gráfico em vez do curl num projeto em que você trabalha por meses. Você monta as requisições uma vez e compartilha a coleção com a equipe.

Você não precisa montá-la à mão. Esta API publica um documento OpenAPI, uma descrição legível por máquina de cada endpoint, em https://api.testingapis.com/openapi/v1.jsonentre para ver. No Postman, escolha Import, cole essa URL e ele cria uma coleção com uma requisição para cada endpoint. A maioria das APIs que você testar no trabalho terá um arquivo parecido, e é o jeito mais rápido de começar com uma que você não conhece.

Ambientes e variáveis

Projetos reais rodam a mesma API em vários lugares: o notebook de um desenvolvedor, um servidor de testes, staging, produção. As requisições são as mesmas, a não ser pela URL base e pelas credenciais. O Postman resolve isso com ambientes. Crie um chamado "testingapis" com uma variável baseUrl valendo https://api.testingapis.com e escreva as URLs das requisições como {{baseUrl}}/api/Products/1. Trocar de ambiente troca todas as requisições de uma vez. Coloque os tokens em variáveis também, para não copiá-los em dezenas de requisições.

Testes no Postman

Cada requisição tem uma aba Tests (chamada Scripts, com uma seção post-response, nas versões mais novas) onde você pode escrever JavaScript que roda quando a resposta chega. Para GET {{baseUrl}}/api/Products/1:

Teste do Postman
pm.test("status is 200", function () {
  pm.response.to.have.status(200);
});

pm.test("product 1 has a price", function () {
  const product = pm.response.json();
  pm.expect(product.id).to.eql(1);
  pm.expect(product.price).to.be.a("number");
});

Os resultados aparecem numa aba Test Results ao lado da resposta. Depois, o Collection Runner pode rodar todas as requisições de uma coleção e mostrar quais verificações falharam. É um primeiro passo suave rumo à automação. A lição de automação trata de escrever testes como código comum, o que escala melhor quando você passa de algumas dezenas.

Qual usar

Os dois, para trabalhos diferentes.

SituaçãoMelhor escolha
Conferir uma coisa rapidinho, ou reproduzir um relatório de bugcurl
Compartilhar uma requisição exata num ticket ou chatcurl (qualquer pessoa pode colar e rodar)
Explorar uma API que você ainda não conheceCliente gráfico com a importação de OpenAPI
Corpos JSON longos que você edita várias vezesCliente gráfico
Alternar entre servidores de teste e de stagingAmbientes do cliente gráfico
Rodar dentro de um script ou num servidor de buildcurl, ou testes escritos em código
Ver cabeçalhos crus e detalhes da conexãocurl -v

Mais uma opção, só para esta API: cada página de endpoint na referência da API tem um formulário para enviar a requisição e mostra um comando curl pronto para copiar. Muitas vezes é o jeito mais rápido de experimentar um endpoint antes de salvá-lo em algum lugar.

  • Quando um relatório de bug incluir uma requisição, anexe-a como comando curl. O desenvolvedor pode rodá-la sem importar nada, e não há dúvida sobre quais cabeçalhos foram enviados.
  • O Postman converte nos dois sentidos. Cole um comando curl na janela Import para obter uma requisição, ou use o botão Code de uma requisição para obter o curl.

Exercício

Faça isto com o curl e depois repita num cliente gráfico.

  • Envie GET /api/echo/headers e compare os cabeçalhos que o curl envia com os que o seu cliente gráfico envia. Quais cabeçalhos cada ferramenta adicionou por conta própria?
  • Crie uma tarefa com POST /api/Todos e depois busque-a com GET /api/Todos/ seguido do ID da resposta.
  • Envie o mesmo POST sem o cabeçalho Content-Type. Que status e corpo voltam?
  • Use -w para medir /api/Products e /api/Products?delay=2. O parâmetro delay faz o servidor esperar, então a segunda deve levar uns dois segundos a mais.

No seu cliente gráfico, crie um ambiente com uma variável baseUrl e escreva um teste que falhe de propósito, para saber como é uma falha antes de confiar numa aprovação.

Pratique e vá além