Guía práctica para consumir la API local del sistema de paquetería
This documentation describes the most used endpoints for integration: Authentication, Products and Orders (Pedidos). Examples show request shape, response shape and common errors.
OpenAPI (machine-readable): paqueteria_api.yaml.
Minimal steps to call the API successfully:
POST /api/auth/login with { "email", "password" }.response.data.token (important: the token is inside data.token, not at the top level).Authorization: Bearer <token>.numero_orden, and ensure the product has enough stock.{
"success": true,
"message": "Login exitoso",
"data": { "token": "<JWT_TOKEN>" }
}
Note: always use the token value located at data.token when setting the Authorization header.
Obtain a JWT token. NOTE: the HTTP response envelope is { success, message, data: { token } }.
| Field | Type | Required | Description |
|---|---|---|---|
email | string (email) | yes | User email |
password | string | yes | User password |
{
"email": "admin@example.com",
"password": "123456"
}
{
"success": true,
"message": "Login exitoso",
"data": { "token": "<JWT_TOKEN>" }
}
Security note: never embed real credentials or long-lived tokens in public documentation or examples. Use placeholders and environment variables when running commands.
Endpoint to retrieve reference lists used by the front-end selects: countries, departments, municipalities, neighborhoods and currencies.
Returns an object data containing arrays for paises (countries), departamentos (departments), municipios (municipalities), barrios (neighborhoods) and monedas (currencies). Useful to initialize forms and dependent selects.
{
"success": true,
"message": "GeoInfo listed",
"data": {
"paises": [{ "id": 1, "nombre": "Nicaragua", "codigo_iso": "NI" }],
"departamentos": [{ "id": 1, "nombre": "Managua", "id_pais": 1 }],
"municipios": [{ "id": 1, "nombre": "Managua", "id_departamento": 1 }],
"barrios": [{ "id": 1, "nombre": "Altamira", "id_municipio": 1 }],
"monedas": [{ "id":1, "codigo":"USD", "nombre":"US Dollar", "tasa_usd":"1.0000" }]
}
}
Endpoints to manage Paises, Departamentos, Municipios, and Barrios. All endpoints support GET, POST, PUT, DELETE.
{
"nombre": "Nombre del Pais",
"codigo_iso": "NP"
}
{
"nombre": "Nombre del Departamento",
"id_pais": 1
}
{
"nombre": "Nombre del Municipio",
"id_departamento": 1
}
{
"nombre": "Nombre del Barrio",
"id_municipio": 1
}
Manage products. Mutating endpoints require a valid Authorization header.
Returns a list of products with aggregated stock (field stock_total).
Optional query parameter: include_stock=1 — when set, the response includes a stock_entries array for each product with recent stock movements (fields: id, id_producto, id_usuario, cantidad, updated_at).
{
"success": true,
"data": [
{ "id": 1, "nombre": "Matcha Slim", "precio_usd": "25.00", "stock_total": 2 },
{ "id": 2, "nombre": "Protein Shake", "precio_usd": "40.00", "stock_total": 60 }
]
}
{
"success": true,
"data": [
{
"id": 2,
"nombre": "Protein Shake",
"precio_usd": "40.00",
"stock_total": "48",
"stock_entries": [
{ "id": 28, "id_producto": 2, "id_usuario": 5, "cantidad": -11, "updated_at": "2025-11-19 11:57:38" },
{ "id": 9, "id_producto": 2, "id_usuario": 1, "cantidad": 29, "updated_at": "2025-10-31 12:56:52" }
]
}
]
}
| Field | Type | Required | Notes |
|---|---|---|---|
nombre | string | yes | Unique-ish name used by lookup functions |
descripcion | string | no | Optional |
precio_usd | number | no | Decimal, stored as string in responses |
stock | integer | no | Optional initial stock quantity — when provided the API inserts a stock movement for the authenticated user (or uses FALLBACK_USER_FOR_STOCK if configured). |
{
"nombre": "Producto X",
"descripcion": "Descripción opcional",
"precio_usd": 9.5,
"stock": 12
}
{
"success": true,
"message": "Producto creado correctamente.",
"data": { "id": 42, "stock_inserted": 99 }
}
Endpoints to create, search and list orders. The server stores coordinates as a POINT; for API requests provide coordinates as "lat,long" or as numeric latitud and longitud fields.
Requires Authorization header: Authorization: Bearer <token>. Returns the order data (latitud/longitud as numbers) when found.
{
"success": true,
"message": "Order found",
"data": {
"numero_orden": "90001",
"destinatario": "Test Customer",
"telefono": "0999999999",
"id_pais": 3,
"latitud": -0.180653,
"longitud": -78.467838,
"nombre_estado": "Pending"
}
}
{ success, message, data }.id_moneda, id_vendedor and id_proveedor are stored in pedidos and have foreign key constraints — they must reference existing rows.pedidos_productos (pivot). The API accepts the simple format using top-level producto or producto_id plus cantidad. Internally the model supports creating an order with multiple items (see crearPedidoConProductos in the model).Below are the main fields related to the pedidos table and how to pass them in the JSON payload when creating an order. Fields generated by the server (like id and fecha_ingreso) should not be supplied.
| Field | Type | Required | Description / how to provide it |
|---|---|---|---|
id | integer | server | Primary key generated by the server — do not provide on create. |
fecha_ingreso | datetime | server | Insertion timestamp set by the server — do not provide on create. |
numero_orden | integer | yes | Unique order number (your system should ensure uniqueness). |
destinatario | string | yes | Recipient name. |
telefono | string | yes | Phone number for the recipient. |
precio_local | number | no | Local currency price (optional). If provided, include as decimal (e.g., 120.50). |
precio_usd | number | no | Price in USD (optional). |
id_pais | integer | recommended | Country id — use the numeric id from /api/geoinfo/listar → paises. |
id_departamento | integer | recommended | Department id — use the numeric id from /api/geoinfo/listar → departamentos. |
id_municipio | integer | recommended | Municipality id — use the numeric id from /api/geoinfo/listar → municipios. |
id_barrio | integer | no | Neighborhood id — optional; get the numeric id from /api/geoinfo/listar → barrios if available. |
direccion | string | no | Full address. |
zona | string | no | Optional zone/neighborhood descriptor (free text). |
comentario | string | no | Optional comments about the order. |
coordenadas | string | yes | Latitude and longitude as "lat,long" (or provide numeric latitud and longitud fields). |
id_estado | integer | recommended | Status id referencing estados (if your system uses it). Use valid id from your statuses table. |
id_moneda | integer | recommended | FK to monedas.id. Use the numeric id from /api/geoinfo/listar → monedas. |
id_vendedor | integer | optional | FK to usuarios.id for seller/repartidor. Use numeric user IDs from your users administration or /api/usuarios/listar when available. |
id_proveedor | integer | optional | FK to usuarios.id for provider — provide a numeric user id; if omitted the authenticated user may be used. |
productos | array | no | Array of items: each item { producto_id: integer, cantidad: integer }. For single-product requests you may use top-level producto_id + cantidad. |
{
"numero_orden": 90001,
"destinatario": "Cliente Prueba",
"telefono": "0999999999",
"producto_id": 12,
"cantidad": 1,
"coordenadas": "-0.180653,-78.467838",
"direccion": "Calle Falsa 123",
"zona": "Zona A",
"precio_local": 120.50,
"precio_usd": 30.12,
"id_moneda": 1,
"id_vendedor": 5,
"id_proveedor": 6,
"id_pais": 3,
"id_departamento": 5,
"id_municipio": 12,
"id_barrio": 7,
"comentario": "Entrega en horario de oficina"
}
Provide product IDs in the productos array. Each item must include producto_id (integer) and cantidad (int).
{
"numero_orden": 90002,
"destinatario": "Cliente Prueba",
"telefono": "0999999999",
"productos": [
{ "producto_id": 12, "cantidad": 2 },
{ "producto_id": 13, "cantidad": 1 }
],
"coordenadas": "-0.180653,-78.467838",
"direccion": "Calle Falsa 123",
"id_moneda": 1,
"id_pais": 3,
"id_departamento": 5,
"id_municipio": 12
}
Example JSON that has been tested with the /api/pedidos/crear endpoint — it uses the productos array with producto_id (product 2: "Protein Shake").
{
"numero_orden": 1700385600,
"destinatario": "Proveedor Prueba",
"telefono": "0999999999",
"productos": [
{ "producto_id": 2, "cantidad": 1 }
],
"coordenadas": "-0.180653,-78.467838",
"direccion": "Calle Falsa 123",
"zona": "Centro",
"id_moneda": 1,
"pais": 3,
"departamento": 5,
"id_municipio": 12,
"id_barrio": 7,
"comentario": "Pedido de prueba via Postman"
}
id_pais, id_departamento, id_municipio, id_barrio). Obtain these ids from /api/geoinfo/listar.id or fecha_ingreso — the server sets them.producto_id + cantidad, or multiple products using the productos array (each item: { producto_id, cantidad }).id_proveedor, the API may use the authenticated user (from the token) when applicable."lat,long" or provide numeric latitud and longitud fields.precio_local, precio_usd) are optional but must be numeric if provided.numero_orden must be unique; duplicate numbers will return an error.{
"success": true,
"message": "Order created successfully.",
"data": 1700385600
}
{
"success": false,
"message": "Error inserting order: Insufficient stock for product ID 11. Available: 0, required: 1"
}
{
"success": false,
"message": "Error inserting order: Cannot add or update a child row: a foreign key constraint fails (...)"
}
Creates multiple orders in a single request from a JSON payload. This endpoint is intended for integrations and batch imports (for example, converting CSV to JSON before sending). The endpoint accepts a top-level JSON object with a pedidos array. Each element must follow the same order structure used by /api/pedidos/crear.
Send a JSON object with a pedidos array. Each order must include numero_orden, recipient details and at least one product in the productos array. Coordinates may be provided as a string "lat,long" or as numeric fields latitud and longitud.
{
"pedidos": [
{
"numero_orden": 1001,
"destinatario": "Customer One",
"telefono": "12345678",
"productos": [
{ "producto_id": 1, "cantidad": 2 }
],
"coordenadas": "-34.500000,-58.400000",
"direccion": "Street 1 #123",
"id_pais": 1,
"id_departamento": 2
},
{
"numero_orden": 1002,
"destinatario": "Customer Two",
"telefono": "87654321",
"productos": [
{ "producto_id": 2, "cantidad": 1 },
{ "producto_id": 3, "cantidad": 1 }
],
"latitud": -34.600000,
"longitud": -58.500000,
"direccion": "Evergreen Ave 742",
"id_pais": 1,
"id_departamento": 2
},
{
"numero_orden": 1003,
"destinatario": "Customer Three",
"telefono": "55512345",
"productos": [
{ "producto_id": 1, "cantidad": 1 }
],
"coordenadas": "-34.510000,-58.410000",
"direccion": "Street 3 #45",
"id_pais": 1,
"id_departamento": 2
},
{
"numero_orden": 1004,
"destinatario": "Customer Four",
"telefono": "60070080",
"productos": [
{ "producto_id": 4, "cantidad": 1 }
],
"latitud": -34.520000,
"longitud": -58.420000,
"direccion": "Boulevard 9",
"id_pais": 1,
"id_departamento": 2
},
{
"numero_orden": 1005,
"destinatario": "Customer Five",
"telefono": "70080090",
"productos": [
{ "producto_id": 2, "cantidad": 2 }
],
"coordenadas": "-34.530000,-58.430000",
"direccion": "Route 5",
"id_pais": 1,
"id_departamento": 2
}
]
}
The endpoint returns a JSON object with a results array. Each item corresponds to one submitted order and contains numero_orden, success (boolean) and either id_pedido when the insertion succeeded or error with a message describing why that particular order failed. Processing continues for remaining orders even if some fail.
{
"results": [
{ "numero_orden": 1001, "success": true, "id_pedido": 201 },
{ "numero_orden": 1002, "success": false, "error": "Insufficient stock for product ID 2" },
{ "numero_orden": 1003, "success": true, "id_pedido": 203 },
{ "numero_orden": 1004, "success": true, "id_pedido": 204 },
{ "numero_orden": 1005, "success": true, "id_pedido": 205 }
]
}
Save the example payload to pedidos_batch.json locally and use the curl command above. The server returns HTTP 200 with the per-order results array when the top-level JSON is valid. If the JSON is malformed the API returns HTTP 400.
id_moneda, id_vendedor and id_proveedor exist in their respective tables./api/productos/crear, then use the stock UI or insert into stock table.pais, departamento and municipio. If any are missing you will receive a validation error listing the missing fields.cantidad.