Guías por comprobante
Guías de remisión electrónicas por API
Emite guías de remisión remitente (09) y transportista (31) con la API nueva de SUNAT en una sola llamada: crear, enviar y consultar el ticket.
Actualizado el
La guía de remisión respalda el traslado de mercadería. La API v1 la emite en una sola llamada: la crea, la envía a
la API de guías de SUNAT y consulta el ticket una vez. Si SUNAT todavía no responde, queda pendiente y la vuelves a
consultar con GET /guias/{id}.
| Guía | codigo_tipo_documento |
Quién la emite |
|---|---|---|
| Remitente | 09 |
El dueño de la mercadería que la traslada (venta, traslado entre locales, compra…) |
| Transportista | 31 |
La empresa de transporte que lleva carga ajena y cobra el flete |
- Endpoint:
POST /guias· alcanceguias.emitir. - Series: las de guía de tu local (
GET /establecimientos); por norma de SUNAT las de remitente empiezan con T y las de transportista con V. - En producción la empresa necesita sus credenciales de guías (usuario secundario SOL, Client ID y Client secret) o enviar por un PSE. Ver pase a producción.
Guía de remitente: JSON mínimo
Traslado de 40 bolsas de cemento por venta, en transporte privado (con chofer y vehículo propios):
{
"serie_documento": "T001",
"numero_documento": "#",
"fecha_de_emision": "2026-11-04",
"hora_de_emision": "09:00:00",
"codigo_tipo_documento": "09",
"datos_del_cliente_o_receptor": {
"codigo_tipo_documento_identidad": "6",
"numero_documento": "20601234567",
"apellidos_y_nombres_o_razon_social": "CONSTRUCTORA ANDINA S.A.C."
},
"codigo_modo_transporte": "02",
"codigo_motivo_traslado": "01",
"fecha_de_traslado": "2026-11-04",
"peso_total": 1000,
"unidad_peso_total": "KGM",
"direccion_partida": { "ubigeo": "150101", "direccion": "Av. Lima 123", "codigo_del_domicilio_fiscal": "0000" },
"direccion_llegada": { "ubigeo": "150132", "direccion": "Jr. Las Obras 456", "codigo_del_domicilio_fiscal": "0000" },
"chofer": {
"codigo_tipo_documento_identidad": "1",
"numero_documento": "40123456",
"nombres": "Luis Quispe",
"numero_licencia": "Q40123456"
},
"vehiculo": { "numero_de_placa": "ABC123" },
"items": [
{ "codigo_interno": "CEM-42", "descripcion": "Cemento 42.5 kg", "unidad_de_medida": "NIU", "cantidad": 40 }
]
}
curl -X POST https://pruebas.sistemafacturacionperu.com/api/v1/guias \
-H "Authorization: Bearer $SFP_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: guia-$(uuidgen)" \
-d @guia.json
<?php
$ch = curl_init('https://pruebas.sistemafacturacionperu.com/api/v1/guias');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_TIMEOUT => 90,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('SFP_API_KEY'),
'Content-Type: application/json',
'Idempotency-Key: ' . bin2hex(random_bytes(16)),
],
CURLOPT_POSTFIELDS => file_get_contents('guia.json'),
]);
$guia = json_decode(curl_exec($ch), true)['data'];
import { readFile } from 'node:fs/promises';
import { randomUUID } from 'node:crypto';
const res = await fetch('https://pruebas.sistemafacturacionperu.com/api/v1/guias', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.SFP_API_KEY}`,
'Content-Type': 'application/json',
'Idempotency-Key': randomUUID(),
},
body: await readFile('guia.json', 'utf8'),
});
const { data: guia } = await res.json();
r = requests.post(
"https://pruebas.sistemafacturacionperu.com/api/v1/guias",
json=json.load(open("guia.json", encoding="utf-8")),
headers={"Authorization": f"Bearer {os.environ['SFP_API_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
timeout=90,
)
guia = r.json()["data"]
Respuesta (201), aceptada o pendiente:
{
"success": true,
"data": {
"id": 310,
"external_id": "4c5d6e7f-…",
"tipo": "09",
"numero_completo": "T001-58",
"fecha_emision": "2026-11-04",
"fecha_traslado": "2026-11-04",
"estado": { "codigo": "05", "clave": "aceptado", "descripcion": "Aceptado" },
"ticket": "a9b8c7d6-…",
"sunat": { "codigo": "0", "descripcion": "…", "notas": [] },
"enlaces": { "pdf": "…/guias/310/pdf", "xml": "…/guias/310/xml", "cdr": "…/guias/310/cdr" },
"avisos": []
}
}
Si el envío falló, la guía queda creada y avisos dice qué pasó y cómo reintentar: POST /guias/{id}/enviar.
Campos clave
| Campo | Qué poner |
|---|---|
codigo_modo_transporte |
01 transporte público (lo lleva una empresa de transporte) · 02 transporte privado (tu chofer y tu vehículo) |
codigo_motivo_traslado |
01 venta · 02 compra · 04 traslado entre locales de la misma empresa · 13 otros (con descripcion_motivo_traslado) |
peso_total / unidad_peso_total |
Peso bruto total; KGM (kilos) o TNE (toneladas) |
direccion_partida / direccion_llegada |
Ubigeo de 6 dígitos y dirección de hasta 100 caracteres; codigo_del_domicilio_fiscal es el código SUNAT del local |
transportista |
Solo con transporte público: codigo_tipo_documento_identidad, numero_documento (RUC), apellidos_y_nombres_o_razon_social y numero_mtc |
chofer / vehiculo |
Con transporte privado: documento, nombres y licencia del chofer; placa del vehículo |
items[].codigo_interno |
Obligatorio en cada línea (con descripcion y cantidad mayor que 0) |
Con transporte público, cambia chofer y vehiculo por la empresa de transporte:
{
"codigo_modo_transporte": "01",
"transportista": {
"codigo_tipo_documento_identidad": "6",
"numero_documento": "20512345678",
"apellidos_y_nombres_o_razon_social": "TRANSPORTES RAPIDOS S.A.C.",
"numero_mtc": "1234567CNG"
}
}
La guía de una venta (y al revés)
- Para emitir la guía de una cotización o un pedido, manda
"origen": {"tipo": "pedido", "id": 33}. - Para facturar lo que ya salió con una guía, emite la factura con
"origen": {"tipo": "guia", "id": 310}: queda amarrada y la mercadería no se descuenta dos veces. Si el amarre no se puede hacer, la factura igual se emite yavisoslo dice.
Guía de transportista (31)
La emite la empresa de transporte. En vez del cliente lleva al remitente y al destinatario de la carga:
{
"codigo_tipo_documento": "31",
"datos_remitente": {
"codigo_tipo_documento_identidad": "6",
"descripcion_tipo_documento_identidad": "RUC",
"numero_documento": "20601234567",
"apellidos_y_nombres_o_razon_social": "FERRETERIA LIMA S.A.C."
},
"datos_destinatario": {
"codigo_tipo_documento_identidad": "6",
"descripcion_tipo_documento_identidad": "RUC",
"numero_documento": "20601234568",
"apellidos_y_nombres_o_razon_social": "CONSTRUCTORA ANDINA S.A.C."
}
}
Lo demás (fechas, peso, partida, llegada, chofer, vehículo e ítems) va como en la de remitente. Te recomendamos probar tu primera guía de transportista en el modo pruebas antes de pasar a producción.
Estados y avisos
aceptadoorechazado: SUNAT respondió el ticket en la misma llamada.pendiente: SUNAT aún no responde.GET /guias/{id}vuelve a consultar el ticket.- Webhooks:
guia.aceptadayguia.rechazada. - Archivos:
GET /guias/{id}/pdf,/xmly/cdr.
Si tu plan ya llegó a su límite de comprobantes del ciclo, la guía responde 422
limite_planantes de crear nada, como en la web.