Как отправить POST-запрос с помощью curl: полное руководство
В настоящее время в мире запущено около двадцати миллиардов установок curl. Эта цифра предоставлена создателем инструмента, Даниэлем Стенбергом, который поддерживает его практически в одиночку. curl входит в состав маршрутизаторов, автомобилей, спутников, смарт-телевизоров, серверов Linux, на которых работает большая часть общедоступного интернета, и всех основных сред выполнения LLM. Из всех HTTP-методов, используемых этими установками, POST-запрос выполняет основную работу. POST-запрос curl — это способ, которым большинство разработчиков тестируют, отлаживают или впервые интегрируются с API.
В отчете Postman «Состояние API в 2025 году» указано, что уровень внедрения REST составляет 93%. 82% организаций сейчас работают как минимум частично по принципу «API-first». POST — это глагол, который вы используете всякий раз, когда создаете, отправляете или передаете данные на сервер. Рабочие нагрузки ИИ еще больше ускорили эту тенденцию. Трафик API, связанный с использованием ИИ, вырос на 73% в 2024 году (Postman, 2024), и документация каждого поставщика LLM теперь начинается с фрагмента кода curl POST в качестве канонического «первого вызова».
В этом справочнике описаны все возможные варианты POST-запросов, выполняемых с помощью curl, от минимального запроса в одну строку до работающего вызова к реальному API для криптовалютных платежей. Цель: получить данные, которые можно скопировать, а не просто прочитать. Независимо от того, отправляете ли вы данные на сервер впервые или перестраиваете обработчик веб-хуков в 2 часа ночи, приведенные ниже шаблоны охватывают все, что вам действительно нужно.
Приведенная ниже таблица представляет собой краткую версию. Шпаргалка по флагам и назначению параметров командной строки curl, наиболее часто используемых при отправке POST-запросов. Каждый из них подробно рассматривается в следующих разделах.
| Флаг | Что это делает | Когда вы тянетесь к нему |
|---|---|---|
| `-X POST`, `--request POST` | Принудительно устанавливает метод HTTP-запроса на POST. | Явный метод или необычные глаголы |
| `-d`, `--data` | Отправляет данные в теле запроса, автоматически устанавливает POST-запрос. | Поля форм, встроенный JSON, простые полезные данные |
| `--data-binary` | Отправляет файловые или двоичные данные без удаления символов новой строки. | Загрузка файлов, большие JSON-файлы, необработанные двоичные данные. |
| `--data-urlencode` | Перед отправкой значение кодируется в URL-формате. | Значения, содержащие пробелы или специальные символы |
| `--json` | Отправляет данные с параметрами `Content-Type: application/json` и `Accept: application/json`. | curl 7.82.0 или более поздней версии, JSON API |
| `-H`, `--header` | Добавляет пользовательский HTTP-заголовок | Content-Type, Authorization, API keys |
| `-F`, `--form` | Отправляет multipart/form-data вместе с полями формы или файлами. | Загрузка файлов, формы в формате HTML. |
| `-u`, `--user` | Отправляет учетные данные для базовой HTTP-аутентификации. | Устаревшие API, простая аутентификация по имени пользователя и паролю. |
| `-i`, `--include` | Включает заголовки ответа в выходные данные. | Анализ ответов сервера |
| `-v`, `--verbose` | Выводит полный запрос и ответ, включая заголовки. | Отладка неудачного POST-запроса |
Разбираемся в POST-запросе curl и методе HTTP.
POST-запрос curl — это HTTP POST-запрос, отправляемый методом POST из командной строки. Сам инструмент curl описывает свою задачу как «передачу данных» по более чем двум десяткам протоколов, из которых HTTP — лишь один. POST означает: вот данные, сделайте с ними что-нибудь. Полезная нагрузка помещается в тело запроса, никогда не в URL. Именно поэтому POST обрабатывает создание ресурсов, отправку форм и все, что содержит учетные данные. GET помещает данные в строку запроса, видимую каждому прокси-серверу и истории браузера. POST этого не делает.
В большинстве руководств упускается небольшая, но полезная деталь. Передавайте параметр `-d`, и curl автоматически переключается на POST. Явный параметр `-X POST`, указывающий на используемый пользовательский метод запроса, является необязательным. Во многих примерах он всё ещё присутствует, потому что наличие `-X POST` рядом с полезной нагрузкой делает намерение очевидным с первого взгляда.
Термины PUT и POST достаточно часто путают, поэтому стоит уточнить. PUT заменяет ресурс в известном месте. POST создает новый ресурс или отправляет данные для обработки в универсальной конечной точке.

Базовый синтаксис POST-запроса curl и флаг -d на практике.
Минимальный POST-запрос curl состоит из одной строки:
```
curl -d "username=arya&age=16" https://api.example.com/users
```
Вот и всё. POST-запрос, тело запроса в формате form-urlencoded, никаких сложностей. Параметр `-d` выполняет тройную функцию: он помещает полезную нагрузку в тело запроса, меняет метод запроса на POST и добавляет заголовок `Content-Type: application/x-www-form-urlencoded` в качестве заголовка по умолчанию. Я обычно всё равно вставляю более подробную форму, потому что POST-запрос лучше читается при проверке кода:
```
curl -X POST -d "username=arya&age=16" https://api.example.com/users
```
Одинаковые байты в сети. Одинаковые аргументы запроса. Используйте тот вариант, который вашей команде будет проще сканировать. Флаг `-d` — это основной инструмент для отправки данных на сервер из командной строки, и он обрабатывает девяносто процентов всего, что бэкенд-разработчик когда-либо отправляет в curl: вызовы оболочки, тесты веб-хуков, цели Makefile, шаги GitHub Actions.
Три близких аналога `-d`. `--data-binary` сохраняет целостность байтов; стандартный `-d` удаляет символы новой строки и искажает двоичные данные. `--data-urlencode` выполняет процентное кодирование: `--data-urlencode "name=I am Daniel"` преобразуется в `name=I%20am%20Daniel`. `--data-raw` — это запасной вариант, когда значение начинается с `@`, и curl не должен читать файл. Несколько флагов `-d` объединяются с помощью `&`. Подходит для форм. Никогда не подходит для JSON.
И ещё один нюанс: кавычки. Одинарные кавычки вокруг полезной нагрузки мешают оболочке интерпретировать символ `$` или обратные косые черты. Забудьте о них, и вы потратите 2 часа ночи на выяснение, почему половина ваших POST-данных отсутствует.
Эти детали важны, потому что curl сам по себе является одним из наиболее тщательно тестируемых HTTP-клиентов в мире. В обзоре Стенберга за декабрь 2025 года было зафиксировано восемь релизов за этот год. Девять уязвимостей CVE, все с низким или средним уровнем опасности. 2179 активных тестовых случаев, 232 из которых были более двенадцати месяцев назад. В релизе 8.11.1, выпущенном в декабре 2024 года, была исправлена уязвимость CVE-2024-11053 (утечка учетных данных netrc и redirect). Текущая стабильная версия по состоянию на конец апреля 2026 года — curl 8.20.0. У всех, кто использует версии ниже 7.82.0, по-прежнему отсутствует флаг `--json`, и они возвращаются к старой схеме с тремя флагами.
Отправка данных в формате JSON с помощью curl с использованием параметров --json или -H
JSON — это универсальный язык REST API в 2026 году. Существует два способа отправить его методом POST с помощью curl. Какой из них использовать, полностью зависит от версии curl, установленной на вашем компьютере.
Классическая схема с тремя флагами, работает везде, начиная с CentOS 6:
```
curl -X POST \
-H "Content-Type: application/json" \
-d '{"title":"Tea","quantity":2}' \
https://api.example.com/orders
```
Современная стенография, доступная с версии curl 7.82.0 (март 2022 г.):
```
curl --json '{"title":"Tea","quantity":2}' https://api.example.com/orders
```
Флаг `--json` выполняет три действия. Устанавливает `Content-Type: application/json`. Устанавливает `Accept: application/json`. Отправляет тело запроса. Он также используется для компоновки: если передать `--json` несколько раз, полезные данные объединятся. Полезно при передаче фрагментов JSON в потоковую конечную точку.
Для JSON-данных, хранящихся в файле, добавьте префикс `@` к пути к файлу. Отправка данных из файла становится стандартным шаблоном, когда JSON-объект становится слишком большим для вставки непосредственно в текст, или когда он находится в системе контроля версий, или когда его генерирует другой скрипт:
```
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
```
Второй вариант считывает данные из файла с именем `order.json` и отправляет их со всеми необходимыми заголовками. Для больших или потенциально двоичных JSON-данных более безопасным вариантом является `--data-binary @file.json`. Он не удаляет символы новой строки, не интерпретирует специальные символы и отправляет необработанные двоичные данные на конечную точку, которая ожидает байты, а не поля формы. Третий вариант считывает данные из стандартного ввода с помощью `-d @-`. Удобно при перенаправлении вывода другой команды непосредственно в POST-запрос curl.
В таблице ниже приведено сопоставление четырех распространенных типов JSON-структур с одной конечной точкой:
| Шаблон | Командование | Когда использовать |
|---|---|---|
| Встроенный, классический | `-X POST -H "Content-Type: application/json" -d '{"k":"v"}'` | Максимальная совместимость с любой версией curl. |
| Встроенный, современный | `--json '{"k":"v"}'` | curl 7.82.0 или более поздней версии, самый чистый синтаксис. |
| Из файла, безопасно | `-X POST -H "..." -d @payload.json` | Полезная нагрузка хранится в системе контроля версий. |
| Из файла, бинарный безопасный | `-X POST -H "..." --data-binary @payload.json` | Большие файлы, содержащие символы новой строки. |
Это имеет большее значение, чем раньше. Каждый крупный поставщик LLM-решений — OpenAI, Anthropic, Mistral, Google — открывает документацию по своим API примером POST-запроса curl, используя именно такую структуру. Трафик, созданный с помощью ИИ, увеличил общий объем вызовов API на 73% в 2024 году (Postman). curl теперь является каноническим справочником по вопросу «как мне вызвать эту конечную точку».

Content-Type, заголовки и предположения curl.
Большинство ответов "415 Unsupported Media Type" сводятся к отсутствию одного заголовка. С параметром `-d` curl незаметно добавляет в ваш запрос `Content-Type: application/x-www-form-urlencoded`. Отправьте тело запроса в формате JSON без `-H "Content-Type: application/json"` или `--json`, и вы получите ответ 415. Никакого предупреждения, только отказ.
Вместе с телом запроса передается и другая метаданная: Content-Length, заголовок Authorization, X-Request-Id для трассировки. Правильное написание этих метаданных — половина любой интеграции API. Сам JSON-объект — это самая простая часть.
`-H` добавляет пользовательские заголовки. Повторяйте по мере необходимости. Имена заголовков нечувствительны к регистру; значения — нет. Самый быстрый способ отладки неправильно настроенного POST-запроса: запустите его с `-v` один раз, прочтите строку запроса и сравните с документацией API. В восьми случаях из десяти ошибка обнаруживается за считанные секунды.
Ещё два замечания. Параметр Content-Length автоматически устанавливается curl на основе размера тела запроса; его редко можно изменить. Параметр `Accept: application/json` указывает серверу отвечать в формате JSON, а не HTML. Добавьте для этого ещё один `-H` или используйте `--json`, который устанавливает Content-Type и Accept одновременно.
Загрузка данных форм и файлов с помощью curl POST -F
Для данных форм в формате HTML с файлами правильный флаг — `-F`. Он создает запрос `multipart/form-data`. Это другой тип содержимого, отличный от типа, используемого по умолчанию для `-d`, который используется для кодировки URL формы. Это другая модель мышления. В одноабзацных руководствах эти два понятия часто путают, что приводит к реальным ошибкам.
`-F` один раз для каждого поля. Поле в простой форме:
```
curl -F "name=Arya" https://api.example.com/submit
```
Загрузка файла:
```
curl -F "file=@/path/to/image.png" https://api.example.com/upload
```
Префикс `@` указывает curl прочитать файл с диска и включить его содержимое в тело запроса. curl автоматически определяет MIME-тип по имени файла; при необходимости его следует явно переопределить:
```
curl -F "[email protected];type=image/png" https://api.example.com/upload
```
Использование нескольких флагов `-F` позволяет объединить несколько полей или файлов в один запрос:
```
curl -F "title=Holiday" -F "[email protected]" -F "[email protected]" https://api.example.com/album
```
Для отправки необработанного содержимого файла без обертки multipart, что часто требуется при отправке JSON-файла или бинарного объекта в потоковую конечную точку, используйте вместо этого `--data-binary @file.bin`. Это отправит байты файла в качестве тела запроса без изменений, с тем Content-Type, который вы явно указали.
Аутентификация в curl POST: basic, bearer, API keys
К 2026 году почти все REST API будут использовать три типа аутентификации. Базовая аутентификация (имя пользователя плюс пароль, закодированные в заголовок с помощью base64):
```
curl -u "myuser:mypass" -X POST -d "..." https://api.example.com/login
```
Токены Bearer, используемые большинством современных API, включая все учетные данные, выдаваемые через OAuth, основаны на пользовательском заголовке Authorization:
```
curl -H "Авторизация: Bearer $TOKEN" --json '{"q":"hello"}' https://api.example.com/query
```
Ключи API обычно находятся в заголовке, специфичном для конкретного сервиса:
```
curl -H "X-API-Key: $PLISIO_KEY" --json @invoice.json https://api.plisio.net/api/v1/invoices/new
```
Учетные данные из переменной окружения или менеджера секретов, никогда не вводимые непосредственно в код. Почему? В отчете GitGuardian «State of Secrets Sprawl 2025» зафиксировано 23,8 миллиона новых утечек секретов в публичный GitHub в течение 2024 года. Это на 25% больше, чем в 2023 году. Более 90% из них оставались действительными в течение пяти дней после утечки. Встроенные учетные данные в скриптах curl являются одним из основных источников таких утечек. В разделе «Безопасность» ниже описан рабочий процесс.
Реальный пример использования POST-запроса curl: API платежей Plisio
Документация без реальных примеров — это всего лишь теория. Приведённый ниже POST-запрос curl создаёт счёт для криптовалютного платежа через REST API Plisio. Plisio взимает фиксированную комиссию в размере 0,5%; платежные системы обычно берут 2-4%. Plisio поддерживает более тридцати криптовалют и предоставляет интеграции для девятнадцати платформ электронной коммерции.
Почему крипто-API работают как тренировочные инструменты. В 2025 году объем реальных экономических операций со стейблкоинами составил примерно 28 триллионов долларов. По оценкам Chainalysis, рост с 2023 года составит 133% в год. Рынок криптоплатежных шлюзов в 2025 году составлял около 2 миллиардов долларов, а к 2026 году, по прогнозам, достигнет 2,39 миллиарда долларов (по данным The Business Research Company). BitPay, Coinbase Commerce, Plisio: выберите любой из них. Первым шагом интеграции с любым современным шлюзом почти всегда является POST-запрос curl.
Минимальный вызов для создания нового счета-фактуры:
```
curl -X POST https://api.plisio.net/api/v1/invoices/new \
-H "Content-Type: application/json" \
-H "Авторизация: Bearer $PLISIO_API_KEY" \
-d '{
"source_currency": "USD",
"source_amount": 49.99,
"order_number": "INV-1042",
"currency": "BTC",
"email": "[email protected]",
"order_name": "Annual subscription"
}'
```
Успешный вызов возвращает HTTP 201. Тело ответа представляет собой JSON-объект: сгенерированный идентификатор счета, URL-адрес счета, по которому клиент производит оплату, адрес кошелька получателя и метка времени истечения срока действия. Передайте данные через `jq`, чтобы извлечь нужное вам поле:
```
... | jq '.data.invoice_url'
```
В этом и заключается вся схема. Поменяйте конечную точку, поменяйте полезную нагрузку, и структура данных напрямую перенесется на платеж BitPay, оформление заказа в Coinbase Commerce или намерение оплаты Stripe. Флаги не меняются; меняется только JSON.
Отладка POST-запроса curl: -v, --trace, errors
Неудачная POST-запрос — это сложная задача для отладки. Повторные попытки вслепую — худший вариант. Четыре параметра в командной строке охватывают большую часть необходимых действий.
Флаг `-v` выводит строку запроса, все заголовки запроса и статус ответа. Это первый флаг, который вы используете. `--trace-ascii -` — более мощный инструмент: он выводит весь диалог, включая тело POST-запроса, в стандартный вывод. Используйте `curl -i`, чтобы встроить заголовки ответа над телом. А `-w "%{http_code}\n"` выводит только код состояния HTTP, что полезно при создании скриптов для проверок CI по отношению к API.
О наиболее часто встречающихся кодах состояния: 400: сервер обработал ваш запрос, но отклонил полезную нагрузку. 401: отсутствует или недействителен заголовок аутентификации. 415: неправильный Content-Type. 500: сервер завершил работу с ошибкой при обработке ваших входных данных. Каждый из этих кодов исключает определенный уровень, что составляет половину ценности запуска `-v` при первой ошибке.
Безопасность POST-запросов curl: ключи API, секреты и утечки.
В каждом источнике этот раздел пропущен. В каждом анализе инцидента он упоминается. Декабрь 2024 года: утечка данных Министерства финансов США связана с утечкой ключа API BeyondTrust. Именно такие учетные данные хранятся в заголовках `-H "Authorization: Bearer ..."` в скриптах для производственных систем.
Защита не отличается привлекательностью. Считывайте токены из переменных окружения. Храните их в менеджере секретов, таком как AWS Secrets Manager, HashiCorp Vault или 1Password CLI. Поддерживайте работу хука pre-commit, запускающего `gitleaks` или `trufflehog`. Меняйте все токены, которые когда-либо хранились в истории командной строки. Ничего захватывающего в этом нет. Но всё это работает. Применение этого подхода ко всем POST-запросам curl — это самая важная привычка, которую может выработать бэкенд-разработчик в 2026 году.