{
  "openapi": "3.0.3",
  "info": {
    "title": "DECA ERP - Alternative NTS FORMAT",
    "version": "1.2.0",
    "description": "Available by default to current and new companies with active API access. It uses the same company key as the standard format. Administrators can disable it per company. It does not send notifications automatically. Maximum 2 MB per request and 5 MB per PDF. Test operations create real documents.",
    "contact": {
      "name": "NetSistemas",
      "email": "nts@netsistemas.com"
    }
  },
  "servers": [
    {
      "url": "https://deca.netsistemas.com"
    }
  ],
  "externalDocs": {
    "description": "Alternative NTS FORMAT guide",
    "url": "https://deca.netsistemas.com/api-nts.html"
  },
  "security": [
    {
      "ApiKeyAuth": []
    },
    {
      "BearerAuth": []
    }
  ],
  "paths": {
    "/api_nts.php": {
      "post": {
        "operationId": "crearDocumentoNts",
        "summary": "Create, replace or process a NTS batch",
        "description": "The key identifies the company; it is not selected in JSON. Use one format per operation: there is no deduplication with api.php. For replacements, send the complete document with documentoOrigenId and a new idempotency key. The number is retained while GUID and URL change. The previous URL links to the current document. Cancellation without replacement is not supported.",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 200
            },
            "description": "Stable key per operation. Same key with different JSON: 409. Without the header, a JSON fingerprint is used. Existing number with a new explicit key: 409. Preserve batch order; for an individual retry use original-key:INDEX (zero-based)."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/Documento"
                  },
                  {
                    "$ref": "#/components/schemas/Lote"
                  }
                ]
              },
              "examples": {
                "documento": {
                  "summary": "Create using fictional data",
                  "value": {
                    "numeroDocumento": "EJEMPLO-2026-001",
                    "transportista": {
                      "nif": "DEMO-TRANSPORTISTA",
                      "razonSocial": "Transportes de ejemplo",
                      "domicilio": "Calle de ejemplo 10, Madrid",
                      "email": "transportista@example.com"
                    },
                    "vehiculo": {
                      "matriculaTractora": "1234BCD",
                      "matriculaRemolque": "R5678BCD",
                      "tipo": "Frigorifico"
                    },
                    "canalNotificacion": "EMAIL",
                    "incluirConductorPdf": true,
                    "conductores": [
                      {
                        "dni": "DEMO-CONDUCTOR-01",
                        "nombre": "Conductor de ejemplo",
                        "numeroTarjeta": "TARJETA-EJEMPLO",
                        "notaDeca": "Mercancia refrigerada. Acceso por muelle 2.",
                        "mostrarNotaDeca": true,
                        "contactos": [
                          {
                            "tipoCanal": "EMAIL",
                            "valor": "conductor@example.com"
                          }
                        ]
                      }
                    ],
                    "grupos": [
                      {
                        "esOrigenCargadorContractual": true,
                        "destinos": [
                          {
                            "razonSocial": "Destino de ejemplo",
                            "domicilio": "Calle de ejemplo 20, Barcelona",
                            "lineasMercancia": [
                              {
                                "descripcion": "Mercancia de ejemplo",
                                "peso": 1200,
                                "unidadMedida": "KG",
                                "bultos": 24,
                                "palets": 2
                              }
                            ]
                          }
                        ]
                      }
                    ],
                    "observaciones": "Datos ficticios para una empresa de pruebas."
                  }
                },
                "lote": {
                  "summary": "Document batch",
                  "value": {
                    "documentos": [
                      {
                        "numeroDocumento": "EJEMPLO-2026-001",
                        "transportista": {
                          "nif": "DEMO-TRANSPORTISTA",
                          "razonSocial": "Transportes de ejemplo",
                          "domicilio": "Calle de ejemplo 10, Madrid",
                          "email": "transportista@example.com"
                        },
                        "vehiculo": {
                          "matriculaTractora": "1234BCD",
                          "matriculaRemolque": "R5678BCD",
                          "tipo": "Frigorifico"
                        },
                        "canalNotificacion": "EMAIL",
                        "incluirConductorPdf": true,
                        "conductores": [
                          {
                            "dni": "DEMO-CONDUCTOR-01",
                            "nombre": "Conductor de ejemplo",
                            "numeroTarjeta": "TARJETA-EJEMPLO",
                            "notaDeca": "Mercancia refrigerada. Acceso por muelle 2.",
                            "mostrarNotaDeca": true,
                            "contactos": [
                              {
                                "tipoCanal": "EMAIL",
                                "valor": "conductor@example.com"
                              }
                            ]
                          }
                        ],
                        "grupos": [
                          {
                            "esOrigenCargadorContractual": true,
                            "destinos": [
                              {
                                "razonSocial": "Destino de ejemplo",
                                "domicilio": "Calle de ejemplo 20, Barcelona",
                                "lineasMercancia": [
                                  {
                                    "descripcion": "Mercancia de ejemplo",
                                    "peso": 1200,
                                    "unidadMedida": "KG",
                                    "bultos": 24,
                                    "palets": 2
                                  }
                                ]
                              }
                            ]
                          }
                        ],
                        "observaciones": "Datos ficticios para una empresa de pruebas."
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Recognized retry; same document.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Exito"
                }
              }
            }
          },
          "201": {
            "description": "Document created or replaced.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Exito"
                }
              }
            }
          },
          "207": {
            "description": "Batch processed. Check http and resultado for each item; there is no global rollback.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResultadoLote"
                }
              }
            }
          },
          "401": {
            "description": "Invalid key or inactive company.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Expired subscription or disabled format.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Source document inaccessible.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "405": {
            "description": "Use POST.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Number, replacement or idempotency conflict.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Maximum 2 MB.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "415": {
            "description": "Use application/json.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Invalid JSON or fields.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal error. Retry with the same key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "X-Api-Key"
      },
      "BearerAuth": {
        "type": "http",
        "scheme": "bearer"
      }
    },
    "schemas": {
      "Tercero": {
        "type": "object",
        "required": [
          "razonSocial",
          "domicilio"
        ],
        "properties": {
          "razonSocial": {
            "type": "string",
            "minLength": 1,
            "maxLength": 150
          },
          "domicilio": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          },
          "nif": {
            "type": "string",
            "maxLength": 20,
            "nullable": true
          },
          "contacto": {
            "type": "string",
            "maxLength": 150,
            "nullable": true
          },
          "telefono": {
            "type": "string",
            "maxLength": 30,
            "nullable": true
          },
          "email": {
            "type": "string",
            "maxLength": 150,
            "nullable": true,
            "format": "email"
          }
        }
      },
      "Transportista": {
        "type": "object",
        "required": [
          "razonSocial",
          "domicilio",
          "nif"
        ],
        "properties": {
          "razonSocial": {
            "type": "string",
            "minLength": 1,
            "maxLength": 150
          },
          "domicilio": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          },
          "nif": {
            "type": "string",
            "minLength": 1,
            "maxLength": 20
          },
          "contacto": {
            "type": "string",
            "maxLength": 150,
            "nullable": true
          },
          "telefono": {
            "type": "string",
            "maxLength": 30,
            "nullable": true
          },
          "email": {
            "type": "string",
            "maxLength": 150,
            "nullable": true,
            "format": "email"
          }
        }
      },
      "Vehiculo": {
        "type": "object",
        "required": [
          "matriculaTractora"
        ],
        "properties": {
          "matriculaTractora": {
            "type": "string",
            "minLength": 1,
            "maxLength": 30,
            "description": "After normalizing spaces and hyphens: 2 to 15 letters or digits."
          },
          "matriculaRemolque": {
            "type": "string",
            "maxLength": 30,
            "nullable": true
          },
          "tipo": {
            "type": "string",
            "maxLength": 80,
            "nullable": true
          }
        }
      },
      "Contacto": {
        "type": "object",
        "required": [
          "tipoCanal",
          "valor"
        ],
        "properties": {
          "tipoCanal": {
            "type": "string",
            "enum": [
              "EMAIL",
              "WHATSAPP",
              "TELEGRAM",
              "SMS"
            ]
          },
          "valor": {
            "type": "string",
            "minLength": 1,
            "maxLength": 150
          }
        }
      },
      "Conductor": {
        "type": "object",
        "required": [
          "dni",
          "nombre"
        ],
        "properties": {
          "dni": {
            "type": "string",
            "minLength": 1,
            "maxLength": 40
          },
          "nombre": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100
          },
          "numeroTarjeta": {
            "type": "string",
            "maxLength": 40,
            "nullable": true
          },
          "notaDeca": {
            "type": "string",
            "maxLength": 300,
            "nullable": true,
            "description": "Operational note copied to the document. Do not include an ID number, telephone, email or unnecessary private data."
          },
          "mostrarNotaDeca": {
            "type": "boolean",
            "default": false,
            "description": "Shows notaDeca next to the name if the document includes drivers in the PDF."
          },
          "contactos": {
            "type": "array",
            "minItems": 0,
            "maxItems": 4,
            "items": {
              "$ref": "#/components/schemas/Contacto"
            },
            "description": "One contact per channel. EMAIL addresses and SMS/WHATSAPP phone numbers are validated."
          }
        }
      },
      "Mercancia": {
        "type": "object",
        "required": [
          "descripcion",
          "peso",
          "unidadMedida"
        ],
        "properties": {
          "descripcion": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          },
          "peso": {
            "type": "number",
            "minimum": 0,
            "exclusiveMinimum": true,
            "maximum": 9999999999.99,
            "multipleOf": 0.01
          },
          "unidadMedida": {
            "type": "string",
            "minLength": 1,
            "maxLength": 30,
            "description": "KG and T are initially available; other units require company configuration."
          },
          "bultos": {
            "type": "integer",
            "minimum": 0,
            "maximum": 2147483647,
            "nullable": true
          },
          "palets": {
            "type": "number",
            "minimum": 0,
            "maximum": 9999999999.99,
            "multipleOf": 0.01,
            "nullable": true
          }
        }
      },
      "Destino": {
        "type": "object",
        "required": [
          "razonSocial",
          "domicilio",
          "lineasMercancia"
        ],
        "properties": {
          "razonSocial": {
            "type": "string",
            "minLength": 1,
            "maxLength": 150
          },
          "domicilio": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          },
          "nif": {
            "type": "string",
            "maxLength": 20,
            "nullable": true
          },
          "contacto": {
            "type": "string",
            "maxLength": 150,
            "nullable": true
          },
          "telefono": {
            "type": "string",
            "maxLength": 30,
            "nullable": true
          },
          "email": {
            "type": "string",
            "maxLength": 150,
            "nullable": true,
            "format": "email"
          },
          "observaciones": {
            "type": "string",
            "maxLength": 300,
            "nullable": true
          },
          "lineasMercancia": {
            "type": "array",
            "minItems": 1,
            "maxItems": 1000,
            "items": {
              "$ref": "#/components/schemas/Mercancia"
            }
          }
        }
      },
      "Grupo": {
        "oneOf": [
          {
            "type": "object",
            "required": [
              "esOrigenCargadorContractual",
              "destinos"
            ],
            "properties": {
              "esOrigenCargadorContractual": {
                "type": "boolean",
                "enum": [
                  true
                ]
              },
              "destinos": {
                "type": "array",
                "minItems": 1,
                "maxItems": 200,
                "items": {
                  "$ref": "#/components/schemas/Destino"
                }
              }
            }
          },
          {
            "type": "object",
            "required": [
              "esOrigenCargadorContractual",
              "origen",
              "destinos"
            ],
            "properties": {
              "esOrigenCargadorContractual": {
                "type": "boolean",
                "enum": [
                  false
                ]
              },
              "origen": {
                "$ref": "#/components/schemas/Tercero"
              },
              "destinos": {
                "type": "array",
                "minItems": 1,
                "maxItems": 200,
                "items": {
                  "$ref": "#/components/schemas/Destino"
                }
              }
            }
          }
        ]
      },
      "Documento": {
        "type": "object",
        "required": [
          "transportista",
          "vehiculo",
          "conductores",
          "grupos",
          "canalNotificacion"
        ],
        "properties": {
          "documentoOrigenId": {
            "type": "string",
            "maxLength": 36,
            "nullable": true,
            "format": "uuid",
            "description": "GUID of the current NTS document in the same company to replace."
          },
          "numeroDocumento": {
            "type": "string",
            "maxLength": 40,
            "nullable": true,
            "description": "Unique current number per company. Assigned if omitted; retained on replacement."
          },
          "fechaTransporte": {
            "type": "string",
            "maxLength": 10,
            "nullable": true,
            "format": "date",
            "description": "If omitted, the issue date in Europe/Madrid."
          },
          "observaciones": {
            "type": "string",
            "maxLength": 500,
            "nullable": true
          },
          "canalNotificacion": {
            "type": "string",
            "enum": [
              "EMAIL",
              "WHATSAPP",
              "TELEGRAM",
              "SMS"
            ],
            "description": "The requested channel is recorded; messages are not sent automatically."
          },
          "incluirConductorPdf": {
            "type": "boolean",
            "default": true,
            "description": "Includes driver names and authorised notes in the PDF. It never includes an ID number, telephone or email."
          },
          "transportista": {
            "$ref": "#/components/schemas/Transportista"
          },
          "vehiculo": {
            "$ref": "#/components/schemas/Vehiculo"
          },
          "conductores": {
            "type": "array",
            "minItems": 1,
            "maxItems": 2,
            "items": {
              "$ref": "#/components/schemas/Conductor"
            },
            "description": "Distinct driver IDs."
          },
          "grupos": {
            "type": "array",
            "minItems": 1,
            "maxItems": 100,
            "items": {
              "$ref": "#/components/schemas/Grupo"
            },
            "description": "Maximum per document: 200 destinations and 1,000 lines."
          },
          "cargador": {
            "$ref": "#/components/schemas/Cargador"
          }
        }
      },
      "Lote": {
        "type": "object",
        "required": [
          "documentos"
        ],
        "properties": {
          "documentos": {
            "type": "array",
            "minItems": 1,
            "maxItems": 20,
            "items": {
              "$ref": "#/components/schemas/Documento"
            }
          }
        }
      },
      "Exito": {
        "type": "object",
        "required": [
          "resultado",
          "doc_Id",
          "numeroDocumento",
          "urlAcceso",
          "repetido",
          "incluirConductorPdf",
          "notificacion",
          "avisos"
        ],
        "properties": {
          "resultado": {
            "type": "string",
            "enum": [
              "OK"
            ]
          },
          "doc_Id": {
            "type": "string",
            "format": "uuid"
          },
          "numeroDocumento": {
            "type": "string"
          },
          "urlAcceso": {
            "type": "string",
            "format": "uri"
          },
          "repetido": {
            "type": "boolean"
          },
          "incluirConductorPdf": {
            "type": "boolean"
          },
          "notificacion": {
            "type": "object",
            "required": [
              "canal",
              "estado"
            ],
            "properties": {
              "canal": {
                "type": "string",
                "enum": [
                  "EMAIL",
                  "WHATSAPP",
                  "TELEGRAM",
                  "SMS"
                ]
              },
              "estado": {
                "type": "string",
                "enum": [
                  "NO_CONFIGURADO"
                ]
              }
            }
          },
          "avisos": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "numeroEmpresa": {
            "type": "integer",
            "format": "int64",
            "minimum": 1,
            "readOnly": true,
            "description": "Sequential and immutable DeCA number within a company. Read-only. It does not replace the global ID used in requests and URLs."
          }
        }
      },
      "Error": {
        "type": "object",
        "required": [
          "resultado",
          "errores"
        ],
        "properties": {
          "http": {
            "type": "integer"
          },
          "resultado": {
            "type": "string"
          },
          "errores": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "campo",
                "mensaje"
              ],
              "properties": {
                "campo": {
                  "type": "string"
                },
                "mensaje": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "ResultadoLote": {
        "type": "object",
        "required": [
          "resultado",
          "documentos"
        ],
        "properties": {
          "resultado": {
            "type": "string",
            "enum": [
              "LOTE_PROCESADO"
            ]
          },
          "documentos": {
            "type": "array",
            "items": {
              "allOf": [
                {
                  "type": "object",
                  "required": [
                    "indice",
                    "http"
                  ],
                  "properties": {
                    "indice": {
                      "type": "integer",
                      "minimum": 0
                    },
                    "http": {
                      "type": "integer"
                    }
                  }
                },
                {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/Exito"
                    },
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              ]
            }
          }
        }
      },
      "Cargador": {
        "oneOf": [
          {
            "type": "object",
            "required": [
              "idCliente"
            ],
            "properties": {
              "idCliente": {
                "type": "integer",
                "minimum": 1,
                "description": "Active entity in the same company with the customer/consignor role."
              }
            }
          },
          {
            "type": "object",
            "required": [
              "razonSocial",
              "domicilio",
              "nif"
            ],
            "properties": {
              "razonSocial": {
                "type": "string",
                "minLength": 1,
                "maxLength": 150
              },
              "domicilio": {
                "type": "string",
                "minLength": 1,
                "maxLength": 200
              },
              "nif": {
                "type": "string",
                "minLength": 1,
                "maxLength": 20
              },
              "contacto": {
                "type": "string",
                "maxLength": 150,
                "nullable": true
              },
              "telefono": {
                "type": "string",
                "maxLength": 30,
                "nullable": true
              },
              "email": {
                "type": "string",
                "maxLength": 150,
                "nullable": true,
                "format": "email"
              }
            }
          }
        ],
        "description": "Optional. Use either idCliente or full details. When omitted, backwards-compatible behaviour is retained and the account company acts as the contractual consignor."
      }
    }
  }
}
