Reenviar PDF de Factura
Reenvia el PDF de una factura por correo electronico al cliente.
Caso de uso
Util cuando el cliente no recibio el correo original o necesita una copia adicional.
Endpoint
POST https://api.lummy.io/v1/invoices/{invoiceId}/resend-pdf
| Entorno | URL |
|---|---|
| Producción | https://api.lummy.io/v1/invoices/{invoiceId}/resend-pdf |
| Sandbox | https://sandbox.lummy.io/v1/invoices/{invoiceId}/resend-pdf |
Headers
{
"Authorization": string,requerido
↳Token de autenticación Bearer (JWT) o API Key. Formato: "Bearer <token>". Se utiliza para validar la identidad del solicitante y verificar que tiene permisos para reenviar facturas en la organización especificada.
"x-organization-id": string (UUID),requerido
↳Identificador único de tu organización en Lummy. Este valor se obtiene al crear tu cuenta y es necesario para todas las operaciones relacionadas con facturación electrónica.
"x-api-key": stringrequerido
↳Clave de API para autenticación. Se genera desde el panel de Lummy y debe mantenerse confidencial. Es una alternativa al token Bearer JWT para autenticar tus solicitudes.
}
Path Parameters
{
"invoiceId": string (UUID)requerido
↳Identificador único interno de la factura en el sistema Lummy cuyo PDF se desea reenviar. Se genera automáticamente al momento de crear la factura.
}
Body Parameters
{
"email": stringopcional
↳Dirección de correo electrónico alternativa a donde se enviará el PDF de la factura. Si se omite este campo, el PDF se enviará automáticamente al correo electrónico del receptor registrado en el CFDI. Útil para enviar copias adicionales a diferentes destinatarios.
}
Ejemplos de Codigo
- cURL
- Node.js (TypeScript)
- Python
- PHP (Guzzle)
# Reenviar al email original del receptor
curl -X POST https://sandbox.lummy.io/invoices/550e8400-e29b-41d4-a716-446655440000/resend-pdf \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${ACCESS_TOKEN}" \
-H "x-organization-id: ${LUMMY_ORG_ID}" \
-H "x-api-key: ${LUMMY_API_KEY}"
# Reenviar a un email alternativo
curl -X POST https://sandbox.lummy.io/invoices/550e8400-e29b-41d4-a716-446655440000/resend-pdf \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${ACCESS_TOKEN}" \
-H "x-organization-id: ${LUMMY_ORG_ID}" \
-H "x-api-key: ${LUMMY_API_KEY}" \
-d '{
"email": "otro-email@cliente.com"
}'
import axios from 'axios';
interface ResendPdfResponse {
success: boolean;
sentTo: string;
sentAt: string;
}
async function reenviarPdf(
invoiceId: string,
email?: string
): Promise<ResendPdfResponse> {
const API_URL = `https://sandbox.lummy.io/invoices/${invoiceId}/resend-pdf`;
const response = await axios.post<ResendPdfResponse>(
API_URL,
email ? { email } : {},
{
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${process.env.ACCESS_TOKEN}`,
'x-organization-id': process.env.LUMMY_ORG_ID!,
'x-api-key': process.env.LUMMY_API_KEY!,
},
}
);
console.log(`PDF reenviado a: ${response.data.sentTo}`);
return response.data;
}
// Reenviar al email original
reenviarPdf('550e8400-e29b-41d4-a716-446655440000');
// Reenviar a email alternativo
reenviarPdf('550e8400-e29b-41d4-a716-446655440000', 'otro@email.com');
import os
import requests
def reenviar_pdf(invoice_id, email=None):
api_url = f"https://sandbox.lummy.io/invoices/{invoice_id}/resend-pdf"
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {os.getenv('ACCESS_TOKEN')}",
"x-organization-id": os.getenv("LUMMY_ORG_ID"),
"x-api-key": os.getenv("LUMMY_API_KEY"),
}
payload = {"email": email} if email else {}
response = requests.post(api_url, json=payload, headers=headers)
response.raise_for_status()
data = response.json()
print(f"PDF reenviado a: {data['sentTo']}")
return data
if __name__ == "__main__":
reenviar_pdf("550e8400-e29b-41d4-a716-446655440000")
<?php
require 'vendor/autoload.php';
use GuzzleHttp\Client;
function reenviarPdf(string $invoiceId, ?string $email = null): array
{
$client = new Client([
'base_uri' => 'https://sandbox.lummy.io',
'headers' => [
'Content-Type' => 'application/json',
'Authorization' => 'Bearer ' . getenv('ACCESS_TOKEN'),
'x-organization-id' => getenv('LUMMY_ORG_ID'),
'x-api-key' => getenv('LUMMY_API_KEY'),
],
]);
$payload = $email ? ['email' => $email] : [];
$response = $client->post("/invoices/{$invoiceId}/resend-pdf", [
'json' => $payload,
]);
$data = json_decode($response->getBody(), true);
echo "PDF reenviado a: " . $data['sentTo'] . "\n";
return $data;
}
reenviarPdf('550e8400-e29b-41d4-a716-446655440000');
Respuestas
Todas las respuestas siguen el formato estándar StandardResponse.
200 OK
PDF reenviado exitosamente.
{
"requestId": "abc123-def456",
"data": {
"success": true,
"sentTo": "cliente@empresa.com",
"sentAt": "2025-01-20T10:30:00.000Z"
},
"timestamp": "2025-01-20T10:30:00.000Z",
"path": "/invoices/550e8400-e29b-41d4-a716-446655440000/resend-pdf",
"method": "POST"
}
404 Not Found
Factura no encontrada.
{
"requestId": "abc123-def456",
"error": {
"message": "Invoice not found",
"code": "NotFoundException",
"status": 404
},
"timestamp": "2025-01-20T10:30:00.000Z",
"path": "/invoices/550e8400-e29b-41d4-a716-446655440000/resend-pdf",
"method": "POST"
}
400 Bad Request
Email invalido.
{
"requestId": "abc123-def456",
"error": {
"message": "Email invalido",
"code": "ValidationError",
"status": 400
},
"timestamp": "2025-01-20T10:30:00.000Z",
"path": "/invoices/550e8400-e29b-41d4-a716-446655440000/resend-pdf",
"method": "POST"
}
429 Too Many Requests
Limite de reenvios alcanzado (max 10 por hora por factura).
{
"requestId": "abc123-def456",
"error": {
"message": "Has alcanzado el limite de reenvios para esta factura. Intenta mas tarde.",
"code": "TooManyRequestsException",
"status": 429
},
"timestamp": "2025-01-20T10:30:00.000Z",
"path": "/invoices/550e8400-e29b-41d4-a716-446655440000/resend-pdf",
"method": "POST"
}
Notas
- El PDF incluye el XML timbrado como adjunto
- El correo se envia desde
facturas@lummy.mx - Maximo 10 reenvios por hora por factura