Saltar al contenido
Tarifa anual desde S/ 37 al mes + IGV. Pide tu demo sin costo. Reserva tu demo
Sistema Facturación Perú
Menú del portal

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 · alcance guias.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 y avisos lo 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

  • aceptado o rechazado: SUNAT respondió el ticket en la misma llamada.
  • pendiente: SUNAT aún no responde. GET /guias/{id} vuelve a consultar el ticket.
  • Webhooks: guia.aceptada y guia.rechazada.
  • Archivos: GET /guias/{id}/pdf, /xml y /cdr.

Si tu plan ya llegó a su límite de comprobantes del ciclo, la guía responde 422 limite_plan antes de crear nada, como en la web.

Portal para desarrolladores · ¿Algo no está claro o te falta un ejemplo? Escríbenos y lo mejoramos.