Tools mentioned in this article
Open the browser-based tool while you read and try the workflow immediately.
Saber leer un curl pegado acelera el trabajo con APIs
Un comando curl copiado de la documentación o de las herramientas de desarrollo del navegador suele tener este aspecto:
curl -X POST 'https://api.example.com/v1/items?limit=10' \
-H 'Authorization: Bearer TOKEN' \
-H 'Content-Type: application/json' \
-d '{"name":"Alice","tags":["a","b"]}'
Es sencillo una vez que se sabe leer, pero hay combinaciones de opciones que cambian el comportamiento, y desconocerlas lleva al clásico «el mismo comando no funciona aquí».
Tabla de opciones
| Opción | Significado |
|---|---|
-X, --request | Método HTTP (GET / POST / PUT / DELETE) |
-H, --header | Añade una cabecera; se puede repetir |
-d, --data | Envía un cuerpo. Implica POST |
--data-raw | Igual que -d, pero no trata la @ inicial como nombre de archivo |
-F, --form | Envía como multipart/form-data (subida de archivos) |
-u, --user | Autenticación básica (usuario:contraseña) |
-L, --location | Sigue las redirecciones (3xx) |
-o, --output | Guarda la respuesta en un archivo |
-O, --remote-name | Guarda con el nombre que indica la URL |
-s, --silent | Oculta el indicador de progreso |
-S, --show-error | Con -s, muestra igualmente los errores |
-i, --include | Incluye las cabeceras de respuesta en la salida |
-I, --head | Envía HEAD y muestra solo las cabeceras |
-v, --verbose | Muestra todo el intercambio, cabeceras incluidas |
-k, --insecure | No verifica el certificado del servidor |
--compressed | Solicita una transferencia comprimida |
-b, --cookie | Envía cookies |
-c, --cookie-jar | Guarda en un archivo las cookies recibidas |
-w, --write-out | Imprime datos como %{http_code} al terminar |
-X POST suele sobrar
Añadir -d ya convierte la petición en POST. Estas dos son idénticas:
curl -X POST https://api.example.com/items -d '{"a":1}'
curl https://api.example.com/items -d '{"a":1}'
El problema es el caso contrario. -X GET junto con -d produce un GET con cuerpo, algo que proxies y servidores pueden ignorar o rechazar: una causa clásica de «funciona en local y falla en producción».
Repetir -d une los valores con &. Útil para formularios, fatal para JSON:
# No es lo que quiere: envía {"a":1}&{"b":2}
curl -d '{"a":1}' -d '{"b":2}' https://api.example.com/items
Una @ inicial en -d lee un archivo
Cuando el valor pasado a -d empieza por @, curl lee ese archivo y envía su contenido:
curl -d @payload.json https://api.example.com/items # envía el contenido del archivo
Práctico, hasta que pasa un nombre de usuario tal cual:
# Intención: enviar la cadena "@alice"
# Realidad: curl busca el archivo ./alice y falla si no existe
curl -d '@alice' https://api.example.com/items
Para enviar un valor que contenga @ literalmente, use --data-raw, que no le da ningún significado especial.
El Content-Type no pasa a JSON por sí solo
Con -d, curl envía Content-Type: application/x-www-form-urlencoded salvo que indique otra cosa. Si manda JSON sin la cabecera, el servidor no podrá analizarlo:
curl -H 'Content-Type: application/json' \
-d '{"name":"Alice"}' https://api.example.com/items
Desde curl 7.82 existe --json, que establece a la vez Content-Type: application/json y Accept: application/json. En entornos antiguos no está disponible, así que escriba la cabecera explícitamente en los comandos que vaya a compartir.
Las comillas causan más fallos que ninguna otra cosa
| Estilo | Comportamiento |
|---|---|
'...' (simples) | Pasa $ y " sin tocarlos. Úselas para JSON |
"..." (dobles) | La shell expande $variables |
El JSON contiene comillas dobles, así que las exteriores deben ser simples:
# Correcto
curl -d '{"name":"Alice"}' https://api.example.com/items
# La shell elimina las comillas interiores y el cuerpo se rompe
curl -d "{"name":"Alice"}" https://api.example.com/items
Cuando necesite un token desde una variable de entorno, combine ambas deliberadamente:
curl -H "Authorization: Bearer $TOKEN" \
-d '{"name":"Alice"}' https://api.example.com/items
El símbolo del sistema de Windows no interpreta las comillas simples, y en PowerShell curl puede ser un alias de Invoke-WebRequest. Llame a curl.exe explícitamente o ejecute el comando en WSL o Git Bash.
Entrecomille las URL que contengan &
Si pega una URL con varios parámetros sin comillas, la shell interpreta & como «ejecutar en segundo plano» y trunca el comando:
# Roto: solo se envía limit=10
curl https://api.example.com/items?limit=10&offset=20
# Correcto
curl 'https://api.example.com/items?limit=10&offset=20'
Los valores con espacios o caracteres no ASCII necesitan codificación porcentual. Puede comprobarla con el codificador/decodificador de URL, o dejar que curl construya la cadena de consulta con -G y --data-urlencode:
curl -G https://api.example.com/search --data-urlencode 'q=hola mundo'
Dos opciones ante las que conviene dudar
-k / --insecure desactiva la verificación del certificado. Tiene sentido al probar un certificado autofirmado en local, pero el incidente clásico es añadirla para silenciar un error y dejarla en un comando compartido o en producción. Los problemas de certificado se arreglan en el certificado.
-L / --location sigue las redirecciones. Es cómodo, pero el tratamiento del método y del cuerpo en un POST redirigido puede cambiar; fíjelo con --post301, --post302 o --post303 cuando importe.
Convertir el comando en código
Una vez leído el comando, transcribir cabeceras y cuerpos a mano es propenso a errores. Péguelo en el conversor de cURL y obtendrá código de petición para JavaScript, Python, Go y otros lenguajes, con el entrecomillado y la separación de cabeceras ya resueltos.
Para formatear o validar el JSON que envía, use el formateador JSON; para inspeccionar una cadena de consulta, parámetros de URL a JSON. Todo se ejecuta en su navegador, así que un comando con un token de autenticación nunca se transmite.
Resumen
-dya implica POST;-X GETcon-dproduce un incómodo GET con cuerpo- Un valor de
-dque empieza por@lee un archivo: use--data-rawpara enviarlo como texto -dpor sí solo significa codificación de formulario. Para JSON, ponga la cabecera o use--json(curl 7.82+)- Comillas simples alrededor del JSON; dobles solo donde necesite expandir variables
- Entrecomille las URL con
&; construya consultas codificadas con-G --data-urlencode -kno sirve para silenciar errores, y-Lpuede cambiar el comportamiento de un POST
Preguntas frecuentes
¿Hace falta escribir -X POST?
Normalmente no: añadir -d o -F convierte la petición en POST automáticamente. Escribirlo documenta la intención, lo cual tiene valor en un comando compartido. Lo que conviene evitar es -X GET junto con -d, que produce un GET con cuerpo y algunos servidores y proxies lo ignoran o lo rechazan.
¿Qué diferencia hay entre -d y --data-raw?
Solo el tratamiento de la @ inicial. Con -d, un valor que empieza por @ se toma como nombre de archivo y se envía su contenido; --data-raw envía la cadena tal cual. Use --data-raw para datos que contengan @ de forma legítima, como una dirección de correo.
He enviado JSON pero el servidor no lo interpreta
Con -d, el Content-Type por defecto es application/x-www-form-urlencoded, así que necesita -H 'Content-Type: application/json'. Desde curl 7.82, --json establece la cabecera por usted.
El comando no funciona en Windows
El símbolo del sistema no interpreta las comillas simples y PowerShell puede tener curl como alias de Invoke-WebRequest. Llame a curl.exe explícitamente o ejecute el comando desde una shell que maneje comillas simples, como WSL o Git Bash.
¿Es seguro pegar un comando que contiene un token?
El conversor de cURL funciona íntegramente en su navegador y nada de lo que pega se transmite. Eso sí, el código convertido sigue conteniendo el token, así que muévalo a una variable de entorno antes de subir el código.