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:
curl -i https://api.testingapis.com/api/healthHTTP/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.
curl -v https://api.testingapis.com/api/health* 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:
curl -X POST https://api.testingapis.com/api/methods/post \
-H "Content-Type: application/json" \
-d '{"name":"Asha","role":"tester"}'{"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:
curl --json '{"title":"Learn curl","completed":false,"userId":1}' \
https://api.testingapis.com/api/Todos{"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:
curl -s -o /dev/null \
-w "status %{http_code} total %{time_total}s size %{size_download} bytes\n" \
https://api.testingapis.com/api/Productsstatus 200 total 0.382512s size 5846 bytesNo 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:
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.
# body.json contains {"name":"Asha","role":"tester"}
curl.exe -s --json "@body.json" https://api.testingapis.com/api/methods/postNo 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:
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:
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ção | Melhor escolha |
|---|---|
| Conferir uma coisa rapidinho, ou reproduzir um relatório de bug | curl |
| Compartilhar uma requisição exata num ticket ou chat | curl (qualquer pessoa pode colar e rodar) |
| Explorar uma API que você ainda não conhece | Cliente gráfico com a importação de OpenAPI |
| Corpos JSON longos que você edita várias vezes | Cliente gráfico |
| Alternar entre servidores de teste e de staging | Ambientes do cliente gráfico |
| Rodar dentro de um script ou num servidor de build | curl, ou testes escritos em código |
| Ver cabeçalhos crus e detalhes da conexão | curl -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/headerse 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/Todose depois busque-a comGET /api/Todos/seguido do ID da resposta. - Envie o mesmo POST sem o cabeçalho
Content-Type. Que status e corpo voltam? - Use
-wpara medir/api/Productse/api/Products?delay=2. O parâmetrodelayfaz 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.