Skip to main content
Las integraciones externas permiten conectar sistemas de terceros (ERPs, tiendas en línea, aplicaciones propias) con FileXpress Hub mediante una API REST autenticada con credenciales propias.

Crear una integración

1

Ir a Gestión → Integraciones → Nueva Integración

2

Ingresar el nombre descriptivo de la integración (mínimo 3 caracteres)

3

Seleccionar los endpoints permitidos

EndpointDatos accesibles
VentasFacturas y documentos de venta
GastosCompras y gastos registrados
ClientesDirectorio de clientes
ProductosCatálogo de productos
4

Configurar el rate limit (solicitudes por minuto, máximo 1,000 — por defecto 100)

5

Guardar

El sistema genera el API Key y API Secret. Copiarlos antes de cerrar el modal — el Secret no se vuelve a mostrar completo.
El API Secret solo se muestra una vez. Si se pierde, debe regenerarse desde el listado de integraciones (invalida el anterior).

Gestionar credenciales

Desde el listado de integraciones:
  • Activar / Desactivar sin eliminar la integración.
  • Regenerar API Key — nuevo key, el anterior deja de funcionar.
  • Regenerar API Secret — nuevo secret, el anterior deja de funcionar.

Estadísticas y logs

  • Estadísticas: volumen total, solicitudes exitosas, errores, tiempo promedio de respuesta, último uso, desglose por endpoint y errores recientes.
  • Logs: historial paginado de cada llamada con estado HTTP, duración y cuerpo de respuesta.

Autenticación

Todas las solicitudes deben incluir las dos cabeceras:
x-api-key: TU_API_KEY
x-api-secret: TU_API_SECRET
URL base: https://api.filexpress.app/api/external
CódigoCausa
401Credenciales inválidas, desactivadas o cabeceras ausentes
403Endpoint no incluido en los permisos de la integración, o recurso de otro negocio
404Recurso no encontrado
422Error de validación — revisar errors en el cuerpo de la respuesta
429Rate limit excedido
500Error interno — reportar con el log del request

Obtener el branch_id

El branch_id es un UUID requerido en la mayoría de endpoints. Se obtiene desde la vista de soporte del panel de administración de FileXpress (Support → Sucursales), donde se listan todos los IDs de sucursales del negocio.

Ventas

Crear venta

POST /api/external/sales
Este endpoint requiere que el sistema externo pre-calcule los desgloses fiscales por línea de producto y los totales globales. No los calcula automáticamente.
Cuerpo de la solicitud
{
  "branch_id": "uuid",
  "customer_id": "uuid",
  "document_type": "fc",
  "date": "2025-06-01T10:00:00",
  "observation": "Entrega en bodega central",
  "is_credit": false,
  "credit_days": 0,
  "payment_details": [
    {
      "code": "01",
      "payment_method": "Efectivo",
      "amount": 22.60,
      "reference": ""
    }
  ],
  "products": [
    {
      "id": "uuid-del-producto",
      "sku": "PRD-001",
      "name": "Producto A",
      "quantity": 2,
      "price_before_taxes": 10.00,
      "sale_not_suject": 0,
      "sale_exent": 0,
      "sale_taxed": 20.00,
      "subtotal": 20.00,
      "discount": 0,
      "type": "phisical"
    }
  ],
  "totals": {
    "netTotals": 20.00,
    "saleTotalNotSuject": 0,
    "saleTotalExent": 0,
    "saleTotalTax": 20.00,
    "totalTax": 2.60,
    "totalRetein": 0,
    "totalRent": 0,
    "freight": 0,
    "insurance": 0,
    "saleTotalToPayment": 22.60
  }
}
Campos principales
CampoTipoRequeridoDescripción
branch_iduuidSucursal que emite la venta
customer_iduuidCliente receptor
document_typestringfc (Factura Consumidor), ccf (Crédito Fiscal), fex (Exportación), nc (Nota Crédito), nd (Nota Débito), nr (Nota Remisión)
datedatetimeNoFecha/hora de emisión (ISO 8601). Por defecto: ahora
observationstringNoObservaciones del documento
is_creditbooleanNoSi la venta es al crédito (defecto false)
credit_daysintegerNoDías de crédito (requiere is_credit: true)
productsarrayLíneas de detalle (mínimo 1)
payment_detailsarrayMétodos de pago utilizados (mínimo 1)
totalsarrayTotales globales del documento
Estructura products[]
CampoTipoDescripción
iduuidID del producto en FileXpress (opcional pero recomendado)
skustringCódigo SKU del producto
namestringNombre del producto tal como aparecerá en el documento
quantitynumberCantidad vendida
price_before_taxesnumberPrecio unitario sin impuestos
sale_not_sujectnumberSubtotal de ventas no sujetas de esta línea
sale_exentnumberSubtotal de ventas exentas de esta línea
sale_taxednumberSubtotal de ventas gravadas de esta línea (price_before_taxes × quantity)
subtotalnumberTotal de la línea sin impuestos
discountnumberDescuento en dólares aplicado a la línea
typestringphisical (bien) o service
Estructura payment_details[]
CampoTipoDescripción
codestringCódigo del método de pago — ver GET /payment-methods
payment_methodstringNombre descriptivo del método (ej: “Efectivo”, “Tarjeta”)
amountnumberMonto pagado con este método
referencestringReferencia de transacción (número de cheque, autorización, etc.)
Estructura totals
CampoTipoDescripción
netTotalsnumberSuma de subtotales de todas las líneas antes de impuestos
saleTotalNotSujectnumberTotal de ventas no sujetas
saleTotalExentnumberTotal de ventas exentas
saleTotalTaxnumberTotal de ventas gravadas (base imponible)
totalTaxnumberMonto total de IVA (saleTotalTax × 0.13)
totalReteinnumberTotal de retenciones (0 si no aplica)
totalRentnumberTotal de renta (0 si no aplica)
freightnumberFlete (0 si no aplica)
insurancenumberSeguro (0 si no aplica)
saleTotalToPaymentnumberTotal a pagar (saleTotalTax + totalTax + saleTotalExent + saleTotalNotSuject)
Respuesta exitosa 200
{
  "status": true,
  "data": {
    "sale_id": "uuid",
    "generation_code": "GC-2025-001",
    "control_number": "DTE-01-0001-000000001",
    "status": "processed",
    "issue_time": "2025-06-01T10:30:00Z",
    "stamp": "...",
    "total": 22.60
  }
}

Obtener venta

GET /api/external/sales/{sale_id}
Respuesta exitosa 200
{
  "status": true,
  "data": {
    "sale_id": "uuid",
    "generation_code": "GC-2025-001",
    "control_number": "DTE-01-0001-000000001",
    "document_type": "fc",
    "status": "processed",
    "issue_time": "2025-06-01T10:30:00Z",
    "stamp": "...",
    "payment_status": "paid",
    "is_credit": false,
    "customer": {
      "id": "uuid",
      "legal_name": "Razón Social S.A.",
      "customer_name": "Nombre Comercial"
    },
    "totals": {
      "sale_total": 22.60,
      "sale_to_payment": 22.60
    },
    "products": [
      {
        "name": "Producto A",
        "quantity": 2,
        "individual_price": 10.00,
        "subtotal": 20.00
      }
    ]
  }
}

Gastos

Crear gasto

POST /api/external/expenses
Al igual que ventas, el sistema externo debe pre-calcular los desgloses fiscales por línea y los totales globales.
Cuerpo de la solicitud
{
  "branch_id": "uuid",
  "provider_id": "uuid",
  "document_type": "ccf",
  "date": "2025-06-01",
  "observation": "Compra de insumos",
  "is_credit": false,
  "credit_days": 0,
  "number_control": "DTE-03-...",
  "generation_code": null,
  "stamp": null,
  "products": [
    {
      "sku": "INS-001",
      "name": "Insumo A",
      "type": "goods",
      "quantity": 5,
      "price_before_taxes": 8.00,
      "expense_not_suject": 0,
      "expense_exent": 0,
      "expense_taxed": 40.00,
      "subtotal": 40.00
    }
  ],
  "totals": {
    "netTotals": 40.00,
    "charge_1": 0,
    "charge_2": 0,
    "expenseTotalTax": 40.00,
    "totalRent": 0,
    "totalTax": 5.20,
    "totalRetein": 0,
    "expenseTotalToPayment": 45.20
  }
}
Campos principales
CampoTipoRequeridoDescripción
branch_iduuidSucursal que registra el gasto
provider_iduuidProveedor emisor del documento
document_typestringfse (Factura Sujeto Excluido), ccf (Crédito Fiscal), ticket
datedateFecha del documento (YYYY-MM-DD)
is_creditbooleanSi es al crédito
credit_daysintegerNoDías de crédito
number_controlstringNoNúmero de control del documento físico
generation_codestringNoCódigo de generación del DTE
stampstringNoSello electrónico
productsarrayLíneas de detalle
totalsarrayTotales globales
Estructura products[] para gastos
CampoTipoDescripción
skustringCódigo del producto/servicio
namestringDescripción de la línea
typestringgoods (bien) o services (servicio)
quantitynumberCantidad
price_before_taxesnumberPrecio unitario sin impuestos
expense_not_sujectnumberMonto no sujeto de la línea
expense_exentnumberMonto exento de la línea
expense_taxednumberMonto gravado de la línea
subtotalnumberTotal de la línea
Estructura totals para gastos
CampoTipoDescripción
netTotalsnumberSuma de subtotales antes de impuestos
charge_1numberCargo adicional 1 (0 si no aplica)
charge_2numberCargo adicional 2 (0 si no aplica)
expenseTotalTaxnumberBase imponible gravada total
totalRentnumberRenta retenida (0 si no aplica)
totalTaxnumberMonto total de IVA
totalReteinnumberRetenciones (0 si no aplica)
expenseTotalToPaymentnumberTotal a pagar
Respuesta exitosa 200
{
  "status": true,
  "data": {
    "expense_id": "uuid",
    "generation_code": null,
    "control_number": "DTE-03-...",
    "status": "processed",
    "issue_time": "2025-06-01T10:00:00Z",
    "total": 45.20
  }
}

Obtener gasto

GET /api/external/expenses/{expense_id}
Devuelve el gasto con proveedor, líneas de detalle y totales (expense_total, expense_to_payment).

Clientes

Listar clientes de una sucursal

GET /api/external/customers/branch/{branch_id}
Devuelve todos los clientes activos de la sucursal (no paginado).

Obtener cliente

GET /api/external/customers/{id}

Crear cliente

POST /api/external/customers
Cuerpo de la solicitud
{
  "customer_name": "Juan Pérez",
  "legal_name": "Juan Antonio Pérez García",
  "register_number": "12345-6",
  "tax_number": "0614-000101-000-0",
  "document_type": "DUI",
  "document_number": "00000000-0",
  "address": "Col. San Benito, Av. La Revolución #123",
  "country_id": "uuid",
  "state_id": "uuid",
  "city_id": "uuid",
  "phone": "7777-1234",
  "email": "juan@example.com",
  "business_type": "non-business",
  "business_size": "",
  "activity_id": "uuid",
  "branch_id": "uuid",
  "is_exent": false,
  "is_public_institution": false
}
Campos requeridos: customer_name, address, country_id, state_id, city_id, phone, email, business_type, branch_id
CampoValores válidos
business_typenon-business (persona individual), natural (persona natural), legal (persona jurídica)
document_typeTipo de documento de identidad (DUI, pasaporte, carné de residente, etc.)
is_exenttrue = el sistema elimina el IVA al facturar a este cliente
is_public_institutiontrue = entidad gubernamental — restringe los tipos de DTE disponibles
Respuesta 200: objeto del cliente creado con id.

Actualizar cliente

PUT /api/external/customers/{id}
Mismos campos requeridos que la creación. Acepta además: legal_name, register_number, tax_number, document_type, document_number, activity_id, business_size.

Eliminar cliente

DELETE /api/external/customers/{id}
Borrado lógico (trashed = true). Responde 200 con confirmación.

Productos

Listar productos de una sucursal

GET /api/external/products/branch/{branch_id}

Obtener producto

GET /api/external/products/{id}
Incluye portions y components si el producto tiene composición avanzada.

Crear producto

POST /api/external/products
Cuerpo de la solicitud
{
  "name": "Refresco 350ml",
  "sku": "BEB-001",
  "price_before_taxes": 1.11,
  "cost": 0.70,
  "tax_method": "is_taxed",
  "composition_type": "simple",
  "product_type": "phisical",
  "product_category_id": "uuid",
  "product_measurement_id": "uuid",
  "branch_id": "uuid",
  "availability": 100,
  "limit_availability": 10
}
Campos requeridos: name, price_before_taxes, product_category_id, product_measurement_id, product_type, tax_method, composition_type, branch_id, availability, limit_availability
CampoValores válidos
tax_methodis_taxed (gravado), is_exent (exento), is_not_subject (no sujeto)
composition_typesimple, with_portions, with_recipe
product_typephisical (bien), service (servicio), both
Con porciones (composition_type: with_portions) — campos adicionales:
{
  "base_unit_quantity": 1000,
  "base_unit": "ml",
  "portions": [
    {
      "portion_name": "Vaso 250ml",
      "portion_quantity": 250,
      "portion_unit": "ml",
      "portion_price": 0.44,
      "is_active": true
    }
  ]
}
Con receta (composition_type: with_recipe) — campos adicionales:
{
  "components": [
    {
      "component_product_id": "uuid-ingrediente",
      "quantity_needed": 2,
      "unit_type": "base"
    }
  ]
}
Al crear un producto físico con availability > 0, se registra automáticamente un movimiento de inventario de entrada.

Actualizar producto

PUT /api/external/products/{id}
Acepta los mismos campos. Si cambia availability, se genera un movimiento de ajuste automático. Al cambiar composition_type, las porciones o componentes anteriores se eliminan y reemplazan.

Eliminar producto

DELETE /api/external/products/{id}
Borrado lógico. Responde 200 con confirmación.

Proveedores

Listar proveedores de una sucursal

GET /api/external/providers/branch/{branch_id}

Crear proveedor

POST /api/external/providers
El cuerpo debe enviarse dentro de una clave data:
{
  "data": {
    "provider_name": "Distribuidora XYZ",
    "legal_name": "Distribuidora XYZ S.A. de C.V.",
    "register_number": "54321-0",
    "tax_number": "0614-000000-000-0",
    "address": "San Salvador",
    "country_id": "uuid",
    "state_id": "uuid",
    "city_id": "uuid",
    "phone": "2222-3333",
    "email": "ventas@xyz.com",
    "business_type": "legal",
    "branch_id": "uuid"
  }
}
Campos requeridos (dentro de data): provider_name, address, country_id, state_id, city_id, phone, email, business_type, branch_id

Actualizar proveedor

PUT /api/external/providers/{id}
Mismos campos que la creación (sin wrapper data en update).

Eliminar proveedor

DELETE /api/external/providers/{id}

Catálogos (solo lectura)

RecursoEndpoint
PaísesGET /countries, GET /countries/{id}
DepartamentosGET /states, GET /states/{id}, GET /states/country/{country_id}
MunicipiosGET /cities, GET /cities/{id}, GET /cities/state/{state_id}
Categorías de productoGET /product-categories, GET /product-categories/{id}
Unidades de medidaGET /product-measurements, GET /product-measurements/{id}
Actividades económicasGET /activities, GET /activities/{id}
Métodos de pagoGET /payment-methods
IncotermsGET /incoterms