{
  "info": {
    "name": "DeCAFacil API (/api/v1)",
    "description": "Coleccion de la API de DeCAFacil para integrarla desde tu propio ERP o software de gestion. Documentacion completa: https://decafacil.es/desarrolladores -- esquema OpenAPI curado: {{baseUrl}}/openapi.json\n\nIMPORTANTE -- ENTORNO DE PRUEBAS POR DEFECTO: esta coleccion esta pensada para ejecutarse con una clave en modo 'pruebas' (scripts/apikey_cli.py emitir --modo pruebas), NUNCA con una clave 'real' por defecto -- es la razon de ser del modo de pruebas: los DeCA que emitas quedan marcados y no cuentan como emisiones reales. La primera carpeta (\"0. Verificacion\") comprueba el modo de la clave antes de nada, y el resto de peticiones se bloquean solas si detectan una clave en modo 'real'. Cambia la variable de coleccion 'apiKey' antes de ejecutar.",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
  },
  "auth": {
    "type": "noauth"
  },
  "event": [
    {
      "listen": "prerequest",
      "script": {
        "type": "text/javascript",
        "exec": [
          "// Guarda de seguridad (Fase 3, punto 20): esta colección apunta por defecto",
          "// al mismo host de siempre, pero SOLO debe ejecutarse con una clave en modo",
          "// \"pruebas\" (scripts/apikey_cli.py emitir --modo pruebas). \"GET /yo\" (la",
          "// primera petición de la carpeta 0) comprueba el modo real de la clave y lo",
          "// guarda aquí; a partir de la segunda petición, esta guarda para en seco",
          "// cualquier ejecución con una clave real -- así un \"Run collection\" sin",
          "// pensar no puede emitir DeCA de verdad.",
          "const modo = pm.collectionVariables.get(\"apiKeyModo\");",
          "if (modo === \"real\") {",
          "    throw new Error(",
          "        \"GUARDA DE SEGURIDAD: esta clave esta en modo 'real'. Esta coleccion \" +",
          "        \"esta pensada para ejecutarse SOLO con una clave en modo 'pruebas' \" +",
          "        \"(scripts/apikey_cli.py emitir --modo pruebas). Cambia la variable \" +",
          "        \"'apiKey' de la coleccion por una clave de pruebas antes de continuar.\"",
          "    );",
          "}",
          ""
        ]
      }
    }
  ],
  "variable": [
    {
      "key": "baseUrl",
      "value": "https://app.decafacil.es/api/v1",
      "description": "Host real -- no hay un host de 'sandbox' aparte: lo que distingue el entorno de pruebas es el MODO de la clave (ver 'apiKey'), no la URL."
    },
    {
      "key": "apiKey",
      "value": "PEGA_AQUI_TU_CLAVE_DE_PRUEBAS",
      "description": "Clave emitida con --modo pruebas (scripts/apikey_cli.py). Nunca pegues aqui una clave 'real' para ejecutar la coleccion entera."
    },
    {
      "key": "apiKeyModo",
      "value": ""
    },
    {
      "key": "externalId",
      "value": ""
    },
    {
      "key": "decaId",
      "value": ""
    },
    {
      "key": "token",
      "value": ""
    },
    {
      "key": "nVersion",
      "value": ""
    }
  ],
  "item": [
    {
      "name": "0. Verificacion",
      "item": [
        {
          "name": "Verificar la clave (GET /yo)",
          "request": {
            "auth": {
              "type": "noauth"
            },
            "method": "GET",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{apiKey}}",
                "type": "text"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/yo",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "yo"
              ]
            },
            "description": "Primer paso siempre: confirma que la clave funciona y en que modo esta. Si no es 'pruebas', el resto de la coleccion se bloquea sola (guarda de seguridad de la coleccion)."
          },
          "response": [],
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"200 y clave valida\", function () {",
                  "    pm.response.to.have.status(200);",
                  "});",
                  "const body = pm.response.json();",
                  "pm.collectionVariables.set(\"apiKeyModo\", body.modo);",
                  "pm.test(\"la clave esta en modo 'pruebas' (guarda de seguridad)\", function () {",
                  "    pm.expect(body.modo).to.eql(\"pruebas\");",
                  "});",
                  "if (body.modo !== \"pruebas\") {",
                  "    console.warn(",
                  "        \"AVISO: esta clave esta en modo 'real'. Las peticiones siguientes de \" +",
                  "        \"esta coleccion se bloquearan solas (ver pre-request script de la \" +",
                  "        \"coleccion) para no emitir DeCA reales por accidente.\"",
                  "    );",
                  "}",
                  ""
                ]
              }
            }
          ]
        }
      ]
    },
    {
      "name": "1. Emitir",
      "item": [
        {
          "name": "Emitir un DeCA (POST /deca)",
          "request": {
            "auth": {
              "type": "noauth"
            },
            "method": "POST",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{apiKey}}",
                "type": "text"
              },
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}",
                "type": "text"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/deca",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "deca"
              ]
            },
            "description": "Crea un DeCA y guarda id/token/n_version en variables de coleccion para las peticiones siguientes. Incluye Idempotency-Key de ejemplo: repetir esta peticion tal cual no crea un segundo documento.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"datos\": {\n    \"cargador_contractual\": {\n      \"nombre\": \"Cargas Ejemplo SA\",\n      \"nif\": \"A76543214\",\n      \"direccion\": {\n        \"empresa\": \"Cargas Ejemplo SA\",\n        \"via\": \"Polígono Industrial El Álamo, nave 12\",\n        \"localidad\": \"Getafe\",\n        \"provincia\": \"Madrid\",\n        \"codigo_postal\": \"28906\",\n        \"pais\": \"España\"\n      }\n    },\n    \"transportista_efectivo\": {\n      \"nombre\": \"Transportes Ejemplo SL\",\n      \"nif\": \"B12345674\",\n      \"direccion\": {\n        \"empresa\": \"Transportes Ejemplo SL\",\n        \"via\": \"Calle del Transporte, 8\",\n        \"localidad\": \"Valencia\",\n        \"provincia\": \"Valencia\",\n        \"codigo_postal\": \"46013\",\n        \"pais\": \"España\"\n      }\n    },\n    \"matricula_vehiculo\": \"1234ABC\",\n    \"envios\": [\n      {\n        \"ref\": \"PED-EJEMPLO\",\n        \"origen\": {\n          \"via\": \"Polígono Industrial El Álamo, nave 12\",\n          \"localidad\": \"Getafe\",\n          \"provincia\": \"Madrid\",\n          \"codigo_postal\": \"28906\",\n          \"pais\": \"España\"\n        },\n        \"destino\": {\n          \"via\": \"Avenida del Puerto, 45\",\n          \"localidad\": \"Valencia\",\n          \"provincia\": \"Valencia\",\n          \"codigo_postal\": \"46023\",\n          \"pais\": \"España\"\n        },\n        \"mercancia\": {\n          \"naturaleza\": \"Palets de material de construcción\",\n          \"peso_kg\": 8200,\n          \"bultos\": 12\n        },\n        \"fecha_efectiva_servicio\": \"2026-08-28\"\n      }\n    ]\n  },\n  \"ejecutado_por\": \"Colección Postman - prueba\",\n  \"external_id\": \"{{externalId}}\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": [],
          "event": [
            {
              "listen": "prerequest",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "// Identificador propio distinto en cada ejecucion, para poder relanzar la",
                  "// coleccion varias veces sin chocar con external_id ya usado (409).",
                  "pm.collectionVariables.set(\"externalId\", \"PED-POSTMAN-\" + Date.now());",
                  ""
                ]
              }
            },
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"201 al emitir\", function () {",
                  "    pm.response.to.have.status(201);",
                  "});",
                  "const body = pm.response.json();",
                  "pm.collectionVariables.set(\"decaId\", body.id);",
                  "pm.collectionVariables.set(\"token\", body.token);",
                  "pm.collectionVariables.set(\"nVersion\", body.n_version);",
                  ""
                ]
              }
            }
          ]
        }
      ]
    },
    {
      "name": "2. Consultar",
      "item": [
        {
          "name": "Listar DeCA (GET /deca)",
          "request": {
            "auth": {
              "type": "noauth"
            },
            "method": "GET",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{apiKey}}",
                "type": "text"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/deca?limite=20",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "deca"
              ],
              "query": [
                {
                  "key": "limite",
                  "value": "20"
                }
              ]
            },
            "description": "Listado paginado de tu cuenta."
          },
          "response": [],
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"200\", function () { pm.response.to.have.status(200); });",
                  ""
                ]
              }
            }
          ]
        },
        {
          "name": "Listar DeCA vivos (GET /deca/vivos)",
          "request": {
            "auth": {
              "type": "noauth"
            },
            "method": "GET",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{apiKey}}",
                "type": "text"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/deca/vivos",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "deca",
                "vivos"
              ]
            },
            "description": "Los que tienen la URL publica del QR activa ahora mismo."
          },
          "response": [],
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"200\", function () { pm.response.to.have.status(200); });",
                  ""
                ]
              }
            }
          ]
        },
        {
          "name": "Consultar por id (GET /deca/:decaId)",
          "request": {
            "auth": {
              "type": "noauth"
            },
            "method": "GET",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{apiKey}}",
                "type": "text"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/deca/{{decaId}}",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "deca",
                "{{decaId}}"
              ]
            },
            "description": "Usa el decaId guardado al emitir."
          },
          "response": [],
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"200\", function () { pm.response.to.have.status(200); });",
                  ""
                ]
              }
            }
          ]
        },
        {
          "name": "Buscar por token (GET /deca/por-token/:token)",
          "request": {
            "auth": {
              "type": "noauth"
            },
            "method": "GET",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{apiKey}}",
                "type": "text"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/deca/por-token/{{token}}",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "deca",
                "por-token",
                "{{token}}"
              ]
            },
            "description": ""
          },
          "response": [],
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"200\", function () { pm.response.to.have.status(200); });",
                  ""
                ]
              }
            }
          ]
        },
        {
          "name": "Descargar PDF vigente (GET /deca/:decaId/pdf)",
          "request": {
            "auth": {
              "type": "noauth"
            },
            "method": "GET",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{apiKey}}",
                "type": "text"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/deca/{{decaId}}/pdf",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "deca",
                "{{decaId}}",
                "pdf"
              ]
            },
            "description": "Devuelve el binario del PDF, no JSON."
          },
          "response": []
        },
        {
          "name": "Historial de versiones (GET /deca/:decaId/versiones)",
          "request": {
            "auth": {
              "type": "noauth"
            },
            "method": "GET",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{apiKey}}",
                "type": "text"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/deca/{{decaId}}/versiones",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "deca",
                "{{decaId}}",
                "versiones"
              ]
            },
            "description": ""
          },
          "response": [],
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"200\", function () { pm.response.to.have.status(200); });",
                  ""
                ]
              }
            }
          ]
        }
      ]
    },
    {
      "name": "3. Modificar",
      "item": [
        {
          "name": "Modificar in_place (POST /deca/:decaId/modificacion)",
          "request": {
            "auth": {
              "type": "noauth"
            },
            "method": "POST",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{apiKey}}",
                "type": "text"
              },
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}",
                "type": "text"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/deca/{{decaId}}/modificacion",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "deca",
                "{{decaId}}",
                "modificacion"
              ]
            },
            "description": "Corrige la matricula del DeCA de prueba. Responde 200 y actualiza nVersion.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"campos\": {\n    \"matricula_vehiculo\": \"5678XYZ\"\n  },\n  \"motivo\": \"Correccion de prueba desde Postman\",\n  \"metodo\": \"in_place\",\n  \"ejecutado_por\": \"Coleccion Postman - prueba\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": [],
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"200\", function () { pm.response.to.have.status(200); });",
                  "const body = pm.response.json();",
                  "pm.collectionVariables.set(\"nVersion\", body.n_version);",
                  ""
                ]
              }
            }
          ]
        }
      ]
    },
    {
      "name": "4. Avisar y finalizar",
      "item": [
        {
          "name": "Registrar aviso al conductor (POST /deca/:decaId/aviso)",
          "request": {
            "auth": {
              "type": "noauth"
            },
            "method": "POST",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{apiKey}}",
                "type": "text"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/deca/{{decaId}}/aviso",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "deca",
                "{{decaId}}",
                "aviso"
              ]
            },
            "description": "",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"canal\": \"whatsapp\",\n  \"destino\": \"+34600111222\",\n  \"nota\": \"Enviado desde la coleccion de Postman\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": [],
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"201\", function () { pm.response.to.have.status(201); });",
                  ""
                ]
              }
            }
          ]
        },
        {
          "name": "Finalizar servicio (POST /deca/:decaId/finalizar)",
          "request": {
            "auth": {
              "type": "noauth"
            },
            "method": "POST",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{apiKey}}",
                "type": "text"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/deca/{{decaId}}/finalizar",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "deca",
                "{{decaId}}",
                "finalizar"
              ]
            },
            "description": "",
            "body": {
              "mode": "raw",
              "raw": "{}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": [],
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"200\", function () { pm.response.to.have.status(200); });",
                  ""
                ]
              }
            }
          ]
        }
      ]
    },
    {
      "name": "5. Anular (opcional)",
      "item": [
        {
          "name": "Anular el DeCA de prueba (POST /deca/:decaId/anular)",
          "request": {
            "auth": {
              "type": "noauth"
            },
            "method": "POST",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{apiKey}}",
                "type": "text"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/deca/{{decaId}}/anular",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "deca",
                "{{decaId}}",
                "anular"
              ]
            },
            "description": "Deshabilitada por defecto en el orden de ejecucion normal -- activala solo si quieres comprobar tambien la anulacion. Como todo lo anterior corrio con una clave de pruebas, no anula nada real.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"motivo\": \"Cierre de la prueba de la coleccion Postman\",\n  \"ejecutado_por\": \"Coleccion Postman - prueba\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": [],
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"200\", function () { pm.response.to.have.status(200); });",
                  ""
                ]
              }
            }
          ]
        }
      ]
    }
  ]
}
