Como enviar uma solicitação POST com curl: guia completo

Como enviar uma solicitação POST com curl: guia completo

Existem aproximadamente vinte bilhões de instalações do curl em execução em algum lugar do mundo neste exato momento. Esse número vem do criador da ferramenta, Daniel Stenberg, que a mantém praticamente sozinho. O curl está presente em roteadores, carros, satélites, smart TVs, nos servidores Linux que sustentam a maior parte da web pública e em todos os principais ambientes de execução LLM. De todos os verbos HTTP que essas instalações utilizam, o POST é o mais utilizado. Um POST com curl é a forma como a maioria dos desenvolvedores testa, depura ou se integra a uma API pela primeira vez.

O relatório State of the API 2025 da Postman indica que a adoção do REST atingiu 93%. 82% das organizações agora operam, pelo menos em parte, com foco em APIs. O método POST é o verbo utilizado sempre que se cria, envia ou transmite dados para um servidor. As cargas de trabalho de IA aceleraram ainda mais essa tendência. O tráfego de API atribuído ao uso de IA cresceu 73% em 2024 (Postman, 2024), e a documentação de todos os provedores de serviços de gestão de bibliotecas (LLM) agora começa com um trecho de código curl POST como a "primeira chamada" padrão.

Este guia descreve todos os formatos que uma requisição POST usando curl pode assumir, desde o mínimo necessário em uma linha até uma chamada funcional para uma API de pagamento em criptomoedas real. Objetivo: algo que você possa copiar e colar, não apenas ler. Seja para enviar dados a um servidor pela primeira vez ou para recriar um manipulador de webhook às 2 da manhã, os padrões abaixo abrangem tudo o que você realmente precisa.

A tabela abaixo é uma versão resumida. Trata-se de um guia de referência com as opções de linha de comando do curl mais utilizadas no envio de requisições POST. Cada opção é detalhada nas seções a seguir.

Bandeira O que faz Quando você estende a mão para ele
`-X POST`, `--request POST` Força o método de requisição HTTP para POST. Método explícito ou verbos incomuns
`-d`, `--data` Envia dados no corpo da requisição e configura o POST automaticamente. Campos de formulário, JSON embutido, cargas úteis simples
`--data-binary` Envia arquivos ou dados binários sem remover quebras de linha. Upload de arquivos, JSON grande, dados binários brutos
`--data-urlencode` Codifica o valor em URL antes de enviar. Valores com espaços ou caracteres especiais
`--json` Envia dados com `Content-Type: application/json` e `Accept: application/json`. curl 7.82.0 ou mais recente, APIs JSON
`-H`, `--header` Adiciona um cabeçalho HTTP personalizado. Tipo de conteúdo, autorização, chaves de API
`-F`, `--form` Envia dados multipart/form com campos de formulário ou arquivos. Envio de arquivos, formulários em formato HTML
`-u`, `--user` Envia credenciais de autenticação HTTP Basic. APIs legadas, autenticação simples com nome de usuário e senha.
`-i`, `--include` Inclui cabeçalhos de resposta na saída. Inspecionando respostas do servidor
`-v`, `--verbose` Imprime a solicitação e a resposta completas, incluindo os cabeçalhos. Depurando uma requisição POST com falha

Entendendo a requisição POST do curl e o método HTTP

Uma requisição POST feita com curl é uma requisição HTTP POST, enviada com o método POST, disparada a partir da linha de comando. A própria ferramenta curl descreve sua função como "transferir dados" através de mais de duas dúzias de protocolos, sendo o HTTP apenas um deles. POST significa: aqui estão alguns dados, faça algo com eles. A carga útil (payload) é enviada no corpo da requisição, nunca na URL. Essa característica é o motivo pelo qual o método POST lida com a criação de recursos, envio de formulários e qualquer coisa que envolva credenciais. O método GET armazena os dados na string de consulta, visíveis para todos os proxies e para o histórico de todos os navegadores. O método POST não.

A maioria dos tutoriais omite um detalhe pequeno, mas útil. Passe `-d` e as opções automáticas do curl para POST. O argumento explícito `-X POST`, que especifica um método de requisição personalizado, é opcional. Muitos exemplos ainda o incluem porque ler `-X POST` ao lado de um payload torna a intenção óbvia à primeira vista.

Os métodos PUT e POST são frequentemente confundidos, por isso vale a pena esclarecer alguns pontos. O método PUT substitui um recurso em um local conhecido. Já o método POST cria um novo recurso ou envia dados para serem processados em um endpoint genérico.

Solicitação POST com curl

Sintaxe básica do comando curl POST e a flag -d na prática

O comando curl POST mínimo consiste em uma única linha:

```

curl -d "username=arya&age=16" https://api.example.com/users

```

É isso aí. Requisição POST, corpo codificado em URL, sem complicações. O parâmetro `-d` cumpre tripla função: insere o conteúdo no corpo da requisição, altera o método da requisição para POST e adiciona `Content-Type: application/x-www-form-urlencoded` como cabeçalho padrão. Normalmente, eu colo a forma um pouco mais detalhada mesmo, porque a intenção POST fica mais legível em uma revisão de código.

```

curl -X POST -d "username=arya&age=16" https://api.example.com/users

```

Os mesmos bytes são transmitidos pela rede. Os mesmos argumentos de requisição. Use o que sua equipe achar mais fácil de analisar. A flag `-d` é a ferramenta principal usada para enviar dados a um servidor a partir da linha de comando e lida com noventa por cento de tudo que um desenvolvedor backend envia para o curl: chamadas de shell, testes de webhook, alvos do Makefile, etapas do GitHub Actions.

Três variantes próximas de `-d`. `--data-binary` mantém seus bytes intactos; o `-d` padrão remove quebras de linha e corrompe um payload binário. `--data-urlencode` codifica a URL em porcentagem para você: `--data-urlencode "name=I am Daniel"` chega como `name=I%20am%20Daniel`. `--data-raw` é a solução quando um valor começa com `@` e o curl não deve ler um arquivo. Múltiplas opções `-d` são combinadas com `&`. Ótimo para formulários. Nunca para JSON.

Uma última observação importante: as aspas. As aspas simples em torno da carga útil impedem que o shell interprete `$` ou barras invertidas. Se você se esquecer delas, vai passar as 2 da manhã se perguntando por que metade dos seus dados POST está faltando.

Esses detalhes são importantes porque o curl em si é um dos clientes HTTP mais testados do planeta. A retrospectiva de Stenberg, de dezembro de 2025, contabilizou oito lançamentos naquele ano. Nove CVEs, todos classificados como de baixa ou média gravidade. 2.179 casos de teste ativos, 232 deles mais de doze meses antes. O lançamento da versão 8.11.1, em dezembro de 2024, corrigiu a CVE-2024-11053 (um vazamento de credenciais no arquivo netrc e no redirecionamento). A versão estável atual, no final de abril de 2026, é a curl 8.20.0. Quem estiver usando uma versão anterior à 7.82.0 ainda não tem a opção `--json` e utiliza o padrão antigo de três opções.

Envio de dados JSON com curl usando --json ou -H

JSON será a linguagem comum das APIs REST em 2026. Existem duas maneiras de enviar uma requisição POST com curl. A escolha entre elas depende inteiramente da versão do curl instalada na máquina.

Padrão clássico de três bandeiras, funciona em todas as versões do CentOS a partir da 6:

```

curl -X POST \

-H "Content-Type: application/json" \

-d '{"title":"Tea","quantity":2}' \

https://api.example.com/orders

```

Abreviação moderna, disponível desde o curl 7.82.0 (março de 2022):

```

curl --json '{"title":"Tea","quantity":2}' https://api.example.com/orders

```

A flag `--json` faz três coisas. Define `Content-Type: application/json`. Define `Accept: application/json`. Envia o corpo da requisição. Ela também permite a composição: se você passar `--json` mais de uma vez, os payloads serão concatenados. Isso é útil ao enviar blocos JSON para um endpoint de streaming.

Para payloads JSON armazenados em um arquivo, prefixe o caminho do arquivo com `@`. O envio de dados de um arquivo torna-se o padrão quando o objeto JSON é muito grande para ser colado diretamente no texto, quando está em um sistema de controle de versão ou quando outro script o gera.

```

curl -X POST -H "Content-Type: application/json" -d @order.json https://api.example.com/orders

curl --json @order.json https://api.example.com/orders

```

O segundo padrão lê os dados de um arquivo chamado `order.json` e os envia com todos os cabeçalhos corretos. Para conteúdo JSON grande ou potencialmente binário, `--data-binary @file.json` é a opção mais segura. Ela não remove quebras de linha, não interpreta caracteres especiais e envia dados binários brutos para um endpoint que espera bytes em vez de campos de formulário. Um terceiro padrão lê os dados da entrada padrão (stdin) via `-d @-`. Útil ao redirecionar a saída de outro comando diretamente para um POST do curl.

A tabela abaixo mapeia os quatro formatos JSON comuns para um único endpoint:

Padrão Comando Quando usar
Em linha, clássico `-X POST -H "Content-Type: application/json" -d '{"k":"v"}'` Compatibilidade máxima com qualquer versão do curl.
Em linha, moderno `--json '{"k":"v"}'` curl 7.82.0 ou mais recente, sintaxe mais limpa
Do arquivo, seguro `-X POST -H "..." -d @payload.json` A carga útil é mantida sob controle de versão.
A partir de um arquivo, seguro para binários. `-X POST -H "..." --data-binary @payload.json` Arquivos grandes, cargas úteis com quebras de linha

Isso importa mais do que antes. Todos os principais provedores de LLM — OpenAI, Anthropic, Mistral, Google — abrem suas documentações de API com um exemplo de POST do curl usando exatamente esse formato. O tráfego gerado por IA adicionou 73% ao volume total de chamadas de API em 2024 (Postman). O curl agora é a referência padrão para "como faço para chamar este endpoint".

Solicitação POST com curl

Content-Type, cabeçalhos e o que o curl pressupõe.

A maioria das respostas "415 Unsupported Media Type" se resume à falta de um cabeçalho. Com `-d`, o curl silenciosamente adiciona à sua requisição o cabeçalho `Content-Type: application/x-www-form-urlencoded`. Envie um corpo JSON sem `-H "Content-Type: application/json"` ou `--json` e você receberá o erro 415. Sem aviso prévio, apenas a rejeição.

Outros metadados também acompanham o corpo da requisição: Content-Length, o cabeçalho Authorization e X-Request-Id para rastreamento. Acertar esses metadados é metade do sucesso de qualquer integração de API. O objeto JSON em si é a outra metade, mais fácil.

A opção `-H` adiciona cabeçalhos personalizados. Repita conforme necessário. Os nomes dos cabeçalhos não diferenciam maiúsculas de minúsculas; os valores, sim. A maneira mais rápida de depurar uma requisição POST mal configurada é executá-la com `-v` uma vez, ler a linha da requisição e comparar com a documentação da API. Em oito de cada dez casos, o erro aparece em segundos.

Mais duas observações. O Content-Length é definido automaticamente pelo curl com base no tamanho do corpo da requisição; raramente você precisa sobrescrevê-lo. `Accept: application/json` é o que instrui o servidor a responder em JSON em vez de HTML. Adicione outro `-H` para isso, ou use `--json`, que define o Content-Type e o Accept juntos.

Envio de dados de formulário e arquivos com curl POST -F

Para dados de formulário em formato HTML com arquivos, a opção correta é `-F`. Ela gera uma requisição `multipart/form-data`. O tipo de conteúdo é diferente do formulário codificado em URL que `-d` usa por padrão. O conceito também é diferente. Tutoriais resumidos costumam confundir os dois conceitos, o que causa erros reais.

`-F` uma vez por campo. Campo de formulário simples:

```

curl -F "name=Arya" https://api.example.com/submit

```

Envio de arquivo:

```

curl -F "file=@/caminho/para/imagem.png" https://api.example.com/upload

```

O prefixo `@` indica ao curl que ele deve ler o arquivo do disco e incluir seu conteúdo no corpo da requisição. O curl detecta automaticamente o tipo MIME a partir do nome do arquivo; você pode sobrescrevê-lo explicitamente quando necessário.

```

curl -F "[email protected];type=image/png" https://api.example.com/upload

```

Várias opções `-F` agrupam vários campos ou arquivos em uma única solicitação:

```

curl -F "title=Holiday" -F "[email protected]" -F "[email protected]" https://api.example.com/album

```

Para conteúdo de arquivo bruto sem o wrapper multipart, uma necessidade comum ao enviar um arquivo JSON ou um blob binário para um endpoint de streaming, use `--data-binary @file.bin`. Isso envia os bytes do arquivo como corpo da requisição literalmente, com o Content-Type que você definir explicitamente.

Autenticação em curl POST: básica, bearer, chaves de API

Em 2026, três formatos de autenticação abrangem praticamente todas as APIs REST. Autenticação básica (nome de usuário e senha, codificados em base64 em um cabeçalho):

```

curl -u "meuusuario:minhasenha" -X POST -d "..." https://api.example.com/login

```

Os tokens Bearer, usados pela maioria das APIs modernas, incluindo todas as credenciais emitidas pelo OAuth, são vinculados a um cabeçalho de Autorização personalizado:

```

curl -H "Authorization: Bearer $TOKEN" --json '{"q":"hello"}' https://api.example.com/query

```

As chaves de API geralmente ficam em um cabeçalho específico do serviço:

```

curl -H "X-API-Key: $PLISIO_KEY" --json @invoice.json https://api.plisio.net/api/v1/invoices/new

```

Credenciais provenientes de variáveis de ambiente ou gerenciadores de segredos, nunca digitadas diretamente no código. Por quê? O relatório "State of Secrets Sprawl 2025" da GitGuardian contabilizou 23,8 milhões de novos segredos vazados para o GitHub público durante 2024. Um aumento de 25% em relação a 2023. Mais de 90% deles permaneceram válidos por cinco dias após a exposição. Credenciais inseridas diretamente no código em scripts curl são uma das principais fontes desses vazamentos. A seção de segurança abaixo aborda o fluxo de trabalho.

Exemplo prático de POST com curl: API de pagamento Plisio

Documentos de referência sem um exemplo real são apenas teoria. O comando curl POST abaixo gera uma fatura de pagamento em criptomoedas através da API REST da Plisio. A Plisio cobra uma taxa fixa de 0,5%; processadores de cartão geralmente cobram de 2% a 4%. A Plisio suporta mais de trinta criptomoedas e oferece integrações para dezenove plataformas de e-commerce.

Por que as APIs de criptomoedas funcionam como alvos de prática. As stablecoins movimentaram aproximadamente US$ 28 trilhões em volume econômico real durante 2025. A Chainalysis estimou o crescimento em uma taxa composta de crescimento anual de 133% desde 2023. O mercado de gateways de pagamento em criptomoedas girou em torno de US$ 2 bilhões em 2025, com previsão de alcançar US$ 2,39 bilhões em 2026 (segundo a The Business Research Company). BitPay, Coinbase Commerce, Plisio: escolha qualquer um. O primeiro passo de integração com qualquer gateway moderno é quase sempre um POST via curl.

A chamada mínima para criar uma nova fatura:

```

curl -X POST https://api.plisio.net/api/v1/invoices/new \

-H "Content-Type: application/json" \

-H "Autorização: Portador $PLISIO_API_KEY" \

-d '{

"source_currency": "USD",

"source_amount": 49.99,

"order_number": "INV-1042",

"currency": "BTC",

"email": "[email protected]",

"order_name": "Annual subscription"

}'

```

Uma chamada bem-sucedida retorna HTTP 201. O corpo da resposta é um objeto JSON: um ID de fatura gerado, um `invoice_url` onde o cliente efetua o pagamento, um endereço de carteira de destino e um timestamp de expiração. Utilize o `jq` para extrair o campo desejado.

```

... | jq '.data.invoice_url'

```

Esse é o padrão completo. Troque o endpoint, troque o payload, e o formato se mantém exatamente o mesmo para uma cobrança da BitPay, um checkout da Coinbase Commerce ou uma intenção de pagamento da Stripe. Os flags não mudam; apenas o JSON.

Depurando uma requisição POST do curl: -v, --trace, erros

Uma falha no POST é um quebra-cabeça para depuração. Tentar novamente às cegas é a pior estratégia. Quatro opções na linha de comando abrangem a maior parte do que você precisa.

`-v` imprime a linha da requisição, todos os cabeçalhos da requisição e o status da resposta. Essa é a primeira opção que você deve usar. `--trace-ascii -` é mais poderosa: ela exibe toda a conversa, incluindo o corpo de um POST, na saída padrão. Use `curl -i` para inserir os cabeçalhos da resposta acima do corpo. E `-w "%{http_code}\n"` escreve apenas o código de status HTTP, útil ao criar scripts de verificação de CI em uma API.

Sobre os códigos de status que você verá com mais frequência: 400: o servidor analisou sua solicitação, mas rejeitou a carga útil. 401: cabeçalho de autenticação ausente ou inválido. 415: Content-Type incorreto. 500: o servidor apresentou uma falha ao processar sua entrada. Cada um deles elimina uma camada específica, o que representa metade da vantagem de executar `-v` na primeira falha.

Segurança do curl POST: chaves de API, segredos e vazamentos

Todas as referências ignoram esta seção. Todas as análises pós-incidente a mencionam. Dezembro de 2024: a violação de segurança do Departamento do Tesouro dos EUA foi rastreada até uma chave de API da BeyondTrust vazada. Exatamente o tipo de credencial que reside nos cabeçalhos `-H "Authorization: Bearer ..."` em scripts de produção.

A defesa é pouco glamorosa. Leia os tokens das variáveis de ambiente. Armazene-os em um gerenciador de segredos como o AWS Secrets Manager, o HashiCorp Vault ou a CLI do 1Password. Mantenha um gancho de pré-commit em execução com `gitleaks` ou `trufflehog`. Rotacione qualquer token que já tenha existido no histórico do shell. Nada disso é empolgante. Tudo funciona. Aplicar isso em cada requisição POST do curl que você enviar é o hábito mais importante que um desenvolvedor backend pode adquirir em 2026.

Alguma pergunta?

Duas formas. Upload multipart (formato de transmissão de formulário HTML): `curl -F "file=@/caminho/para/arquivo.png" https://api.example.com/upload`. Binário bruto, sem wrapper: `curl --data-binary @file.bin -H "Content-Type: application/octet-stream" https://api.example.com/raw`. O `@` é o que faz o curl ler do disco.

curl 7.82.0 (março de 2022) e versões mais recentes: `curl --json `{"key":"value"}` https://api.example.com`. Em versões anteriores, o padrão com três flags é: `curl -X POST -H "Content-Type: application/json" -d `{"key":"value"}` https://api.example.com`. O JSON já está em um arquivo? Adicione o prefixo `@`: `--json @payload.json` ou `-d @payload.json`.

Eu não diria que nenhum dos dois é "melhor". O curl se destaca em tudo que um shell supera uma GUI: chamadas pontuais, tarefas de CI, qualquer coisa que você acesse via SSH. O Postman se destaca em coleções salvas, comparação lado a lado e fluxos de trabalho em equipe. Eu mantenho ambos instalados.

Abra o terminal, cole `curl -X POST -d "field=value" https://api.example.com/endpoint`, pressione Enter. O endpoint espera JSON? Adicione `-H "Content-Type: application/json"`, ou use `--json` se estiver usando o curl 7.82.0 ou mais recente. A saída será impressa na saída padrão (stdout), pronta para ser executada com `jq`.

O método GET funciona sozinho. O método POST entra em ação assim que os parâmetros `-d`, `--data`, `--data-binary`, `--data-urlencode`, `-F` ou `--json` são inseridos no comando. Qualquer outro método (PATCH, DELETE, PROPFIND) precisa do parâmetro `-X`, pois nenhum deles possui um parâmetro de atalho.

O que você obtém com `curl -X POST` (ou qualquer flag de envio de dados) em um terminal. O verbo diz ao servidor "receba isso e faça algo". Eu o utilizo para testar um endpoint REST, reproduzir um webhook que falhou em produção ou executar uma função Lambda logo após a implantação.

Ready to Get Started?

Create an account and start accepting payments – no contracts or KYC required. Or, contact us to design a custom package for your business.

Make first step

Always know what you pay

Integrated per-transaction pricing with no hidden fees

Start your integration

Set up Plisio swiftly in just 10 minutes.