Postman
  • Descargar JSON
  • Descargar YAML
Postman
  • Documentación

    • Información general
    • Entornos
    • Primeros pasos
    • Listar CFDI's
    • Buscar CFDI
    • Crear CFDI 4.0
    • Crear CFDI Global 4.0
    • Borradores CFDI 4.0
    • Descargar CFDI
    • Cancelar CFDI 4.0
    • Descargar acuse CFDI 4.0
    • Enviar CFDI
    • Consultar estatus de cancelación de un CFDI
    • Autofacturación Pro
    • Factura360
    • Referencias de pago
    • Autofacturación
    • Grupos de empleados
    • Empleados
    • Nóminas
    • Complementos
    • Retenciones
    • Complementos de retenciones
    • Carta porte v3.1
    • Catálogos
    • Clientes
    • Empresas
    • Migraciones
    • Partners
    • Series
    • Productos
    • Addendas
    • Fundamentos legales del SAT

Partners

Bienvenido a la documentación oficial del API de Partners de factura.com. Esta sección está diseñada para que puedas automatizar y gestionar todo tu ecosistema de negocio de forma centralizada a través de nuestra API.

Documentación legacy

La documentación de la versión anterior de Partners está deprecada y ya no aparece en el menú lateral, pero seguirá disponible como referencia para integraciones existentes en Partners legacy.

Con este módulo, tendrás el control total para integrar las siguientes capacidades en tu plataforma:

  • Gestión de Clientes: Crea, actualiza y administra a tus clientes de manera segura.
  • Control de Planes: Maneja tus diferentes planes paquetes que ofrecerás al mercado.
  • Administración de Suscripciones: Controla el ciclo de vida completo de las suscripciones de tus clientes.

Para el API de Partners, es necesario utilizar un metodo de autenticación basado en tokens para poder hacer peticiones.

Especificación OpenAPI

Ponemos a tu disposición la especificación OpenAPI 3.1 del API de Partners. Con ella puedes generar SDKs, autocompletar peticiones o importar todos los endpoints en tu cliente de API favorito (Postman, Insomnia, Swagger, Scalar, etc.).

Descargar JSONDescargar YAML

Cómo importarla

  • Postman: Import → pestaña File (sube el .json o .yaml) o pega la URL de descarga.
  • Insomnia: Create → Import From → URL/File y selecciona el archivo.
  • Swagger Editor / Swagger UI: usa el botón Abrir en Swagger Editor o File → Import URL.
  • Scalar: desde scalar.com crea una referencia e importa la URL del .json.

El mismo enlace de descarga está disponible en la barra de navegación superior mientras estés en esta página.

Host y modo sandbox

Todas las peticiones al API de Partners utilizan el mismo dominio para producción y sandbox:

Host: https://api-partners.factura.com/api

En los ejemplos de codigo es necesario reemplazar {HOST} por el que mencionamos arriba.

Para enviar una petición al ambiente sandbox, agrega el siguiente header:

F-Sandbox-Mode: true

Si envías F-Sandbox-Mode: false o no envías el header, la petición se procesará en producción.

Credenciales exclusivas para Sandbox

El modo Sandbox utiliza credenciales independientes de las de producción. Antes de hacer peticiones en este ambiente debes:

  1. Habilitar el modo Sandbox desde tu Panel de Partners en Configuración → Sandbox.
  2. Generar tus credenciales de API de Sandbox (Client ID y API Secret) en Configuración → API.

Usa estas credenciales de Sandbox para obtener tu token de acceso cuando envíes el header F-Sandbox-Mode: true. Las credenciales de producción no funcionan en Sandbox y viceversa.

Proceso de autenticación

A diferencia del resto de la API global de Factura.com, el API de Partners se autentica mediante el estándar OAuth 2.0, usando específicamente el flujo Client Credentials (grant_type: client_credentials).

Este flujo está diseñado para comunicación servidor a servidor (machine-to-machine): tu aplicación se identifica con sus propias credenciales —Client ID y API Secret— sin que intervenga ningún usuario final ni se requiera redirección a un navegador. A cambio, recibes un token de acceso (Bearer Token) de vida limitada que deberás incluir en cada petición a los endpoints protegidos.

En resumen, el ciclo de autenticación es:

  1. Obtén tus credenciales de aplicación (Client ID y API Secret) una sola vez desde tu Panel de Partners.
  2. Genera un token de acceso enviando esas credenciales al endpoint POST /v1/auth/token.
  3. Usa el token en el header Authorization: Bearer <access_token> de cada petición.
  4. Renueva el token solicitando uno nuevo cuando esté por expirar (ver Renovación del token).

Paso 1: Obtener tus credenciales de aplicación (Client ID y API Secret)

Antes de realizar tu primera petición, necesitas generar tus credenciales exclusivas para el API de partners desde tu Panel Administrativo:

  1. Inicia sesión en tu cuenta de Factura.com para ingresar al Panel de Partners.
  2. Dirígete al menú de Configuración -> API.
  3. Haz clic en el botón Crear aplicación.
  4. El sistema te proporcionará dos valores únicos:
    • Client ID (Identificador de tu aplicación)
    • API Secret (Llave secreta de tu aplicación)

Aviso

El API SECRET se muestra una sola vez. Guárdalo en un lugar seguro. Por tu seguridad, no volveremos a mostrarlo, ya que solo almacenamos una versión encriptada en nuestros servidores.

Paso 2: Generar el Token de Acceso

Una vez que tengas tu Client ID y API Secret, deberás utilizar esa información en los siguiente parámetros.

ParámetroTipoRequeridoDetalles
grant_typeStringRequerido En este campo, siempre debemos mandar: "client_credentials"
client_idStringRequerido Aqui debes colocar el Client_id que copiaste de la aplicación que creaste desde la interfaz de tu Panel de Partners.

Ejemplo - "client_id": "YOUR_CLIENT_ID",

client_secretStringRequerido En este campo hay que agregar el API secret que obtenemos en la interfaz de tu Panel de Partners.

Ejemplo - "client_secret": "YOUR_CLIENT_SECRET",

Construcción de la URL

Importante

Importante el metodo para agregar una referencia de pago es POST

Host: https://api-partners.factura.com/api

Endpoint: v1/auth/token

Ejemplo: https://api-partners.factura.com/api/v1/auth/token

Ejemplo de solicitar el token de acceso
POST /v1/auth/token HTTP/1.1
Host: {HOST}
Accept: application/json
Content-Type: application/json
F-Sandbox-Mode: true

{
  "grant_type": "client_credentials",
  "client_id": "YOUR_CLIENT_ID",
  "client_secret": "YOUR_CLIENT_SECRET"
}
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => '{ HOST }/v1/auth/token',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => '',
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 0,
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => 'POST',
  CURLOPT_POSTFIELDS =>'{
    "grant_type": "client_credentials",
    "client_id": "YOUR_CLIENT_ID",
    "client_secret": "YOUR_CLIENT_SECRET"
}',
  CURLOPT_HTTPHEADER => array(
    'Accept: application/json',
    'Content-Type: application/json',
    'F-Sandbox-Mode: true'
  ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;

var request = require('request');
var options = {
  'method': 'POST',
  'url': '{ HOST }/v1/auth/token',
  'headers': {
    'Accept': 'application/json',
    'Content-Type': 'application/json',
    'F-Sandbox-Mode': 'true'
  },
  body: JSON.stringify({
    "grant_type": "client_credentials",
    "client_id": "YOUR_CLIENT_ID",
    "client_secret": "YOUR_CLIENT_SECRET"
  })

};
request(options, function (error, response) {
  if (error) throw new Error(error);
  console.log(response.body);
});

import requests
import json

url = "{ HOST }/v1/auth/token"

payload = json.dumps({
  "grant_type": "client_credentials",
  "client_id": "YOUR_CLIENT_ID",
  "client_secret": "YOUR_CLIENT_SECRET"
})
headers = {
  'Accept': 'application/json',
  'Content-Type': 'application/json',
  'F-Sandbox-Mode': 'true'
}

response = requests.request("POST", url, headers=headers, data=payload)

print(response.text)

require "uri"
require "json"
require "net/http"

url = URI("{ HOST }/v1/auth/token")

http = Net::HTTP.new(url.host, url.port);
https.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Accept"] = "application/json"
request["Content-Type"] = "application/json"
request["F-Sandbox-Mode"] = "true"
request.body = JSON.dump({
  "grant_type": "client_credentials",
  "client_id": "YOUR_CLIENT_ID",
  "client_secret": "YOUR_CLIENT_SECRET"
})

response = http.request(request)
puts response.read_body

Respuesta

{
    "token_type": "Bearer",
    "expires_in": 31535999,
    "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhdWQiOiIwMTllZWMwZC0yMjhkLTcwYzgtYjE5MS0yMzliODFlMmQ1N2MiLCJqdGkiOiJiMzc0OTYyMmVmMWQ0NWU4YTljNzQ5YTE3MjJlZDQ4Zjg5NGJhZTZiMTgwYTFmMDI1YWEyMDJiMDNjNDI4NmE1MzRkM2Y5ZWF..."
}
{
    "error": "invalid_client",
    "error_description": "Client authentication failed"
}

Entendiendo la respuesta del token

La respuesta exitosa devuelve los siguientes campos:

CampoTipoDetalles
token_typeStringTipo de token. Siempre será Bearer, por lo que debe enviarse como Authorization: Bearer <access_token>.
expires_inIntegerTiempo de vida del token en segundos, contado a partir del momento en que se emitió. Cuando este tiempo transcurre, el token deja de ser válido y debes generar uno nuevo.
access_tokenStringEl token de acceso que usarás para autenticar tus peticiones. Trátalo como información sensible (equivale a una contraseña) y nunca lo expongas en código de cliente público.

Uso del token en tus peticiones

Una vez obtenido, incluye el access_token en el header Authorization de todas las peticiones a los endpoints protegidos del API de Partners:

GET /v1/products HTTP/1.1
Host: {HOST}
Accept: application/json
Authorization: Bearer YOUR_ACCESS_TOKEN
F-Sandbox-Mode: true

Si el token es inválido, está mal formado o ya expiró, el API responderá con un estatus 401 No autenticado. En ese caso deberás generar un nuevo token.

Renovación del token

El flujo Client Credentials de OAuth 2.0 no emite un refresh_token. Esto significa que no existe un endpoint de "refresco": para renovar el acceso simplemente vuelves a solicitar un token al mismo endpoint POST /v1/auth/token, reutilizando tu Client ID y API Secret.

Recomendaciones para gestionar el ciclo de vida del token de forma eficiente:

  • Reutiliza el token mientras siga vigente. No solicites uno nuevo en cada petición; cada token es válido durante el número de segundos indicado en expires_in.
  • Almacena el token y su fecha de expiración. Guarda el access_token junto con el instante en que lo obtuviste y el valor de expires_in. Calcula su vencimiento como momento_de_emisión + expires_in.
  • Solicita un nuevo token de forma anticipada. Idealmente renueva el token un poco antes de que expire (por ejemplo, con un margen de unos minutos) para evitar peticiones fallidas por una expiración a mitad de operación.
  • Maneja el 401 de forma reactiva. Si una petición devuelve 401 No autenticado, genera un token nuevo y reintenta la operación una sola vez.

Consejos

Como el access_token reemplaza por completo al anterior, no necesitas invalidar el token previo: basta con empezar a usar el nuevo. Cada vez que generas un token, el contador de expires_in se reinicia.

Consultar tus planes

Este endpoint permite obtener un listado paginado de todos los planes (productos) que has creado y configurado previamente desde tu panel de control.

El endpoint incluye soporte nativo para paginación, filtros de búsqueda por nombre y ordenamiento avanzado, lo que te permite optimizar la carga de datos en tu plataforma.

Construcción de la URL

Importante

Importante el metodo para agregar una referencia de pago es GET

Host: https://api-partners.factura.com/api

Endpoint: v1/products

Ejemplo: https://api-partners.factura.com/api/v1/products

Utilice los siguientes parámetros opcionales en la URL para filtrar los resultados por nombre del plan, o para aplicar paginación u ordenamiento en la respuesta:

ParámetroTipoRequeridoDetalles
namestringOpcional

Indica el nombre del plan que se quiere consultar, puede estar completo o no.

Ejemplo: /api/v1/products?name=paquete

sortstringOpcional

Define el orden de los resultados. Utiliza el prefijo + para orden ascendente y - para descendente.
Valores permitidos: +sales, -sales, +name, -name, +created_at, -created_at.

Ejemplo: /api/v1/products?sort=+sales

per_pageIntegerOpcional Indica el limite de resultados para mostrar, por default retorna todos los planes del catálogo.

Ejemplo: /api/v1/products?per_page=3

pageIntegerOpcional Indica número de página a consultar, por default posiciona en la página 1.

Ejemplo: /api/v1/products?page=2

Ejemplo de petición
GET /v1/products HTTP/1.1
Host: {HOST}
Accept: application/json
Authorization: Bearer YOUR_ACCESS_TOKEN
F-Sandbox-Mode: true
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => '{ HOST }/v1/products',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => '',
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 0,
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => 'GET',
  CURLOPT_HTTPHEADER => array(
    'Accept: application/json',
    'Authorization: Bearer YOUR_ACCESS_TOKEN',
    'F-Sandbox-Mode: true'
  ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;
var request = require('request');
var options = {
  'method': 'GET',
  'url': '{ HOST }/v1/products',
  'headers': {
    'Accept': 'application/json',
    'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
    'F-Sandbox-Mode': 'true'
  }
};
request(options, function (error, response) {
  if (error) throw new Error(error);
  console.log(response.body);
});
import requests

url = "{ HOST }/v1/products"

headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
  'F-Sandbox-Mode': 'true'
}

response = requests.request("GET", url, headers=headers)

print(response.text)
require "uri"
require "net/http"

url = URI("{ HOST }/v1/products")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Accept"] = "application/json"
request["Authorization"] = "Bearer YOUR_ACCESS_TOKEN"
request["F-Sandbox-Mode"] = "true"

response = http.request(request)
puts response.read_body

Respuesta

{
    "response": "success",
    "data": {
        "products": [
            {
                "uuid": "a21062196ea748e4a3e08280765fab75",
                "name": "PLAN adicional",
                "services": {
                    "api": false,
                    "smtp": true,
                    "custom_email": false,
                    "auto_invoices": false,
                    "invoices_migrator": false,
                    "clients": 0,
                    "extra_rfc": 0,
                    "extra_user": 0
                },
                "sales": 1,
                "expiration_type": 0,
                "status": "active",
                "vigencies": [
                    {
                        "uuid": "a2106219c219440d8d03836f8d51171e",
                        "folios": 60,
                        "price": "400.00",
                        "expiration_period": "Sin periodicidad de expiración"
                    }
                ],
                "pdf_templates": [
                    "default",
                    "classic",
                    "formal"
                ]
            },
        ],
        "pagination": {
            "currentPage": 1,
            "lastPage": 1,
            "perPage": 15,
            "total": 5
        }
    }
}

{
    "status": "error",
    "message": "Unauthenticated.",
    "code": "SERVER_ERROR"
}
Parámetros de respuesta
ParámetroTipoDetalles
 response String Estado general de la respuesta.
 data.products Array Listado de productos o planes encontrados.
 data.products[] Object Objeto con la información de cada producto.
 data.products[].uuid String UUID del producto.
 data.products[].name String Nombre del producto.
 data.products[].services Object Configuración de servicios del producto.
 data.products[].services.api Booleano Indica si el producto incluye acceso a la API.
 data.products[].services.smtp Booleano Indica si el producto incluye servicio SMTP.
 data.products[].services.custom_email Booleano Indica si el producto incluye correo personalizado.
 data.products[].services.auto_invoices Booleano Indica si el producto incluye autofacturación.
 data.products[].services.invoices_migrator Booleano Indica si el producto incluye migrador de facturas.
 data.products[].services.clients Numérico Cantidad de clientes incluidos.
 data.products[].services.extra_rfc Numérico Cantidad de RFC adicionales incluidos.
 data.products[].services.extra_user Numérico Cantidad de usuarios adicionales incluidos.
 data.products[].sales Numérico Cantidad de ventas asociadas al producto.
 data.products[].expiration_type Numérico Tipo de expiración configurado para el producto.
 data.products[].status String Estatus actual del producto.
 data.products[].vigencies Array Listado de vigencias disponibles para el producto.
 data.products[].vigencies[] Object Objeto con la información de cada vigencia.
 data.products[].vigencies[].uuid String UUID de la vigencia.
 data.products[].vigencies[].folios Numérico Cantidad de folios incluidos en la vigencia.
 data.products[].vigencies[].price String Precio configurado para la vigencia.
 data.products[].vigencies[].expiration_period String Periodo de expiración de la vigencia.
 data.products[].pdf_templates Array Lista de plantillas PDF autorizadas.
 data.products[].pdf_templates[] String Nombre de cada plantilla PDF autorizada.
 data.pagination Object Información de paginación del listado.
 data.pagination.currentPage Numérico Página actual de resultados.
 data.pagination.lastPage Numérico Última página disponible.
 data.pagination.perPage Numérico Cantidad de elementos por página.
 data.pagination.total Numérico Total de productos encontrados.

Crear planes

Este endpoint permite registrar un nuevo plan (producto) dentro de tu catálogo desde la API. Al crearlo, puedes definir su vigencia, precios, folios incluidos y activar o desactivar características específicas (servicios) que tendrá disponibles el cliente que adquiera dicho plan.

Podemos crear un nuevo plan haciendo uso de los siguientes parámetros:

ParámetroTipoRequeridoDetalles
 name String Requerido Sirve para indicar el nombre que queremos ponerle al plan.
 vigencies Array Requerido Nodo para definir el tipo de vigencia y el tiempo del plan, la cantidad de folios y el precio.
 vigencies[].folios Numérico Requerido Elemento para indicar cuantos folios cargara el plan al clinete.
 vigencies[].vigency String Requerido Periodo de validez del plan. Valores aceptados:
• "Mensual"
• "Trimestral"
• "Semestral"
• "Anual"
• "SP" (sin periodicidad)
 vigencies[].price Numérico Requerido Elemento para marcar el precio del plan. Esto servira para tus estadisticas mensuales.
 services Objeto Requerido Nodo contenedor con las configuraciones y características técnicas activas en el plan.
Las funciones que se envíen como true (ej. smtp_mail) dependen estrictamente de que el Partner las tenga incluidas en su plan.
 services.api Booleano Opcional Define si la cuenta tendrá habilitado el acceso a las funciones de la API. 
 services.smtp_mail Booleano Opcional Indica si la cuenta a crearse tendrá habilitadas las funciones de smtp para email.
 services.custom_email Booleano Opcional Indica si la cuenta a crearse tendrá habilitadas las funciones de un email personalizado.
 services.pdf_templates Array Requerido Lista de cadenas con los nombres de las plantillas PDF autorizadas para el plan (ej. "default", "classic").
 services.pdf_templates[] String Requerido Nombre de cada plantilla PDF autorizada para el plan.
 services.invoices_migrator Booleano Opcional Activa la herramienta interna para migrar facturas o CFDI previos de los clientes.
 services.auto_invoice Booleano Opcional Indica si se habilita el autofacturador para el usuario.
 services.extra_rfc Numérico Opcional Se ingresa el número de los RFC extra que se desean agregar a la cuenta.
 services.extra_user Numérico Opcional Se ingresa la Cantidad de usuarios adicionales que pueden tener acceso a la cuenta.

Construcción de la URL

Importante

Importante el metodo para agregar una referencia de pago es POST

Host: https://api-partners.factura.com/api

Endpoint: v1/products

Ejemplo: https://api-partners.factura.com/api/v1/products

Ejemplo de crear plan
POST /v1/products HTTP/1.1
Host: {HOST}
Accept: application/json
Content-Type: application/json
Authorization: Bearer YOUR_ACCESS_TOKEN
F-Sandbox-Mode: true

{
  "name": "Plan especial",
  "vigencies": [
    {
      "folios": 50,
      "vigency": "Mensual",
      "price": 490.00
    }
  ],
  "services": {
    "api": false,
    "smtp_mail": true,
    "custom_email": true,
    "pdf_templates": ["default", "classic"],
    "invoices_migrator": false,
    "auto_invoice": false,
    "extra_rfc": 3,
    "extra_user": 1
  }
}
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => '{ HOST }/v1/products',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => '',
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 0,
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => 'POST',
  CURLOPT_POSTFIELDS =>'{
    "name": "Plan especial",
    "vigencies": [
        {
            "folios": 50,
            "vigency": "Mensual",
            "price": 490.00
        }
    ],
    "services": {
        "api": false,
        "smtp_mail": true,
        "custom_email": true,
        "pdf_templates": [
            "default",
            "classic"
        ],
        "invoices_migrator": false,
        "auto_invoice": false,
        "extra_rfc": 3,
        "extra_user": 1
    }
}',
  CURLOPT_HTTPHEADER => array(
    'Accept: application/json',
    'Content-Type: application/json',
    'Authorization: ••••••',
    'F-Sandbox-Mode: true'
  ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;

var request = require('request');
var options = {
  'method': 'POST',
  'url': '{ HOST }/v1/products',
  'headers': {
    'Accept': 'application/json',
    'Content-Type': 'application/json',
    'Authorization': '••••••',
    'F-Sandbox-Mode': 'true'
  },
  body: JSON.stringify({
    "name": "Plan especial",
    "vigencies": [
      {
        "folios": 50,
        "vigency": "Mensual",
        "price": 490
      }
    ],
    "services": {
      "api": false,
      "smtp_mail": true,
      "custom_email": true,
      "pdf_templates": [
        "default",
        "classic"
      ],
      "invoices_migrator": false,
      "auto_invoice": false,
      "extra_rfc": 3,
      "extra_user": 1
    }
  })

};
request(options, function (error, response) {
  if (error) throw new Error(error);
  console.log(response.body);
});

import requests
import json

url = "{ HOST }/v1/products"

payload = json.dumps({
  "name": "Plan especial",
  "vigencies": [
    {
      "folios": 50,
      "vigency": "Mensual",
      "price": 490
    }
  ],
  "services": {
    "api": False,
    "smtp_mail": True,
    "custom_email": True,
    "pdf_templates": [
      "default",
      "classic"
    ],
    "invoices_migrator": False,
    "auto_invoice": False,
    "extra_rfc": 3,
    "extra_user": 1
  }
})
headers = {
  'Accept': 'application/json',
  'Content-Type': 'application/json',
  'Authorization': '••••••',
  'F-Sandbox-Mode': 'true'
}

response = requests.request("POST", url, headers=headers, data=payload)

print(response.text)

require "uri"
require "json"
require "net/http"

url = URI("{ HOST }/v1/products")

http = Net::HTTP.new(url.host, url.port);
https.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Accept"] = "application/json"
request["Content-Type"] = "application/json"
request["F-Sandbox-Mode"] = "true"
request["Authorization"] = "••••••"
request.body = JSON.dump({
  "name": "Plan especial",
  "vigencies": [
    {
      "folios": 50,
      "vigency": "Mensual",
      "price": 490
    }
  ],
  "services": {
    "api": false,
    "smtp_mail": true,
    "custom_email": true,
    "pdf_templates": [
      "default",
      "classic"
    ],
    "invoices_migrator": false,
    "auto_invoice": false,
    "extra_rfc": 3,
    "extra_user": 1
  }
})

response = http.request(request)
puts response.read_body

Respuesta

{
    "response": "success",
    "data": {
        "uuid": "a2151fa2877f4d0a9781aa3fa275c0d6",
        "name": "Plan 3",
        "services": {
            "api": false,
            "smtp": false,
            "custom_email": false,
            "auto_invoices": false,
            "invoices_migrator": false,
            "clients": 0,
            "extra_rfc": 0,
            "extra_user": 0
        },
        "sales": 0,
        "expiration_type": false,
        "status": null,
        "vigencies": [
            {
                "uuid": "a2151fa2968e4879b029cc095d5e35f6",
                "folios": 50,
                "price": "490.00",
                "expiration_period": "Mensual"
            }
        ],
        "pdf_templates": [
            "default"
        ]
    }
}
{
    "status": "error",
    "message": "Error de validación de datos.",
    "errors": {
        "services.pdf_templates": [
            "The services.pdf templates field is required."
        ]
    },
    "code": "VALIDATION_FAILED"
}

Actualizar plan

Este endpoint permite modificar y actualizar la configuración de un plan (producto) ya existente dentro de tu catálogo desde la API. A través de esta petición, puedes editar de forma dinámica el nombre del plan, ajustar sus esquemas de vigencia y precios, o reconfigurar las características y servicios técnicos que tus clientes tendrán activos al adquirir o renovar dicho plan.

Para poder actualizar un plan existende podemos usar los siguientes parámetros:

ParámetroTipoRequeridoDetalles
 name String Requerido Sirve para indicar el nombre que queremos ponerle al plan.
 vigencies Array Requerido Nodo para definir el tipo de vigencia y el tiempo del plan, la cantidad de folios y el precio.
 vigencies[].folios Numérico Requerido Elemento para indicar cuantos folios cargara el plan al clinete.
 vigencies[].vigency String Requerido Periodo de validez del plan. Valores aceptados:
• "Mensual"
• "Trimestral"
• "Semestral"
• "Anual"
• "SP" (sin periodicidad)
 vigencies[].price Numérico Requerido Elemento para marcar el precio del plan. Esto servira para tus estadisticas mensuales.
 services Objeto Requerido Nodo contenedor con las configuraciones y características técnicas activas en el plan.
Las funciones que se envíen como true (ej. smtp_mail) dependen estrictamente de que el Partner las tenga incluidas en su plan.
 services.api Booleano Opcional Define si la cuenta tendrá habilitado el acceso a las funciones de la API. 
 services.smtp_mail Booleano Opcional Indica si la cuenta a crearse tendrá habilitadas las funciones de smtp para email.
 services.custom_email Booleano Opcional Indica si la cuenta a crearse tendrá habilitadas las funciones de un email personalizado.
 services.pdf_templates Array Requerido Lista de cadenas con los nombres de las plantillas PDF autorizadas para el plan (ej. "default", "classic").
 services.pdf_templates[] String Requerido Nombre de cada plantilla PDF autorizada para el plan.
 services.invoices_migrator Booleano Opcional Activa la herramienta interna para migrar facturas o CFDI previos de los clientes.
 services.auto_invoice Booleano Opcional Indica si se habilita el autofacturador para el usuario.
 services.extra_rfc Numérico Opcional Se ingresa el número de los RFC extra que se desean agregar a la cuenta.
 services.extra_user Numérico Opcional Se ingresa la Cantidad de usuarios adicionales que pueden tener acceso a la cuenta.

Construcción de la URL

Importante

Importante el metodo para agregar una referencia de pago es PATCH

Host: https://api-partners.factura.com/api

Endpoint: v1/products/UUID del plan

Ejemplo: https://api-partners.factura.com/api/v1/products/a2151fa2877f4d0a9781aa3fa275c0d6

Ejemplo de actualizar plan
PATCH /v1/products/{uuid} HTTP/1.1
Host: {HOST}
Accept: application/json
Content-Type: application/json
Authorization: Bearer YOUR_ACCESS_TOKEN
F-Sandbox-Mode: true

{
  "name": "PLAN EDITADO",
  "vigencies": [
    {
      "folios": 60,
      "vigency": "Trimestral",
      "price": 790.00
    }
  ],
  "services": {
    "api": true,
    "smtp_mail": true,
    "custom_email": true,
    "auto_invoices": true,
    "invoices_migrator": false,
    "extra_rfc": 1,
    "extra_user": 1,
    "pdf_templates": ["default", "classic"]
  }
}
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => '{ HOST }/v1/products/a2151fa2877f4d0a9781aa3fa275c0d6',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => '',
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 0,
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => 'PATCH',
  CURLOPT_POSTFIELDS =>'{
    "name": "PLAN EDITADO",
        "vigencies": [
        {
            "folios": 60,
            "vigency": "Trimestral",
            "price": 790.00
        }
    ],
    "services": {
    "api": true,
    "smtp_mail": true,
    "custom_email": true,
    "auto_invoices": true,
    "invoices_migrator": false,
    "extra_rfc": 1,
    "extra_user": 1,
    "pdf_templates": ["default",
    "classic"
    ]
  }
}',
  CURLOPT_HTTPHEADER => array(
    'Accept: application/json',
    'Content-Type: application/json',
    'Authorization: ••••••',
    'F-Sandbox-Mode: true'
  ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;

var request = require('request');
var options = {
  'method': 'PATCH',
  'url': '{ HOST }/v1/products/a2151fa2877f4d0a9781aa3fa275c0d6',
  'headers': {
    'Accept': 'application/json',
    'Content-Type': 'application/json',
    'Authorization': '••••••',
    'F-Sandbox-Mode': 'true'
  },
  body: JSON.stringify({
    "name": "PLAN EDITADO",
    "vigencies": [
      {
        "folios": 60,
        "vigency": "Trimestral",
        "price": 790
      }
    ],
    "services": {
      "api": true,
      "smtp_mail": true,
      "custom_email": true,
      "auto_invoices": true,
      "invoices_migrator": false,
      "extra_rfc": 1,
      "extra_user": 1,
      "pdf_templates": [
        "default",
        "classic"
      ]
    }
  })

};
request(options, function (error, response) {
  if (error) throw new Error(error);
  console.log(response.body);
});

import requests
import json

url = "{ HOST }/v1/products/a2151fa2877f4d0a9781aa3fa275c0d6"

payload = json.dumps({
  "name": "PLAN EDITADO",
  "vigencies": [
    {
      "folios": 60,
      "vigency": "Trimestral",
      "price": 790
    }
  ],
  "services": {
    "api": True,
    "smtp_mail": True,
    "custom_email": True,
    "auto_invoices": True,
    "invoices_migrator": False,
    "extra_rfc": 1,
    "extra_user": 1,
    "pdf_templates": [
      "default",
      "classic"
    ]
  }
})
headers = {
  'Accept': 'application/json',
  'Content-Type': 'application/json',
  'Authorization': '••••••',
  'F-Sandbox-Mode': 'true'
}

response = requests.request("PATCH", url, headers=headers, data=payload)

print(response.text)

require "uri"
require "json"
require "net/http"

url = URI("{ HOST }/v1/products/a2151fa2877f4d0a9781aa3fa275c0d6")

http = Net::HTTP.new(url.host, url.port);
https.use_ssl = true
request = Net::HTTP::Patch.new(url)
request["Accept"] = "application/json"
request["Content-Type"] = "application/json"
request["F-Sandbox-Mode"] = "true"
request["Authorization"] = "••••••"
request.body = JSON.dump({
  "name": "PLAN EDITADO",
  "vigencies": [
    {
      "folios": 60,
      "vigency": "Trimestral",
      "price": 790
    }
  ],
  "services": {
    "api": true,
    "smtp_mail": true,
    "custom_email": true,
    "auto_invoices": true,
    "invoices_migrator": false,
    "extra_rfc": 1,
    "extra_user": 1,
    "pdf_templates": [
      "default",
      "classic"
    ]
  }
})

response = http.request(request)
puts response.read_body

Respuesta

{
    "response": "success",
    "data": {
        "uuid": "a2151fa2877f4d0a9781aa3fa275c0d6",
        "name": "PLAN EDITADO",
        "services": {
            "api": true,
            "smtp": true,
            "custom_email": true,
            "auto_invoices": true,
            "invoices_migrator": false,
            "clients": 5,
            "extra_rfc": 1,
            "extra_user": 1
        },
        "sales": 0,
        "expiration_type": 0,
        "status": "active",
        "vigencies": [
            {
                "uuid": "a2152b157b4949fab99b1085bd4186b3",
                "folios": 60,
                "price": "790.00",
                "expiration_period": "Trimestral"
            }
        ],
        "pdf_templates": [
            "default",
            "classic"
        ]
    }
}
{
    "status": "error",
    "message": "El recurso solicitado no fue encontrado.",
    "code": "NOT_FOUND"
}

Borrar planes

Este endpoint permite eliminar uno o múltiples planes (productos) de tu catálogo de forma masiva desde la API. Al realizar esta acción, los identificadores enviados dejarán de estar disponibles para nuevas asignaciones o suscripciones.

Podemos borrar planes haciendo uso de los siguientes parámetros:

ParámetroTipoRequeridoDetalles
 uuids Array Requerido Mandar el UUID del plane que se desea eliminar.
 uuids[] String Requerido UUID del plan que se desea eliminar.

Construcción de la URL

Importante

Importante el método para borrar uno o múltiples planes es DELETE

Host: https://api-partners.factura.com/api

Endpoint: v1/products

Ejemplo: https://api-partners.factura.com/api/v1/products

Ejemplo de borrar plan
DELETE /v1/products HTTP/1.1
Host: {HOST}
Accept: application/json
Content-Type: application/json
Authorization: Bearer YOUR_ACCESS_TOKEN
F-Sandbox-Mode: true

{
  "uuids": [
    "a1e2019fe2b542af96caf6f9320781bd"
  ]
}
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => '{ HOST }/v1/products',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => '',
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 0,
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => 'DELETE',
  CURLOPT_POSTFIELDS =>'{
    "uuids": [
        "a1e2019fe2b542af96caf6f9320781bd"
    ]
}',
  CURLOPT_HTTPHEADER => array(
    'Accept: application/json',
    'Content-Type: application/json',
    'Authorization: ••••••',
    'F-Sandbox-Mode: true'
  ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;

var request = require('request');
var options = {
  'method': 'DELETE',
  'url': '{ HOST }/v1/products',
  'headers': {
    'Accept': 'application/json',
    'Content-Type': 'application/json',
    'Authorization': '••••••',
    'F-Sandbox-Mode': 'true'
  },
  body: JSON.stringify({
    "uuids": [
      "a1e2019fe2b542af96caf6f9320781bd"
    ]
  })

};
request(options, function (error, response) {
  if (error) throw new Error(error);
  console.log(response.body);
});

import requests
import json

url = "{ HOST }/v1/products"

payload = json.dumps({
  "uuids": [
    "a1e2019fe2b542af96caf6f9320781bd"
  ]
})
headers = {
  'Accept': 'application/json',
  'Content-Type': 'application/json',
  'Authorization': '••••••',
  'F-Sandbox-Mode': 'true'
}

response = requests.request("DELETE", url, headers=headers, data=payload)

print(response.text)

require "uri"
require "json"
require "net/http"

url = URI("{ HOST }/v1/products")

http = Net::HTTP.new(url.host, url.port);
request = Net::HTTP::Delete.new(url)
request["Accept"] = "application/json"
request["Content-Type"] = "application/json"
request["F-Sandbox-Mode"] = "true"
request.body = JSON.dump({
  "uuids": [
    "a1e2019fe2b542af96caf6f9320781bd"
  ]
})

response = http.request(request)
puts response.read_body

Respuesta

{
    "response": "success",
    "data": {
        "products": [
            {
                "uuid": "a2151814db4d4ead827e708300b86792",
                "name": "API ELIMINADO",
                "services": {
                    "api": false,
                    "smtp": true,
                    "custom_email": true,
                    "auto_invoices": false,
                    "invoices_migrator": false,
                    "clients": 0,
                    "extra_rfc": 3,
                    "extra_user": 1
                },
                "sales": 0,
                "expiration_type": 0,
                "status": "inactive",
                "vigencies": [
                    {
                        "uuid": "a21518150304451a866317c2503fc557",
                        "folios": 50,
                        "price": "490.00",
                        "expiration_period": "Trimestral"
                    }
                ],
                "pdf_templates": [
                    "default",
                    "classic"
                ]
            }
        ]
    }
}

{
    "status": "error",
    "message": "El recurso solicitado no fue encontrado.",
    "code": "NOT_FOUND"
}

Mostrar plan

Este endpoint permite obtener la información detallada de un plan (producto) específico de tu catálogo utilizando su identificador único (UUID). Es de gran utilidad para verificar de forma dinámica los folios, precios y servicios activos de un plan antes de asociarlo a un cliente.

Podemos consultar un plan haciendo uso de los siguientes parámetros de ruta:

Construcción de la URL

Importante

Importante el método para borrar uno o múltiples planes es GET

Host: https://api-partners.factura.com/api

Endpoint: v1/products/UUID del plan

Ejemplo: https://api-partners.factura.com/api/v1/products/a1390ee8e88e4b089e7bca82b1be5a0c

Ejemplo de petición
GET /v1/products/{uuid} HTTP/1.1
Host: {HOST}
Accept: application/json
Authorization: Bearer YOUR_ACCESS_TOKEN
F-Sandbox-Mode: true
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => '{ HOST }/v1/products/a1390ee8e88e4b089e7bca82b1be5a0c',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => '',
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 0,
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => 'GET',
  CURLOPT_HTTPHEADER => array(
    'Accept: application/json',
    'Authorization: Bearer YOUR_ACCESS_TOKEN',
    'F-Sandbox-Mode: true'
  ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;
var request = require('request');
var options = {
  'method': 'GET',
  'url': '{ HOST }/v1/products/a1390ee8e88e4b089e7bca82b1be5a0c',
  'headers': {
    'Accept': 'application/json',
    'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
    'F-Sandbox-Mode': 'true'
  }
};
request(options, function (error, response) {
  if (error) throw new Error(error);
  console.log(response.body);
});
import requests

url = "{ HOST }/v1/products/a1390ee8e88e4b089e7bca82b1be5a0c"

headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
  'F-Sandbox-Mode': 'true'
}

response = requests.request("GET", url, headers=headers)

print(response.text)
require "uri"
require "net/http"

url = URI("{ HOST }/v1/products/a1390ee8e88e4b089e7bca82b1be5a0c")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Accept"] = "application/json"
request["Authorization"] = "Bearer YOUR_ACCESS_TOKEN"
request["F-Sandbox-Mode"] = "true"

response = http.request(request)
puts response.read_body

Respuesta

{
    "response": "success",
    "data": {
        "uuid": "a2106219d0724860a1521780eea0827a",
        "name": "PLAN ELITE",
        "services": {
            "api": true,
            "smtp": true,
            "custom_email": false,
            "auto_invoices": false,
            "invoices_migrator": false,
            "clients": 0,
            "extra_rfc": 0,
            "extra_user": 0
        },
        "sales": 1,
        "expiration_type": 1,
        "status": "active",
        "vigencies": [
            {
                "uuid": "a210621a4715406086913d91ae27c134",
                "folios": 100,
                "price": "700.00",
                "expiration_period": "Anual"
            }
        ],
        "pdf_templates": [
            "default",
            "classic",
            "formal",
            "minimalist",
            "trendy",
            "elegant"
        ]
    }
}
{
    "status": "error",
    "message": "El recurso solicitado no fue encontrado.",
    "code": "NOT_FOUND"
}

Cambiar estatus de plan

Este endpoint permite activar (habilitar) o desactivar (deshabilitar) un plan (producto) específico de tu catálogo mediante su UUID. Deshabilitar un plan evitará que puedan ponérselo a un cliente.

Construcción de la URL

Importante

Importante el método para borrar uno o múltiples planes es POST

Host: https://api-partners.factura.com/api

Endpoint: v1/products/UUID del plan/change-status

Ejemplo: https://api-partners.factura.com/api/v1/products/a1390ee8e88e4b089e7bca82b1be5a0c/change-status

Ejemplo de petición
POST /v1/products/{uuid}/change-status HTTP/1.1
Host: {HOST}
Accept: application/json
Authorization: Bearer YOUR_ACCESS_TOKEN
F-Sandbox-Mode: true
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => '{ HOST }/v1/products/a1390ee8e88e4b089e7bca82b1be5a0c/change-status',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => '',
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 0,
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => 'POST',
  CURLOPT_HTTPHEADER => array(
    'Accept: application/json',
    'Authorization: Bearer YOUR_ACCESS_TOKEN',
    'F-Sandbox-Mode: true'
  ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;
var request = require('request');
var options = {
  'method': 'POST',
  'url': '{ HOST }/v1/products/a1390ee8e88e4b089e7bca82b1be5a0c/change-status',
  'headers': {
    'Accept': 'application/json',
    'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
    'F-Sandbox-Mode': 'true'
  }
};
request(options, function (error, response) {
  if (error) throw new Error(error);
  console.log(response.body);
});
import requests

url = "{ HOST }/v1/products/a1390ee8e88e4b089e7bca82b1be5a0c/change-status"

headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
  'F-Sandbox-Mode': 'true'
}

response = requests.request("POST", url, headers=headers)

print(response.text)
require "uri"
require "net/http"

url = URI("{ HOST }/v1/products/a1390ee8e88e4b089e7bca82b1be5a0c/change-status")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Accept"] = "application/json"
request["Authorization"] = "Bearer YOUR_ACCESS_TOKEN"
request["F-Sandbox-Mode"] = "true"

response = http.request(request)
puts response.read_body

Respuesta

{
    "response": "success",
    "data": {
        "uuid": "a210621a54b142a8915f0f1a16afc83c",
        "name": "NUEVO PLAN",
        "services": {
            "api": false,
            "smtp": false,
            "custom_email": false,
            "auto_invoices": true,
            "invoices_migrator": true,
            "clients": 0,
            "extra_rfc": "2",
            "extra_user": "2"
        },
        "sales": 0,
        "expiration_type": 1,
        "status": "inactive",
        "vigencies": [
            {
                "uuid": "a210621b0702489ca4037bcbd4796465",
                "folios": 10,
                "price": "100.00",
                "expiration_period": "Semestral"
            }
        ],
        "pdf_templates": [
            "default",
            "classic",
            "elegant"
        ]
    }
}
{
    "status": "error",
    "message": "El recurso solicitado no fue encontrado.",
    "code": "NOT_FOUND"
}

Consultar clientes

Este endpoint permite obtener un listado de todos los clientes registrados bajo tu cuenta de Partner.

Construcción de la URL

Importante

Importante el método para borrar uno o múltiples planes es GET

Host: https://api-partners.factura.com/api

Endpoint: v1/clients

Ejemplo: https://api-partners.factura.com/api/v1/clients

Utilice los siguientes parámetros opcionales en la URL para filtrar los resultados por nombre del cliente, o para aplicar paginación u ordenamiento en la respuesta:

ParámetroTipoRequeridoDetalles
namestringOpcional

Indica el nombre del cliente que se quiere consultar, puede estar completo o no.

Ejemplo: /api/v1/clients?name=Escuela

sortstringOpcional

Define el orden de los resultados. Utiliza el prefijo + para orden ascendente y - para descendente.
Valores permitidos: +name, -name, +created_at, -created_at.

Ejemplo: /api/v1/clients?sort=+name

per_pageIntegerOpcional Indica el límite de resultados para mostrar, por default retorna todos los planes del catalogo.

Ejemplo: /api/v1/clients?per_page=3

pageIntegerOpcional Indica número de página a consultar, por default posiciona en la página 1.

Ejemplo: /api/v1/clients?page=2

Ejemplo de petición
GET /v1/clients HTTP/1.1
Host: {HOST}
Accept: application/json
Authorization: Bearer YOUR_ACCESS_TOKEN
F-Sandbox-Mode: true
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => '{ HOST }/v1/clients',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => '',
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 0,
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => 'GET',
  CURLOPT_HTTPHEADER => array(
    'Accept: application/json',
    'Authorization: Bearer YOUR_ACCESS_TOKEN',
    'F-Sandbox-Mode: true'
  ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;
var request = require('request');
var options = {
  'method': 'GET',
  'url': '{ HOST }/v1/clients',
  'headers': {
    'Accept': 'application/json',
    'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
    'F-Sandbox-Mode': 'true'
  }
};
request(options, function (error, response) {
  if (error) throw new Error(error);
  console.log(response.body);
});
import requests

url = "{ HOST }/v1/clients"

headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
  'F-Sandbox-Mode': 'true'
}

response = requests.request("GET", url, headers=headers)

print(response.text)
require "uri"
require "net/http"

url = URI("{ HOST }/v1/clients")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Accept"] = "application/json"
request["Authorization"] = "Bearer YOUR_ACCESS_TOKEN"
request["F-Sandbox-Mode"] = "true"

response = http.request(request)
puts response.read_body

Respuesta

{
    "response": "success",
    "data": {
        "clients": [
            {
                "uuid": "a210621c826a46499ef1000d64aeb402",
                "name": " ",
                "email": "[email protected]",
                "status": "active",
                "taxInformation": {
                    "legalName": "INDISTRIA ILUMINADORA ELITE",
                    "taxId": "IIA040805DZ0",
                    "taxRegime": null,
                    "useKey": null,
                    "zipCode": "62661",
                    "country": "MEX",
                    "state": "",
                    "city": "",
                    "neighborhood": "",
                    "address": "",
                    "additionalEmail": null
                },
                "subscription": null,
                "createdAt": "2026-06-19T23:41:32.000000Z",
                "updatedAt": "2026-06-19T23:41:32.000000Z"
            },
            {
                "uuid": "a210621b15284f9db98e939008e775db",
                "name": " ",
                "email": "[email protected]",
                "status": "suspended",
                "taxInformation": {
                    "legalName": "CECILIA ELITE",
                    "taxId": "MISC491214B85",
                    "taxRegime": null,
                    "useKey": null,
                    "zipCode": "01010",
                    "country": "MEX",
                    "state": "Distrito Federal",
                    "city": "Álvaro Obregón",
                    "neighborhood": "",
                    "address": "",
                    "additionalEmail": null
                },
                "subscription": null,
                "createdAt": "2026-06-19T23:41:31.000000Z",
                "updatedAt": "2026-06-19T23:41:31.000000Z"
              }
            ],
            "pagination": {
            "currentPage": 1,
            "lastPage": 1,
            "perPage": 15,
            "total": 2
        }
    }
}

{
    "status": "error",
    "message": "Unauthenticated.",
    "code": "SERVER_ERROR"
}

Mostrar cliente

Este endpoint permite obtener la información detallada de un solo cliente específico de tu catálogo utilizando su identificador único (UUID).

Podemos consultar un cliente haciendo uso de los siguientes parámetros de ruta:

Construcción de la URL

Importante

Importante el método para borrar uno o múltiples planes es GET

Host: https://api-partners.factura.com/api

Endpoint: v1/clients/UUID del cliente

Ejemplo: https://api-partners.factura.com/api/v1/clients/a23640b3d6a843fdb2c37df143931f5d

Ejemplo de petición
GET /v1/clients/{uuid} HTTP/1.1
Host: {HOST}
Accept: application/json
Authorization: Bearer YOUR_ACCESS_TOKEN
F-Sandbox-Mode: true
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => '{ HOST }/v1/clients/a1390ee8e88e4b089e7bca82b1be5a0c',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => '',
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 0,
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => 'GET',
  CURLOPT_HTTPHEADER => array(
    'Accept: application/json',
    'Authorization: Bearer YOUR_ACCESS_TOKEN',
    'F-Sandbox-Mode: true'
  ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;
var request = require('request');
var options = {
  'method': 'GET',
  'url': '{ HOST }/v1/clients/a1390ee8e88e4b089e7bca82b1be5a0c',
  'headers': {
    'Accept': 'application/json',
    'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
    'F-Sandbox-Mode': 'true'
  }
};
request(options, function (error, response) {
  if (error) throw new Error(error);
  console.log(response.body);
});
import requests

url = "{ HOST }/v1/clients/a1390ee8e88e4b089e7bca82b1be5a0c"

headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
  'F-Sandbox-Mode': 'true'
}

response = requests.request("GET", url, headers=headers)

print(response.text)
require "uri"
require "net/http"

url = URI("{ HOST }/v1/clients/a1390ee8e88e4b089e7bca82b1be5a0c")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Accept"] = "application/json"
request["Authorization"] = "Bearer YOUR_ACCESS_TOKEN"
request["F-Sandbox-Mode"] = "true"

response = http.request(request)
puts response.read_body

Respuesta

{
    "response": "success",
    "data": {
        "uuid": "a23640b3d6a843fdb2c37df143931f5d",
        "name": "Juan Lopez",
        "email": "[email protected]",
        "apiKey": "JDJ5J...",
        "secretKey": "JDJ5...",
        "token": "ZXlKc...",
        "status": "suspended",
        "taxInformation": {
            "legalName": "INDUSTRIAS XA",
            "taxId": "XIA190128J61",
            "taxRegime": null,
            "useKey": null,
            "zipCode": "76343",
            "country": "MEX",
            "state": null,
            "city": null,
            "neighborhood": null,
            "address": null,
            "additionalEmail": null
        },
        "subscription": null,
        "createdAt": "2026-07-08T19:29:34.000000Z",
        "updatedAt": "2026-07-08T19:29:34.000000Z"
    }
}
{
    "status": "error",
    "message": "El recurso solicitado no fue encontrado.",
    "code": "NOT_FOUND"
}

Crear cliente

A continuación se explica la función para partners con la cual podrás crear cuentas para tus clientes y asignarles planes para que comiencen a facturar

Tip

Es importante tener configurados los planes en tu interfaz los cuales asignaras a los clientes que generes por API

Podemos crear un nuevo cliente haciendo uso de los siguientes parámetros:

ParámetroTipoRequeridoDetalles
 client Objeto Requerido Nodo contenedor con la información general del cliente que se desea crear.
 client.name String Requerido Sirve para indicar el nombre del cliente que se registrará en el sistema.
 client.email String Requerido Correo electrónico principal del cliente. Este correo será utilizado para el acceso y recepción de notificaciones del sistema.
 tax_information Objeto Requerido Nodo que contiene la información fiscal del cliente para efectos de facturación.
 tax_information.tax_id String Requerido RFC del cliente que será utilizado para la emisión de CFDI.
 tax_information.legal_name String Requerido Razón social o nombre fiscal del cliente registrado ante el SAT.
 tax_information.postal_code String Requerido Código postal correspondiente al domicilio fiscal del cliente.
 tax_information.invoice_use_key String Requerido  Clave de uso de CFDI que se asignará por defecto al cliente para la emisión de facturas.
Ejemplo: "G01"
 tax_information.tax_regime String Requerido Clave del régimen fiscal correspondiente al cliente conforme al catálogo del SAT.
 tax_information.country String Opcional País correspondiente al domicilio fiscal del cliente.
 tax_information.state String Opcional Estado o entidad federativa correspondiente al domicilio fiscal del cliente.
 tax_information.city String Opcional Ciudad o municipio correspondiente al domicilio fiscal del cliente.
 tax_information.neighborhood String Opcional Colonia correspondiente al domicilio fiscal del cliente.
 tax_information.address String Opcional Dirección completa del domicilio fiscal del cliente.
 tax_information.additional_email String Opcional Correo electrónico adicional al que se podrán enviar documentos fiscales o notificaciones relacionadas con la facturación.
 product Objeto Requerido Nodo que contiene la información del producto o plan que será asignado al cliente.
 product.uuid String Requerido Es el UUID del plan que se asignará al cliente.
 product.vigency_uuid String Requerido Es el UUID de la vigencia asociada al producto seleccionado.

Construcción de la URL

Importante

Importante el método para borrar uno o múltiples planes es POST

Host: https://api-partners.factura.com/api

Endpoint: v1/clients

Ejemplo: https://api-partners.factura.com/api/v1/clients

Ejemplo para dar de alta un nuevo cliente

POST /v1/clients HTTP/1.1
Host: {HOST}
Content-Type: application/json
Authorization: Bearer YOUR_ACCESS_TOKEN
F-Sandbox-Mode: true

{
  "client": {
    "name": "MARTIN LOPEZ",
    "email": "[email protected]"
  },
  "tax_information": {
    "tax_id": "FUNK671228PH1",
    "legal_name": "MARTIN LOPEZ LOPEZ",
    "postal_code": "01234",
    "invoice_use_key": "G01",
    "tax_regime": "601"
  },
  "product": {
    "uuid": "a2106219d0724860a1521780eea0827a",
    "vigency_uuid": "a210621a4715406086913d91ae27c134"
  }
}
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => '{ HOST }/v1/clients',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => '',
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 0,
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => 'POST',
  CURLOPT_POSTFIELDS =>'{
    "client": {
        "name": "MARTIN LOPEZ",
        "email": "[email protected]"
    },
    "tax_information": {
        "tax_id": "FUNK671228PH1",
        "legal_name": "MARTIN LOPEZ LOPEZ",
        "postal_code": "01234",
        "invoice_use_key": "G01",
        "tax_regime": "601"
    },
    "product": {
        "uuid": "a2106219d0724860a1521780eea0827a",
        "vigency_uuid": "a210621a4715406086913d91ae27c134"
    }
}',
  CURLOPT_HTTPHEADER => array(
    'Content-Type: application/json',
    'Authorization: ••••••',
    'F-Sandbox-Mode: true'
  ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;

var request = require('request');
var options = {
  'method': 'POST',
  'url': '{ HOST }/v1/clients',
  'headers': {
    'Content-Type': 'application/json',
    'Authorization': '••••••',
    'F-Sandbox-Mode': 'true'
  },
  body: JSON.stringify({
    "client": {
      "name": "MARTIN LOPEZ",
      "email": "[email protected]"
    },
    "tax_information": {
      "tax_id": "FUNK671228PH1",
      "legal_name": "MARTIN LOPEZ LOPEZ",
      "postal_code": "01234",
      "invoice_use_key": "G01",
      "tax_regime": "601"
    },
    "product": {
      "uuid": "a2106219d0724860a1521780eea0827a",
      "vigency_uuid": "a210621a4715406086913d91ae27c134"
    }
  })

};
request(options, function (error, response) {
  if (error) throw new Error(error);
  console.log(response.body);
});

import requests
import json

url = "{ HOST }/v1/clients"

payload = json.dumps({
  "client": {
    "name": "MARTIN LOPEZ",
    "email": "[email protected]"
  },
  "tax_information": {
    "tax_id": "FUNK671228PH1",
    "legal_name": "MARTIN LOPEZ LOPEZ",
    "postal_code": "01234",
    "invoice_use_key": "G01",
    "tax_regime": "601"
  },
  "product": {
    "uuid": "a2106219d0724860a1521780eea0827a",
    "vigency_uuid": "a210621a4715406086913d91ae27c134"
  }
})
headers = {
  'Content-Type': 'application/json',
  'Authorization': '••••••',
  'F-Sandbox-Mode': 'true'
}

response = requests.request("POST", url, headers=headers, data=payload)

print(response.text)

require "uri"
require "json"
require "net/http"

url = URI("{ HOST }/v1/clients")

https = Net::HTTP.new(url.host, url.port)
https.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Content-Type"] = "application/json"
request["F-Sandbox-Mode"] = "true"
request["Authorization"] = "••••••"
request.body = JSON.dump({
  "client": {
    "name": "MARTIN LOPEZ",
    "email": "[email protected]"
  },
  "tax_information": {
    "tax_id": "FUNK671228PH1",
    "legal_name": "MARTIN LOPEZ LOPEZ",
    "postal_code": "01234",
    "invoice_use_key": "G01",
    "tax_regime": "601"
  },
  "product": {
    "uuid": "a2106219d0724860a1521780eea0827a",
    "vigency_uuid": "a210621a4715406086913d91ae27c134"
  }
})

response = https.request(request)
puts response.read_body

Respuesta

{
    "response": "success",
    "data": {
        "uuid": "a21544903d574f0c889798f8c13965cc",
        "name": "MARTIN LOPEZ",
        "email": "[email protected]",
        "status": null,
        "taxInformation": {
            "legalName": "MARTIN LOPEZ LOPEZ",
            "taxId": "FUNK671228PH1",
            "taxRegime": "601",
            "useKey": "G01",
            "zipCode": "01234",
            "country": null,
            "state": null,
            "city": null,
            "neighborhood": null,
            "address": null,
            "additionalEmail": null
        },
        "subscription": {
            "uuid": "a2154491e9e04adcabf6a051e2dbdaca",
            "name": "PLAN ELITE",
            "startDate": "2026-06-22T00:00:00.000000Z",
            "endDate": "2026-07-22T00:00:00.000000Z",
            "folios": 100,
            "foliosUsed": 0,
            "status": "active",
            "services": {
                "api": true,
                "smtp": true,
                "customEmail": false,
                "extraCompanies": 0,
                "extraUsers": 0
            }
        },
        "createdAt": "2026-06-22T09:58:03.000000Z",
        "updatedAt": "2026-06-22T09:58:04.000000Z"
    }
}
{
    "status": "error",
    "message": "Error de validación de datos.",
    "errors": {
        "product.uuid": [
            "The selected product.uuid is invalid."
        ]
    },
    "code": "VALIDATION_FAILED"
}

Suspender cliente

A continuación se explica la función para suspender a un cliente. Durante la suspensión podrás indicar el mensaje que recibirá el cliente y definir si los folios disponibles deben conservarse o regresar a tu panel de partner.

Estos son los parámetros para parámetros un cliente:

ParámetroTipoRequeridoDetalles
 uuids Array Requerido  UUID de cliente que sera suspendido.
 uuids[] String Requerido UUID del cliente que será suspendido.
 message String Requerido  Mensaje que se enviara por correo del motivo de la suspensión de la cuenta al cliente.
 keep_folios Booleano Requerido  Indica si los folios disponibles del cliente deberán conservarse después de realizar la suspensión.

Valores aceptados:
• true → Conserva los folios disponibles.
• false → Elimina los folios disponibles al suspender la cuenta.

Construcción de la URL

Importante

Importante el método para borrar uno o múltiples planes es POST

Host: https://api-partners.factura.com/api

Endpoint: v1/clients/suspend

Ejemplo: https://api-partners.factura.com/api/v1/clients/suspend

Ejemplo para suspender cliente

POST /v1/clients/suspend HTTP/1.1
Host: {HOST}
Content-Type: application/json
Authorization: Bearer YOUR_ACCESS_TOKEN
F-Sandbox-Mode: true

{
  "uuids": [
    "a20840069eb541f79a70fd7522f27f1d"
  ],
  "message": "Este es una suspensión de prueba por API",
  "keep_folios": true
}
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => '{ HOST }/v1/clients/suspend',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => '',
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 0,
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => 'POST',
  CURLOPT_POSTFIELDS =>'{
    "uuids": [
        "a20840069eb541f79a70fd7522f27f1d"
    ],
    "message": "Este es una suspensión de prueba por API",
    "keep_folios": true
}',
  CURLOPT_HTTPHEADER => array(
    'Content-Type: application/json',
    'Authorization: ••••••',
    'F-Sandbox-Mode: true'
  ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;

var request = require('request');
var options = {
  'method': 'POST',
  'url': '{ HOST }/v1/clients/suspend',
  'headers': {
    'Content-Type': 'application/json',
    'Authorization': '••••••',
    'F-Sandbox-Mode': 'true'
  },
  body: JSON.stringify({
    "uuids": [
      "a20840069eb541f79a70fd7522f27f1d"
    ],
    "message": "Este es una suspensión de prueba por API",
    "keep_folios": true
  })

};
request(options, function (error, response) {
  if (error) throw new Error(error);
  console.log(response.body);
});

import requests
import json

url = "{ HOST }/v1/clients/suspend"

payload = json.dumps({
  "uuids": [
    "a20840069eb541f79a70fd7522f27f1d"
  ],
  "message": "Este es una suspensión de prueba por API",
  "keep_folios": True
})
headers = {
  'Content-Type': 'application/json',
  'Authorization': '••••••',
  'F-Sandbox-Mode': 'true'
}

response = requests.request("POST", url, headers=headers, data=payload)

print(response.text)

require "uri"
require "json"
require "net/http"

url = URI("{ HOST }/v1/clients/suspend")

https = Net::HTTP.new(url.host, url.port)
https.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Content-Type"] = "application/json"
request["F-Sandbox-Mode"] = "true"
request["Authorization"] = "••••••"
request.body = JSON.dump({
  "uuids": [
    "a20840069eb541f79a70fd7522f27f1d"
  ],
  "message": "Este es una suspensión de prueba por API",
  "keep_folios": true
})

response = https.request(request)
puts response.read_body

Respuesta

{
    "response": "success",
    "data": {
        "clients": [
            {
                "uuid": "a21544903d574f0c889798f8c13965cc",
                "name": "CLIENTE MARTIN LOPEZ",
                "email": "[email protected]",
                "status": "suspended",
                "taxInformation": {
                    "legalName": "MARTIN LOPEZ LOPEZ",
                    "taxId": "FUNK671228PH1",
                    "taxRegime": "601",
                    "useKey": "G01",
                    "zipCode": "01234",
                    "country": null,
                    "state": null,
                    "city": null,
                    "neighborhood": null,
                    "address": null,
                    "additionalEmail": null
                },
                "subscription": null,
                "createdAt": "2026-06-22T09:58:03.000000Z",
                "updatedAt": "2026-06-22T10:28:28.000000Z"
            }
        ]
    }
}
{
    "status": "error",
    "message": "El recurso solicitado no fue encontrado.",
    "code": "NOT_FOUND"
}

Reactivar cliente

A continuación se explica la función para reactivar uno o múltiples clientes previamente suspendidos para que puedan volver a utilizar su cuenta y continuar operando normalmente.

Estos son los parámetros para reactivar clientes:

ParámetroTipoRequeridoDetalles
 uuids Array Requerido  UUID de uno o múltiples clientes que serán reactivados.
 uuids[] String Requerido UUID del cliente que será reactivado.

Construcción de la URL

Importante

Importante el método para borrar uno o múltiples planes es POST

Host: https://api-partners.factura.com/api

Endpoint: v1/clients/reactivate

Ejemplo: https://api-partners.factura.com/api/v1/clients/reactivate

Ejemplo para suspender cliente

POST /v1/clients/reactivate HTTP/1.1
Host: {HOST}
Content-Type: application/json
Authorization: Bearer YOUR_ACCESS_TOKEN
F-Sandbox-Mode: true

{
  "uuids": [
    "a1391c1fc8914e618413e476b52b4615"
  ]
}
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => '{ HOST }/v1/clients/reactivate',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => '',
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 0,
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => 'POST',
  CURLOPT_POSTFIELDS =>'{
    "uuids": [
        "a1391c1fc8914e618413e476b52b4615"
    ]
}',
  CURLOPT_HTTPHEADER => array(
    'Content-Type: application/json',
    'Authorization: ••••••',
    'F-Sandbox-Mode: true'
  ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;


var request = require('request');
var options = {
  'method': 'POST',
  'url': '{ HOST }/v1/clients/reactivate',
  'headers': {
    'Content-Type': 'application/json',
    'Authorization': '••••••',
    'F-Sandbox-Mode': 'true'
  },
  body: JSON.stringify({
    "uuids": [
      "a1391c1fc8914e618413e476b52b4615"
    ]
  })

};

request(options, function (error, response) {
  if (error) throw new Error(error);
  console.log(response.body);
});


import requests
import json

url = "{ HOST }/v1/clients/reactivate"

payload = json.dumps({
  "uuids": [
    "a1391c1fc8914e618413e476b52b4615"
  ]
})

headers = {
  'Content-Type': 'application/json',
  'Authorization': '••••••',
  'F-Sandbox-Mode': 'true'
}

response = requests.request("POST", url, headers=headers, data=payload)

print(response.text)


require "uri"
require "json"
require "net/http"

url = URI("{ HOST }/v1/clients/reactivate")

https = Net::HTTP.new(url.host, url.port)
https.use_ssl = true

request = Net::HTTP::Post.new(url)

request["Content-Type"] = "application/json"
request["F-Sandbox-Mode"] = "true"
request["Authorization"] = "••••••"

request.body = JSON.dump({
  "uuids": [
    "a1391c1fc8914e618413e476b52b4615"
  ]
})

response = https.request(request)

puts response.read_body


Respuesta

{
    "response": "success",
    "data": {
        "clients": [
            {
                "uuid": "a21544903d574f0c889798f8c13965cc",
                "name": "CLIENTE MARTIN LOPEZ",
                "email": "[email protected]",
                "status": "active",
                "taxInformation": {
                    "legalName": "MARTIN LOPEZ LOPEZ",
                    "taxId": "FUNK671228PH1",
                    "taxRegime": "601",
                    "useKey": "G01",
                    "zipCode": "01234",
                    "country": null,
                    "state": null,
                    "city": null,
                    "neighborhood": null,
                    "address": null,
                    "additionalEmail": null
                },
                "subscription": {
                    "uuid": "a2154491e9e04adcabf6a051e2dbdaca",
                    "name": "PLAN ELITE",
                    "startDate": "2026-06-22T00:00:00.000000Z",
                    "endDate": "2026-07-22T00:00:00.000000Z",
                    "folios": 100,
                    "foliosUsed": 0,
                    "status": "active",
                    "services": {
                        "api": true,
                        "smtp": true,
                        "customEmail": false,
                        "extraCompanies": 0,
                        "extraUsers": 0
                    }
                },
                "createdAt": "2026-06-22T09:58:03.000000Z",
                "updatedAt": "2026-06-22T10:40:42.000000Z"
            }
        ]
    }
}
{
    "status": "error",
    "message": "El recurso solicitado no fue encontrado.",
    "code": "NOT_FOUND"
}

Reenviar accesos al cliente

A continuación se explica la función para reenviar por correo electrónico los accesos de una cuenta previamente creada. Esta función permite volver a enviar al cliente la información de acceso utilizando el UUID de su cuenta.

Construcción de la URL

Importante

Importante el método para borrar uno o múltiples planes es POST

Host: https://api-partners.factura.com/api

Endpoint: v1/clients/UUID del cliente/resend-credentials

Ejemplo: https://api-partners.factura.com/api/v1/clients/a1f9c3d9fee5434ebf6104e1de572b59/resend-credentials

Ejemplo de petición
POST /v1/clients/{uuid}/resend-credentials HTTP/1.1
Host: {HOST}
Accept: application/json
Authorization: Bearer YOUR_ACCESS_TOKEN
F-Sandbox-Mode: true
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => '{ HOST }/v1/clients/a1f9c3d9fee5434ebf6104e1de572b59/resend-credentials',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => '',
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 0,
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => 'POST',
  CURLOPT_HTTPHEADER => array(
    'Accept: application/json',
    'Authorization: Bearer YOUR_ACCESS_TOKEN',
    'F-Sandbox-Mode: true'
  ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;
var request = require('request');
var options = {
  'method': 'POST',
  'url': '{ HOST }/v1/clients/a1f9c3d9fee5434ebf6104e1de572b59/resend-credentials',
  'headers': {
    'Accept': 'application/json',
    'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
    'F-Sandbox-Mode': 'true'
  }
};
request(options, function (error, response) {
  if (error) throw new Error(error);
  console.log(response.body);
});
import requests

url = "{ HOST }/v1/clients/a1f9c3d9fee5434ebf6104e1de572b59/resend-credentials"

headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
  'F-Sandbox-Mode': 'true'
}

response = requests.request("POST", url, headers=headers)

print(response.text)
require "uri"
require "net/http"

url = URI("{ HOST }/v1/clients/a1f9c3d9fee5434ebf6104e1de572b59/resend-credentials")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Accept"] = "application/json"
request["Authorization"] = "Bearer YOUR_ACCESS_TOKEN"
request["F-Sandbox-Mode"] = "true"

response = http.request(request)
puts response.read_body

Respuesta

{
    "response": "success",
    "data": {
        "clients": [
            {
                "uuid": "a21544903d574f0c889798f8c13965cc",
                "name": "CLIENTE MARTIN LOPEZ",
                "email": "[email protected]",
                "status": "active",
                "taxInformation": {
                    "legalName": "MARTIN LOPEZ LOPEZ",
                    "taxId": "FUNK671228PH1",
                    "taxRegime": "601",
                    "useKey": "G01",
                    "zipCode": "01234",
                    "country": null,
                    "state": null,
                    "city": null,
                    "neighborhood": null,
                    "address": null,
                    "additionalEmail": null
                },
                "subscription": {
                    "uuid": "a2154491e9e04adcabf6a051e2dbdaca",
                    "name": "PLAN ELITE",
                    "startDate": "2026-06-22T00:00:00.000000Z",
                    "endDate": "2026-07-22T00:00:00.000000Z",
                    "folios": 100,
                    "foliosUsed": 0,
                    "status": "active",
                    "services": {
                        "api": true,
                        "smtp": true,
                        "customEmail": false,
                        "extraCompanies": 0,
                        "extraUsers": 0
                    }
                },
                "createdAt": "2026-06-22T09:58:03.000000Z",
                "updatedAt": "2026-06-22T10:40:42.000000Z"
            }
        ]
    }
}
{
    "status": "error",
    "message": "El recurso solicitado no fue encontrado.",
    "code": "NOT_FOUND"
}

Actualizar cliente

A continuación se explica la función para actualizar la información de una cuenta de cliente previamente creada. Con esta operación podrás modificar los datos generales y fiscales del cliente; sin embargo, el producto o plan asignado a la cuenta no podrá ser modificado desde este endpoint.

Estos son los parámetros para actualizar un cliente:

ParámetroTipoRequeridoDetalles
 client Objeto Opcional Nodo contenedor con la información general del cliente que se desea actualizar.
 client.name String Opcional Sirve para indicar el nuevo nombre que tendrá registrado el cliente.
 client.email String Opcional Correo electrónico principal del cliente. Este correo será utilizado para el acceso y recepción de notificaciones del sistema.
 tax_information Objeto Opcional Nodo que contiene la información fiscal del cliente que será actualizada.
 tax_information.tax_id String Opcional RFC del cliente que será utilizado para la emisión de CFDI.
 tax_information.legal_name String Opcional Razón social o nombre fiscal del cliente registrado ante el SAT.
 tax_information.postal_code String Opcional Código postal correspondiente al domicilio fiscal del cliente.
 tax_information.invoice_use_key String Opcional  Clave de uso de CFDI que se asignará al cliente para la emisión de facturas.
Ejemplo: "G01"
 tax_information.tax_regime String Opcional Clave del régimen fiscal correspondiente al cliente conforme al catálogo del SAT.
 tax_information.country String Opcional País correspondiente al domicilio fiscal del cliente.
 tax_information.state String Opcional Estado o entidad federativa correspondiente al domicilio fiscal del cliente.
 tax_information.city String Opcional Ciudad o municipio correspondiente al domicilio fiscal del cliente.
 tax_information.neighborhood String Opcional Colonia correspondiente al domicilio fiscal del cliente.
 tax_information.address String Opcional Dirección completa correspondiente al domicilio fiscal del cliente.
 tax_information.additional_email String Opcional Correo electrónico adicional al que se podrán enviar documentos fiscales o notificaciones relacionadas con la facturación.

Construcción de la URL

Importante

Importante el método para borrar uno o múltiples planes es PATCH

Host: https://api-partners.factura.com/api

Endpoint: v1/clients/UUID del cliente

Ejemplo: https://api-partners.factura.com/api/v1/clients/ra21544903d574f0c889798f8c13965cc

Ejemplo para actualizar cliente

PATCH /v1/clients/{uuid} HTTP/1.1
Host: {HOST}
Content-Type: application/json
Authorization: Bearer YOUR_ACCESS_TOKEN
F-Sandbox-Mode: true

{
  "client": {
    "name": "MARTIN LOPEZ EDIT",
    "email": "[email protected]"
  },
  "tax_information": {
    "tax_id": "FUNK671228PH8",
    "legal_name": "MARTIN EDITADO",
    "postal_code": "01235",
    "invoice_use_key": "G01",
    "tax_regime": "626",
    "country": "México",
    "state": "Ciudad de México",
    "city": "Ciudad de México",
    "neighborhood": "Polanco",
    "address": "Av. Reforma 123, Col. Polanco",
    "additional_email": "[email protected]"
  }
}
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => '{ HOST }/v1/clients/a21544903d574f0c889798f8c13965cc',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => '',
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 0,
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => 'POST',
  CURLOPT_POSTFIELDS =>'{
    "client": {
        "name": "MARTIN LOPEZ EDIT",
        "email": "[email protected]"
    },
    "tax_information": {
        "tax_id": "FUNK671228PH8",
        "legal_name": "MARTIN EDITADO",
        "postal_code": "01235",
        "invoice_use_key": "G01",
        "tax_regime": "626",
        "country": "México",
        "state": "Ciudad de México",
        "city": "Ciudad de México",
        "neighborhood": "Polanco",
        "address": "Av. Reforma 123, Col. Polanco",
        "additional_email": "[email protected]"
    }
}',
  CURLOPT_HTTPHEADER => array(
    'Content-Type: application/json',
    'Authorization: ••••••',
    'F-Sandbox-Mode: true'
  ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;


var request = require('request');
var options = {
  'method': 'POST',
  'url': '{ HOST }/v1/clients/a21544903d574f0c889798f8c13965cc',
  'headers': {
    'Content-Type': 'application/json',
    'Authorization': '••••••',
    'F-Sandbox-Mode': 'true'
  },
  body: JSON.stringify({
    "client": {
      "name": "MARTIN LOPEZ EDIT",
      "email": "[email protected]"
    },
    "tax_information": {
      "tax_id": "FUNK671228PH8",
      "legal_name": "MARTIN EDITADO",
      "postal_code": "01235",
      "invoice_use_key": "G01",
      "tax_regime": "626",
      "country": "México",
      "state": "Ciudad de México",
      "city": "Ciudad de México",
      "neighborhood": "Polanco",
      "address": "Av. Reforma 123, Col. Polanco",
      "additional_email": "[email protected]"
    }
  })

};

request(options, function (error, response) {
  if (error) throw new Error(error);
  console.log(response.body);
});


import requests
import json

url = "{ HOST }/v1/clients/a21544903d574f0c889798f8c13965cc"

payload = json.dumps({
  "client": {
    "name": "MARTIN LOPEZ EDIT",
    "email": "[email protected]"
  },
  "tax_information": {
    "tax_id": "FUNK671228PH8",
    "legal_name": "MARTIN EDITADO",
    "postal_code": "01235",
    "invoice_use_key": "G01",
    "tax_regime": "626",
    "country": "México",
    "state": "Ciudad de México",
    "city": "Ciudad de México",
    "neighborhood": "Polanco",
    "address": "Av. Reforma 123, Col. Polanco",
    "additional_email": "[email protected]"
  }
})

headers = {
  'Content-Type': 'application/json',
  'Authorization': '••••••',
  'F-Sandbox-Mode': 'true'
}

response = requests.request("POST", url, headers=headers, data=payload)

print(response.text)


require "uri"
require "json"
require "net/http"

url = URI("{ HOST }/v1/clients/a21544903d574f0c889798f8c13965cc")

https = Net::HTTP.new(url.host, url.port)
https.use_ssl = true

request = Net::HTTP::Post.new(url)

request["Content-Type"] = "application/json"
request["F-Sandbox-Mode"] = "true"
request["Authorization"] = "••••••"

request.body = JSON.dump({
  "client": {
    "name": "MARTIN LOPEZ EDIT",
    "email": "[email protected]"
  },
  "tax_information": {
    "tax_id": "FUNK671228PH8",
    "legal_name": "MARTIN EDITADO",
    "postal_code": "01235",
    "invoice_use_key": "G01",
    "tax_regime": "626",
    "country": "México",
    "state": "Ciudad de México",
    "city": "Ciudad de México",
    "neighborhood": "Polanco",
    "address": "Av. Reforma 123, Col. Polanco",
    "additional_email": "[email protected]"
  }
})

response = https.request(request)

puts response.read_body


Respuesta

{
    "response": "success",
    "data": {
        "uuid": "a21544903d574f0c889798f8c13965cc",
        "name": "MARTIN LOPEZ EDIT",
        "email": "[email protected]",
        "status": "active",
        "taxInformation": {
            "legalName": "MARTIN EDITADO",
            "taxId": "FUNK671228PH8",
            "taxRegime": "626",
            "useKey": "G01",
            "zipCode": "01235",
            "country": "México",
            "state": "Ciudad de México",
            "city": "Ciudad de México",
            "neighborhood": "Polanco",
            "address": "Av. Reforma 123, Col. Polanco",
            "additionalEmail": "[email protected]"
        },
        "subscription": {
            "uuid": "a2154491e9e04adcabf6a051e2dbdaca",
            "name": "PLAN ELITE",
            "startDate": "2026-06-22T00:00:00.000000Z",
            "endDate": "2026-07-22T00:00:00.000000Z",
            "folios": 100,
            "foliosUsed": 0,
            "status": "active",
            "services": {
                "api": true,
                "smtp": true,
                "customEmail": false,
                "extraCompanies": 0,
                "extraUsers": 0
            }
        },
        "createdAt": "2026-06-22T09:58:03.000000Z",
        "updatedAt": "2026-06-22T11:01:48.000000Z"
    }
}
{
    "status": "error",
    "message": "El recurso solicitado no fue encontrado.",
    "code": "NOT_FOUND"
}

Consultar suscripciones

A continuación se explica la función para consultar las suscripciones disponibles y obtener la información relacionada con los planes asignados a las cuentas de tus clientes. Esta consulta permite recuperar los detalles de la suscripción, incluyendo información sobre vigencias, estado y configuración asociada.

Construcción de la URL

Importante

Importante el método para borrar uno o múltiples planes es GET

Host: https://api-partners.factura.com/api

Endpoint: v1/subscriptions

Ejemplo: https://api-partners.factura.com/api/v1/subscriptions

Utilice los siguientes parámetros opcionales en la URL para filtrar los resultados por nombre del plan que tiene la suscripción, o para aplicar paginación u ordenamiento en la respuesta:

ParámetroTipoRequeridoDetalles
namestringOpcional

Indica el nombre del plan que tiene la suscripción que se quiere consultar, puede estar completo o no.

Ejemplo: /api/v1/subscriptions?name=Plan2026

sortstringOpcional

Define el orden de los resultados. Utiliza el prefijo + para orden ascendente y - para descendente.
Valores permitidos: +name, -name, +created_at, -created_at,+folios, -folios.

Ejemplo: /api/v1/subscriptions?sort=+folios

per_pageIntegerOpcional Indica el limite de resultados para mostrar, por default retorna todos las suscripciones del catalogo.

Ejemplo: /api/v1/subscriptions?per_page=3

pageIntegerOpcional Indica número de página a consultar, por default posiciona en la página 1.

Ejemplo: /api/v1/subscriptions?page=2

Ejemplo de petición
GET /v1/subscriptions HTTP/1.1
Host: {HOST}
Accept: application/json
Authorization: Bearer YOUR_ACCESS_TOKEN
F-Sandbox-Mode: true
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => '{ HOST }/v1/subscriptions',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => '',
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 0,
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => 'GET',
  CURLOPT_HTTPHEADER => array(
    'Accept: application/json',
    'Authorization: Bearer YOUR_ACCESS_TOKEN',
    'F-Sandbox-Mode: true'
  ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;
var request = require('request');
var options = {
  'method': 'GET',
  'url': '{ HOST }/v1/subscriptions',
  'headers': {
    'Accept': 'application/json',
    'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
    'F-Sandbox-Mode': 'true'
  }
};
request(options, function (error, response) {
  if (error) throw new Error(error);
  console.log(response.body);
});
import requests

url = "{ HOST }/v1/subscriptions"

headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
  'F-Sandbox-Mode': 'true'
}

response = requests.request("GET", url, headers=headers)

print(response.text)
require "uri"
require "net/http"

url = URI("{ HOST }/v1/subscriptions")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Accept"] = "application/json"
request["Authorization"] = "Bearer YOUR_ACCESS_TOKEN"
request["F-Sandbox-Mode"] = "true"

response = http.request(request)
puts response.read_body

Respuesta

{
    "response": "success",
    "data": {
        "uuid": "a2154491e9e04adcabf6a051e2dbdaca",
        "name": "PLAN ELITE",
        "start_date": "2026-06-22T00:00:00.000000Z",
        "end_date": "2026-07-22T00:00:00.000000Z",
        "folios": 100,
        "status": "active",
        "client": {
            "uuid": "a21544903d574f0c889798f8c13965cc",
            "name": "MARTIN LOPEZ EDIT",
            "email": "[email protected]",
            "status": "active"
        },
        "product": {
            "uuid": "a2106219d0724860a1521780eea0827a",
            "name": "PLAN ELITE",
            "status": "active"
        },
        "vigency": "Anual",
        "folios_used": 0
    }
}
{
    "status": "error",
    "message": "El recurso solicitado no fue encontrado.",
    "code": "NOT_FOUND"
}

Mostrar suscripción

A continuación se explica la función para consultar una suscripción específica utilizando su UUID. Esta consulta permite obtener la información detallada de la suscripción, incluyendo el plan asociado, vigencia, y estado.

Construcción de la URL

Importante

Importante el método para borrar uno o múltiples planes es GET

Host: https://api-partners.factura.com/api

Endpoint: v1/subscriptions/UUID de la suscripción

Ejemplo: https://api-partners.factura.com/api/v1/subscriptions/a2154491e9e04adcabf6a051e2dbdaca

Ejemplo de petición
GET /v1/subscriptions/{uuid} HTTP/1.1
Host: {HOST}
Accept: application/json
Authorization: Bearer YOUR_ACCESS_TOKEN
F-Sandbox-Mode: true
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => '{ HOST }/v1/subscriptions/a2154491e9e04adcabf6a051e2dbdaca',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => '',
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 0,
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => 'GET',
  CURLOPT_HTTPHEADER => array(
    'Accept: application/json',
    'Authorization: Bearer YOUR_ACCESS_TOKEN',
    'F-Sandbox-Mode: true'
  ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;
var request = require('request');
var options = {
  'method': 'GET',
  'url': '{ HOST }/v1/subscriptions/a2154491e9e04adcabf6a051e2dbdaca',
  'headers': {
    'Accept': 'application/json',
    'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
    'F-Sandbox-Mode': 'true'
  }
};
request(options, function (error, response) {
  if (error) throw new Error(error);
  console.log(response.body);
});
import requests

url = "{ HOST }/v1/subscriptions/a2154491e9e04adcabf6a051e2dbdaca"

headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
  'F-Sandbox-Mode': 'true'
}

response = requests.request("GET", url, headers=headers)

print(response.text)
require "uri"
require "net/http"

url = URI("{ HOST }/v1/subscriptions/a2154491e9e04adcabf6a051e2dbdaca")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Accept"] = "application/json"
request["Authorization"] = "Bearer YOUR_ACCESS_TOKEN"
request["F-Sandbox-Mode"] = "true"

response = http.request(request)
puts response.read_body

Respuesta

{
    "response": "success",
    "data": {
        "uuid": "a21565b38d6142f38424aa0b351a889e",
        "name": "PLAN ELITE",
        "start_date": "2026-06-22T00:00:00.000000Z",
        "end_date": "2026-07-22T00:00:00.000000Z",
        "folios": 100,
        "status": "active",
        "client": {
            "uuid": "a210621b15284f9db98e939008e775db",
            "name": "ANA LAURA MARTINEZ",
            "email": "[email protected]",
            "status": "activo"
        },
        "product": {
            "uuid": "a2106219d0724860a1521780eea0827a",
            "name": "PLAN ELITE",
            "status": "suspended"
        },
        "vigency": "Anual",
        "folios_used": 0
    }
}
{
    "status": "error",
    "message": "El recurso solicitado no fue encontrado.",
    "code": "NOT_FOUND"
}

Renovar suscripción

A continuación se explica la función para renovar una suscripción existente y extender la vigencia del plan asignado al cliente. Esta operación permite mantener activa la suscripción aplicando una nueva vigencia sobre el plan actualmente contratado, renovar con un plan distinto.

Estos son los parámetros para renovar una suscripción:

ParámetroTipoRequeridoDetalles
 product_uuid String Requerido  UUID del producto o plan que será utilizado para realizar la renovación de la suscripción.
 vigency_uuid String Requerido  UUID de la vigencia que se aplicará al producto seleccionado durante el proceso de renovación de la suscripción.

Construcción de la URL

Importante

Importante el método para borrar uno o múltiples planes es POST

Host: https://api-partners.factura.com/api

Endpoint: v1/subscriptions/UUID del cliente/renew

Ejemplo: https://api-partners.factura.com/api/v1/subscriptions/a20c4a7f2ab443bf8d548b8713a7ab56/renew

Ejemplo para renovar suscripción

POST /v1/subscriptions/{uuid}/renew HTTP/1.1
Host: {HOST}
Content-Type: application/json
Authorization: Bearer YOUR_ACCESS_TOKEN
F-Sandbox-Mode: true

{
  "product_uuid": "a2151fa2877f4d0a9781aa3fa275c0d6",
  "vigency_uuid": "a2152b157b4949fab99b1085bd4186b3"
}
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => '{ HOST }/v1/subscriptions/a20c4a7f2ab443bf8d548b8713a7ab56/renew',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => '',
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 0,
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => 'POST',
  CURLOPT_POSTFIELDS =>'{
    "product_uuid": "a2151fa2877f4d0a9781aa3fa275c0d6",
    "vigency_uuid": "a2152b157b4949fab99b1085bd4186b3"
}',
  CURLOPT_HTTPHEADER => array(
    'Content-Type: application/json',
    'Authorization: ••••••',
    'F-Sandbox-Mode: true'
  ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;


var request = require('request');
var options = {
  'method': 'POST',
  'url': '{ HOST }/v1/subscriptions/a20c4a7f2ab443bf8d548b8713a7ab56/renew',
  'headers': {
    'Content-Type': 'application/json',
    'Authorization': '••••••',
    'F-Sandbox-Mode': 'true'
  },
  body: JSON.stringify({
    "product_uuid": "a2151fa2877f4d0a9781aa3fa275c0d6",
    "vigency_uuid": "a2152b157b4949fab99b1085bd4186b3"
  })

};

request(options, function (error, response) {
  if (error) throw new Error(error);
  console.log(response.body);
});


import requests
import json

url = "{ HOST }/v1/subscriptions/a20c4a7f2ab443bf8d548b8713a7ab56/renew"

payload = json.dumps({
  "product_uuid": "a2151fa2877f4d0a9781aa3fa275c0d6",
  "vigency_uuid": "a2152b157b4949fab99b1085bd4186b3"
})

headers = {
  'Content-Type': 'application/json',
  'Authorization': '••••••',
  'F-Sandbox-Mode': 'true'
}

response = requests.request("POST", url, headers=headers, data=payload)

print(response.text)


require "uri"
require "json"
require "net/http"

url = URI("{ HOST }/v1/subscriptions/a20c4a7f2ab443bf8d548b8713a7ab56/renew")

https = Net::HTTP.new(url.host, url.port)
https.use_ssl = true

request = Net::HTTP::Post.new(url)

request["Content-Type"] = "application/json"
request["F-Sandbox-Mode"] = "true"
request["Authorization"] = "••••••"

request.body = JSON.dump({
  "product_uuid": "a2151fa2877f4d0a9781aa3fa275c0d6",
  "vigency_uuid": "a2152b157b4949fab99b1085bd4186b3"
})

response = https.request(request)

puts response.read_body


Respuesta

{
    "response": "success",
    "data": {
        "uuid": "a2156965cbc44cf6a9cb3d8934fffd9d",
        "name": "PLAN EDITADO",
        "start_date": "2026-06-22T00:00:00.000000Z",
        "end_date": "2026-09-22T00:00:00.000000Z",
        "folios": 50,
        "status": null,
        "client": {
            "uuid": "a210621bcfba4098a0e9ae5e6031f649",
            "name": "ANA LAURA MARTINES",
            "email": "[email protected]",
            "status": "active"
        },
        "product": {
            "uuid": "a2151fa2877f4d0a9781aa3fa275c0d6",
            "name": "PLAN EDITADO",
            "status": "active"
        },
        "vigency": "Trimestral",
        "folios_used": 0
    }
}
{
    "status": "error",
    "message": "Error de validación de datos.",
    "errors": {
        "product_uuid": [
            "The selected product uuid is invalid."
        ]
    },
    "code": "VALIDATION_FAILED"
}

Agregar folios

A continuación se explica la función para agregar folios disponibles a una suscripción. Esta operación permite poner una cantidad específica de folios y registrar el monto asociado al ajuste realizado.

Estos son los parámetros para remover folios:

ParámetroTipoRequeridoDetalles
 folios Numérico Requerido  Cantidad de folios que serán agregados de la suscripción.
 amount Numérico Requerido  Monto asociado a la operación de agregar folios. Este valor podrá utilizarse para fines de control o estadísticas.

Construcción de la URL

Importante

Importante el método para borrar uno o múltiples planes es POST

Host: https://api-partners.factura.com/api

Endpoint: v1/subscriptions/UUID de la suscripción/add-folios

Ejemplo: https://api-partners.factura.com/api/v1/subscriptions/a20c4a7f2ab443bf8d548b8713a7ab56/add-folios

Ejemplo para agregar folios

POST /v1/subscriptions/{uuid}/add-folios HTTP/1.1
Host: {HOST}
Content-Type: application/json
Authorization: Bearer YOUR_ACCESS_TOKEN
F-Sandbox-Mode: true

{
  "folios": 5,
  "amount": 2.99
}
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => '{ HOST }/v1/subscriptions/a20c4a7f2ab443bf8d548b8713a7ab56/add-folio',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => '',
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 0,
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => 'POST',
  CURLOPT_POSTFIELDS =>'{
    "folios": 5,
    "amount": 2.99
}',
  CURLOPT_HTTPHEADER => array(
    'Content-Type: application/json',
    'Authorization: ••••••',
    'F-Sandbox-Mode: true'
  ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;


var request = require('request');
var options = {
  'method': 'POST',
  'url': '{ HOST }/v1/subscriptions/a20c4a7f2ab443bf8d548b8713a7ab56/add-folio',
  'headers': {
    'Content-Type': 'application/json',
    'Authorization': '••••••',
    'F-Sandbox-Mode': 'true'
  },
  body: JSON.stringify({
    "folios": 5,
    "amount": 2.99
  })

};

request(options, function (error, response) {
  if (error) throw new Error(error);
  console.log(response.body);
});


import requests
import json

url = "{ HOST }/v1/subscriptions/a20c4a7f2ab443bf8d548b8713a7ab56/add-folio"

payload = json.dumps({
  "folios": 5,
  "amount": 2.99
})

headers = {
  'Content-Type': 'application/json',
  'Authorization': '••••••',
  'F-Sandbox-Mode': 'true'
}

response = requests.request("POST", url, headers=headers, data=payload)

print(response.text)


require "uri"
require "json"
require "net/http"

url = URI("{ HOST }/v1/subscriptions/a20c4a7f2ab443bf8d548b8713a7ab56/add-folio")

https = Net::HTTP.new(url.host, url.port)
https.use_ssl = true

request = Net::HTTP::Post.new(url)

request["Content-Type"] = "application/json"
request["F-Sandbox-Mode"] = "true"
request["Authorization"] = "••••••"

request.body = JSON.dump({
  "folios": 5,
  "amount": 2.99
})

response = https.request(request)

puts response.read_body


Respuesta

{
    "response": "success",
    "data": {
        "uuid": "a2154491e9e04adcabf6a051e2dbdaca",
        "name": "PLAN ELITE",
        "start_date": "2026-06-22T00:00:00.000000Z",
        "end_date": "2026-07-22T00:00:00.000000Z",
        "folios": 105,
        "status": "active",
        "client": {
            "uuid": "a21544903d574f0c889798f8c13965cc",
            "name": "MARTIN LOPEZ EDIT",
            "email": "[email protected]",
            "status": "active"
        },
        "product": {
            "uuid": "a2106219d0724860a1521780eea0827a",
            "name": "PLAN ELITE",
            "status": "active"
        },
        "vigency": "Anual",
        "folios_used": 0
    }
}
{
    "status": "error",
    "message": "Error de validación de datos.",
    "errors": {
        "folios": [
            "The folios field is required."
        ]
    },
    "code": "VALIDATION_FAILED"
}

Retirar folios

A continuación se explica la función para retirar folios disponibles a una suscripción de un cliente. Esta operación permite poner una cantidad específica de folios.

Estos son los parámetros para remover folios:

ParámetroTipoRequeridoDetalles
 folios Numérico Requerido  Cantidad de folios que serán agregados de la suscripción.

Construcción de la URL

Importante

Importante el método para borrar uno o múltiples planes es POST

Host: https://api-partners.factura.com/api

Endpoint: v1/subscriptions/UUID de la suscripción/remove-folios

Ejemplo: https://api-partners.factura.com/api/v1/subscriptions/a20c4a7f2ab443bf8d548b8713a7ab56/remove-folios

Ejemplo para remover folios

POST /v1/subscriptions/{uuid}/remove-folios HTTP/1.1
Host: {HOST}
Content-Type: application/json
Authorization: Bearer YOUR_ACCESS_TOKEN
F-Sandbox-Mode: true

{
  "folios": 4
}
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => '{ HOST }/v1/subscriptions/a20c4a7f2ab443bf8d548b8713a7ab56/remove-folios',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => '',
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 0,
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => 'POST',
  CURLOPT_POSTFIELDS =>'{
    "folios": 4
}',
  CURLOPT_HTTPHEADER => array(
    'Content-Type: application/json',
    'Authorization: ••••••',
    'F-Sandbox-Mode: true'
  ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;


var request = require('request');
var options = {
  'method': 'POST',
  'url': '{ HOST }/v1/subscriptions/a20c4a7f2ab443bf8d548b8713a7ab56/remove-folios',
  'headers': {
    'Content-Type': 'application/json',
    'Authorization': '••••••',
    'F-Sandbox-Mode': 'true'
  },
  body: JSON.stringify({
    "folios": 4
  })

};

request(options, function (error, response) {
  if (error) throw new Error(error);
  console.log(response.body);
});


import requests
import json

url = "{ HOST }/v1/subscriptions/a20c4a7f2ab443bf8d548b8713a7ab56/remove-folios"

payload = json.dumps({
  "folios": 4
})

headers = {
  'Content-Type': 'application/json',
  'Authorization': '••••••',
  'F-Sandbox-Mode': 'true'
}

response = requests.request("POST", url, headers=headers, data=payload)

print(response.text)


require "uri"
require "json"
require "net/http"

url = URI("{ HOST }/v1/subscriptions/a20c4a7f2ab443bf8d548b8713a7ab56/remove-folios")

https = Net::HTTP.new(url.host, url.port)
https.use_ssl = true

request = Net::HTTP::Post.new(url)

request["Content-Type"] = "application/json"
request["F-Sandbox-Mode"] = "true"
request["Authorization"] = "••••••"

request.body = JSON.dump({
  "folios": 4
})

response = https.request(request)

puts response.read_body


Respuesta

{
    "response": "success",
    "data": {
        "uuid": "a2154491e9e04adcabf6a051e2dbdaca",
        "name": "PLAN ELITE",
        "start_date": "2026-06-22T00:00:00.000000Z",
        "end_date": "2026-07-22T00:00:00.000000Z",
        "folios": 101,
        "status": "active",
        "client": {
            "uuid": "a21544903d574f0c889798f8c13965cc",
            "name": "MARTIN LOPEZ EDIT",
            "email": "[email protected]",
            "status": "active"
        },
        "product": {
            "uuid": "a2106219d0724860a1521780eea0827a",
            "name": "PLAN ELITE",
            "status": "active"
        },
        "vigency": "Anual",
        "folios_used": 0
    }
}
{
    "status": "error",
    "message": "Error de validación de datos.",
    "errors": {
        "folios": [
            "The folios field is required."
        ]
    },
    "code": "VALIDATION_FAILED"
}

Suspender suscripción

A continuación se explica la función para suspender una suscripción activa de un cliente. Esta operación permite desactivar temporalmente el plan asignado, deteniendo el acceso a los servicios asociados hasta que la suscripción sea reactivada.

Estos son los parámetros para suspender una suscripción:

ParámetroTipoRequeridoDetalles
 uuids Array Requerido  Lista de UUIDs de las suscripciones que serán suspendidas. Permite enviar uno o múltiples registros.
 uuids[] String Requerido UUID de la suscripción que será suspendida.
 message String Requerido  Mensaje o motivo de la suspensión que será enviado al cliente y registrado en el sistema.
 keep_folios Booleano Requerido  Indica si los folios disponibles de la suscripción deben conservarse después de la suspensión.

Valores aceptados:
• true → Conserva los folios disponibles.
• false → Los folios no se conservan al suspender la suscripción.

Construcción de la URL

Importante

Importante el método para borrar uno o múltiples planes es POST

Host: https://api-partners.factura.com/api

Endpoint: v1/subscriptions/suspend

Ejemplo: https://api-partners.factura.com/api/v1/subscriptions/suspend

Ejemplo para suspender suscripción

POST /v1/subscriptions/suspend HTTP/1.1
Host: {HOST}
Content-Type: application/json
Authorization: Bearer YOUR_ACCESS_TOKEN
F-Sandbox-Mode: true

{
  "uuids": [
    "a2085c1803f9bb39c56227db1daa4de"
  ],
  "message": "prueba por API",
  "keep_folios": true
}
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => '{ HOST }/v1/subscriptions/suspend',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => '',
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 0,
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => 'POST',
  CURLOPT_POSTFIELDS =>'{
    "uuids": [
        "a2085c1803f9bb39c56227db1daa4de"
    ],
    "message": "prueba por API",
    "keep_folios": true
}',
  CURLOPT_HTTPHEADER => array(
    'Content-Type: application/json',
    'Authorization: ••••••',
    'F-Sandbox-Mode: true'
  ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;


var request = require('request');
var options = {
  'method': 'POST',
  'url': '{ HOST }/v1/subscriptions/suspend',
  'headers': {
    'Content-Type': 'application/json',
    'Authorization': '••••••',
    'F-Sandbox-Mode': 'true'
  },
  body: JSON.stringify({
    "uuids": [
      "a2085c1803f9bb39c56227db1daa4de"
    ],
    "message": "prueba por API",
    "keep_folios": true
  })

};

request(options, function (error, response) {
  if (error) throw new Error(error);
  console.log(response.body);
});


import requests
import json

url = "{ HOST }/v1/subscriptions/suspend"

payload = json.dumps({
  "uuids": [
    "a2085c1803f9bb39c56227db1daa4de"
  ],
  "message": "prueba por API",
  "keep_folios": True
})

headers = {
  'Content-Type': 'application/json',
  'Authorization': '••••••',
  'F-Sandbox-Mode': 'true'
}

response = requests.request("POST", url, headers=headers, data=payload)

print(response.text)


require "uri"
require "json"
require "net/http"

url = URI("{ HOST }/v1/subscriptions/suspend")

https = Net::HTTP.new(url.host, url.port)
https.use_ssl = true

request = Net::HTTP::Post.new(url)

request["Content-Type"] = "application/json"
request["F-Sandbox-Mode"] = "true"
request["Authorization"] = "••••••"

request.body = JSON.dump({
  "uuids": [
    "a2085c1803f9bb39c56227db1daa4de"
  ],
  "message": "prueba por API",
  "keep_folios": true
})

response = https.request(request)

puts response.read_body


Respuesta

{
    "response": "success",
    "data": [
        {
            "uuid": "a2154491e9e04adcabf6a051e2dbdaca",
            "name": "PLAN ELITE",
            "start_date": "2026-06-22T00:00:00.000000Z",
            "end_date": "2026-07-22T00:00:00.000000Z",
            "folios": 0,
            "status": "suspended",
            "client": {
                "uuid": "a21544903d574f0c889798f8c13965cc",
                "name": "MARTIN LOPEZ EDIT",
                "email": "[email protected]",
                "status": "active"
            },
            "product": {
                "uuid": "a2106219d0724860a1521780eea0827a",
                "name": "PLAN ELITE",
                "status": "active"
            },
            "vigency": "Anual",
            "folios_used": 0
        }
    ]
}
{
    "status": "error",
    "message": "El recurso solicitado no fue encontrado.",
    "code": "NOT_FOUND"
}

Reactivar suscripción

A continuación se explica la función para reactivar una suscripción previamente suspendida. Esta operación permite restaurar el acceso a los servicios del plan asociado al cliente, volviendo a activar su estado operativo.

Estos son los parámetros para reactivar una suscripción:

ParámetroTipoRequeridoDetalles
 uuids Array Requerido  Lista de UUIDs de las suscripciones que serán reactivadas. Permite enviar uno o múltiples registros.
 uuids[] String Requerido UUID de la suscripción que será reactivada.

Construcción de la URL

Importante

Importante el método para borrar uno o múltiples planes es POST

Host: https://api-partners.factura.com/api

Endpoint: v1/subscriptions/reactivate

Ejemplo: https://api-partners.factura.com/api/v1/subscriptions/reactivate

Ejemplo para reactivar suscripción

POST /v1/subscriptions/reactivate HTTP/1.1
Host: {HOST}
Content-Type: application/json
Authorization: Bearer YOUR_ACCESS_TOKEN
F-Sandbox-Mode: true

{
  "uuids": [
    "a1fe2f3758a54614900a02209b322e9c"
  ]
}
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => '{ HOST }/v1/subscriptions/reactivate',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => '',
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 0,
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => 'POST',
  CURLOPT_POSTFIELDS =>'{
    "uuids": [
        "a1fe2f3758a54614900a02209b322e9c"
    ]
}',
  CURLOPT_HTTPHEADER => array(
    'Content-Type: application/json',
    'Authorization: ••••••',
    'F-Sandbox-Mode: true'
  ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;


var request = require('request');
var options = {
  'method': 'POST',
  'url': '{ HOST }/v1/subscriptions/reactivate',
  'headers': {
    'Content-Type': 'application/json',
    'Authorization': '••••••',
    'F-Sandbox-Mode': 'true'
  },
  body: JSON.stringify({
    "uuids": [
      "a1fe2f3758a54614900a02209b322e9c"
    ]
  })

};

request(options, function (error, response) {
  if (error) throw new Error(error);
  console.log(response.body);
});


import requests
import json

url = "{ HOST }/v1/subscriptions/reactivate"

payload = json.dumps({
  "uuids": [
    "a1fe2f3758a54614900a02209b322e9c"
  ]
})

headers = {
  'Content-Type': 'application/json',
  'Authorization': '••••••',
  'F-Sandbox-Mode': 'true'
}

response = requests.request("POST", url, headers=headers, data=payload)

print(response.text)


require "uri"
require "json"
require "net/http"

url = URI("{ HOST }/v1/subscriptions/reactivate")

https = Net::HTTP.new(url.host, url.port)
https.use_ssl = true

request = Net::HTTP::Post.new(url)

request["Content-Type"] = "application/json"
request["F-Sandbox-Mode"] = "true"
request["Authorization"] = "••••••"

request.body = JSON.dump({
  "uuids": [
    "a1fe2f3758a54614900a02209b322e9c"
  ]
})

response = https.request(request)

puts response.read_body


Respuesta

{
    "response": "success",
    "data": [
        {
            "uuid": "a2154491e9e04adcabf6a051e2dbdaca",
            "name": "PLAN ELITE",
            "start_date": "2026-06-22T00:00:00.000000Z",
            "end_date": "2026-07-22T00:00:00.000000Z",
            "folios": 101,
            "status": "active",
            "client": {
                "uuid": "a21544903d574f0c889798f8c13965cc",
                "name": "MARTIN LOPEZ EDIT",
                "email": "[email protected]",
                "status": "active"
            },
            "product": {
                "uuid": "a2106219d0724860a1521780eea0827a",
                "name": "PLAN ELITE",
                "status": "active"
            },
            "vigency": "Anual",
            "folios_used": 0
        }
    ]
}
{
    "status": "error",
    "message": "El recurso solicitado no fue encontrado.",
    "code": "NOT_FOUND"
}
Prev
Migraciones
Next
Series