Cada vez que abres una página, envías un formulario o una aplicación habla con su servidor, se manda una petición HTTP. Toda petición lleva dos cosas: una dirección, que dice sobre qué se actúa, y un método, que dice qué hacer con ello. Los cuatro métodos que vas a usar casi siempre son GET, POST, PUT y DELETE. Esta guía los explica con esquemas y con ejemplos reales, sin dar nada por sabido.
Los cuatro, en una frase
| Método | Qué hace | Ejemplo | ¿Lleva datos? | Respuesta típica |
|---|---|---|---|---|
GET | Leer algo, sin cambiar nada | Ver la lista de tareas | No | 200 OK con los datos |
POST | Crear algo nuevo (o enviar datos para que el servidor los procese) | Añadir una tarea, enviar un formulario | Sí | 201 Created |
PUT | Reemplazar algo que ya existe, entero | Cambiar la tarea 3 por su versión nueva | Sí | 200 OK o 204 No Content |
DELETE | Borrar algo | Eliminar la tarea 3 | No | 204 No Content |
Cómo es una petición por dentro
Una petición HTTP es texto. La primera línea dice el método y la ruta; después vienen unas cabeceras con información extra; una línea en blanco marca el final, y detrás puede ir un cuerpo con datos. La respuesta tiene la misma forma, pero empieza con un código de estado que dice cómo fue.
No hace falta creérselo: curl -v muestra lo que se envía (líneas con >) y lo que se recibe (con <):
curl -v http://localhost:8000/tareas/1
extracto de la salida: solo la petición y la respuesta> GET /tareas/1 HTTP/1.1
> Host: localhost:8000
> User-Agent: curl/8.14.1
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: BaseHTTP/0.6 Python/3.13.16
< Date: Tue, 13 Oct 2026 15:52:47 GMT
< Content-Type: application/json; charset=utf-8
< Content-Length: 50
<
{"id": 1, "titulo": "Comprar pan", "hecha": false}Los cuatro métodos, con un ejemplo real
Para probarlos montamos una pequeña API: una lista de tareas en http://localhost:8000/tareas que empieza con dos. Usamos curl, que viene en Linux, macOS y Windows (desde Windows 10, en 2018); -i muestra también el código y las cabeceras de la respuesta, -X elige el método, -H añade una cabecera y -d manda datos en el cuerpo.
GET: leer
Pide algo y no cambia nada en el servidor. Es lo que hace el navegador cada vez que escribes una dirección o pulsas un enlace.
curl -i http://localhost:8000/tareas
salidaHTTP/1.1 200 OK
Server: BaseHTTP/0.6 Python/3.13.16
Date: Tue, 13 Oct 2026 15:52:46 GMT
Content-Type: application/json; charset=utf-8
Content-Length: 110
[{"id": 1, "titulo": "Comprar pan", "hecha": false}, {"id": 2, "titulo": "Llamar al dentista", "hecha": true}]Si lo pedido no existe, el servidor no lo inventa: responde 404.
curl -i http://localhost:8000/tareas/9
salidaHTTP/1.1 404 Not Found
Server: BaseHTTP/0.6 Python/3.13.16
Date: Tue, 13 Oct 2026 15:52:47 GMT
Content-Type: application/json; charset=utf-8
Content-Length: 35
{"error": "no hay ninguna tarea 9"}POST: crear
Envía datos en el cuerpo para crear algo nuevo. Se hace sobre la colección (/tareas), y es el servidor quien decide el número de la tarea nueva y lo dice en la cabecera Location. Content-Type avisa de que los datos van en JSON.
curl -i -X POST http://localhost:8000/tareas -H 'Content-Type: application/json' -d '{"titulo": "Pagar la luz"}'salidaHTTP/1.1 201 Created
Server: BaseHTTP/0.6 Python/3.13.16
Date: Tue, 13 Oct 2026 15:52:47 GMT
Content-Type: application/json; charset=utf-8
Location: /tareas/3
Content-Length: 51
{"id": 3, "titulo": "Pagar la luz", "hecha": false}Si faltan datos, la culpa es de quien pide, y el código lo dice: 400 Bad Request.
curl -i -X POST http://localhost:8000/tareas -H 'Content-Type: application/json' -d '{}'salidaHTTP/1.1 400 Bad Request
Server: BaseHTTP/0.6 Python/3.13.16
Date: Tue, 13 Oct 2026 15:52:47 GMT
Content-Type: application/json; charset=utf-8
Content-Length: 29
{"error": "falta el título"}PUT: reemplazar
Manda la versión completa de algo que ya existe, y se hace sobre su dirección concreta (/tareas/3). Aquí marcamos la tarea como hecha; por eso se envían todos los campos, también el título que no cambia.
curl -i -X PUT http://localhost:8000/tareas/3 -H 'Content-Type: application/json' -d '{"titulo": "Pagar la luz", "hecha": true}'salidaHTTP/1.1 200 OK
Server: BaseHTTP/0.6 Python/3.13.16
Date: Tue, 13 Oct 2026 15:52:47 GMT
Content-Type: application/json; charset=utf-8
Content-Length: 50
{"id": 3, "titulo": "Pagar la luz", "hecha": true}Repetir exactamente el mismo PUT da la misma respuesta y deja la tarea igual: lo comprobamos ejecutándolo dos veces. Con POST no pasa: cada vez que se repite crea una tarea más.
DELETE: borrar
Borra lo que hay en esa dirección. No lleva cuerpo, y la respuesta tampoco suele llevarlo: 204 No Content significa «hecho, y no tengo nada que contarte».
curl -i -X DELETE http://localhost:8000/tareas/3
salidaHTTP/1.1 204 No Content Server: BaseHTTP/0.6 Python/3.13.16 Date: Tue, 13 Oct 2026 15:52:47 GMT Content-Length: 0
Si se repite, ya no hay nada que borrar y la respuesta es 404. Aun así, el resultado en el servidor es el mismo: la tarea 3 no existe.
salida al repetirloHTTP/1.1 404 Not Found
Server: BaseHTTP/0.6 Python/3.13.16
Date: Tue, 13 Oct 2026 15:52:47 GMT
Content-Type: application/json; charset=utf-8
Content-Length: 35
{"error": "no hay ninguna tarea 3"}¿Y PUSH? No existe: es PUT
Es una confusión muy común, porque push suena a «enviar» y se usa en Git (git push). Pero en HTTP no hay ningún método PUSH. Si lo envías, el servidor responde que no lo conoce:
curl -i -X PUSH http://localhost:8000/tareas
salida, con el cuerpo HTML recortadoHTTP/1.1 501 Unsupported method ('PUSH')
Server: BaseHTTP/0.6 Python/3.13.16
Date: Tue, 13 Oct 2026 15:52:47 GMT
Connection: close
Content-Type: text/html;charset=utf-8
Content-Length: 357
…
<p>Message: Unsupported method ('PUSH').</p>
<p>Error code explanation: 501 - Server does not support this operation.</p>
…El código 501 Not Implemented es justo el que indica el estándar para un método que el servidor no reconoce. Hay otro método que sí verás a menudo: PATCH, que cambia solo una parte de algo (por ejemplo, solo "hecha": true), mientras que PUT lo reemplaza entero. Además existen HEAD (como GET, pero solo las cabeceras) y OPTIONS (qué métodos se permiten), menos frecuentes.
Seguro e idempotente: dos palabras que conviene conocer
- Seguro: no cambia nada en el servidor. Se puede llamar sin miedo.
- Idempotente: hacerlo una vez o diez da el mismo resultado final en el servidor. Si la conexión falla a medias, se puede repetir sin miedo a duplicar nada.
| Método | ¿Seguro? | ¿Idempotente? | Por qué |
|---|---|---|---|
GET | Sí | Sí | Solo lee |
POST | No | No | Repetirlo crea otra tarea: así se duplican pedidos y pagos |
PUT | No | Sí | Cambia datos, pero poner lo mismo dos veces deja lo mismo |
DELETE | No | Sí | Borrar dos veces deja el mismo resultado: no está (aunque la respuesta cambie) |
Por eso el navegador pregunta «¿Confirmar reenvío del formulario?» si recargas una página a la que llegaste con POST: sabe que repetirlo puede duplicar algo.
Los códigos de respuesta que más verás
El primer número dice el tipo de respuesta: 2xx, todo bien; 4xx, la petición tiene un problema (es culpa de quien pide); 5xx, el servidor ha fallado.
| Código | Significa | Cuándo |
|---|---|---|
200 OK | Todo bien, aquí está | GET, PUT |
201 Created | Creado | POST, con Location apuntando a lo nuevo |
204 No Content | Hecho, sin nada que devolver | DELETE y a veces PUT |
400 Bad Request | La petición está mal formada o faltan datos | Un POST sin título |
401 Unauthorized | Hay que identificarse | Falta el usuario o la clave |
403 Forbidden | Te conozco, pero no tienes permiso | Borrar algo que no es tuyo |
404 Not Found | Eso no existe | La tarea 9 |
405 Method Not Allowed | El servidor conoce el método, pero no lo permite en esa dirección | Un DELETE sobre toda la colección |
500 Internal Server Error | El servidor ha fallado | Un error en su código |
501 Not Implemented | El servidor no conoce ese método | PUSH |
¿Y qué cambia con HTTPS?
Nada en lo que has visto: los métodos, las cabeceras y los códigos son exactamente los mismos. HTTPS es el mismo HTTP metido dentro de una conexión cifrada (TLS), normalmente en el puerto 443 en lugar del 80. Lo que cambia es quién puede verlo por el camino:
| Quien mira el tráfico (el wifi, tu proveedor…) | Con HTTP | Con HTTPS |
|---|---|---|
El método (GET, POST…) | Lo ve | No lo ve |
La ruta y los parámetros (/tareas?buscar=luz) | Lo ve | No lo ve |
| Las cabeceras y el cuerpo (contraseñas, datos) | Lo ve y puede cambiarlo | No lo ve ni puede cambiarlo sin que se note |
El dominio (decodigo.com) | Lo ve | Lo ve |
Un detalle práctico: aunque con HTTPS la dirección completa viaja cifrada, no pongas contraseñas ni datos privados en la URL de un GET. Las direcciones se quedan en el historial del navegador y en los registros del servidor; esos datos van en el cuerpo de un POST. Si quieres ver cómo se cifra todo, paso a paso, está en la guía HTTPS por dentro.
Errores típicos al empezar
- Usar GET para borrar o cambiar cosas (
/borrar?id=3). Los navegadores, los buscadores y las vistas previas de enlaces hacen GET por su cuenta, porque se supone que es seguro, y podrían borrar algo sin que nadie lo pida. - Olvidar
Content-Typeal mandar JSON. Muchos servidores no sabrán leer el cuerpo y responderán400o415. - Usar PUT para cambiar un solo campo. PUT reemplaza el recurso entero: lo que no envíes puede perderse. Para cambios parciales existe PATCH.
- Esperar que un formulario HTML mande PUT o DELETE. El atributo
methodde un<form>solo acepta GET y POST; los otros se envían desde JavaScript (fetch) o con herramientas comocurl.
Resumen
| Quiero… | Método | Dirección | Respuesta si va bien |
|---|---|---|---|
| ver todas las tareas | GET | /tareas | 200 + la lista |
| ver una tarea | GET | /tareas/1 | 200 + la tarea |
| crear una tarea | POST | /tareas | 201 + Location |
| cambiar una tarea entera | PUT | /tareas/3 | 200 o 204 |
| borrar una tarea | DELETE | /tareas/3 | 204 |
Los ejemplos se ejecutaron el 13 de octubre de 2026 con curl 8.14.1 contra una API de prueba escrita con el módulo http.server de Python 3.13, en un contenedor desechable; las salidas están copiadas de esa ejecución. Los significados de los métodos y los códigos son los del estándar: RFC 9110 (semántica de HTTP) y, para PATCH, RFC 5789.
Fuente: IETF, RFC 9110, «HTTP Semantics», sección 9: Methods
