Connect

Carpeta tributaria puntual

Solicita el PDF original del SII mediante el widget y recibe el resultado por API o webhook.

Esta capacidad está en piloto y requiere habilitación de tu organización. El receptor se configura en el servidor y queda fijado al crear la solicitud. La autorización muestra esa institución; quien abre el enlace no puede cambiarla.

El widget conserva cuatro pantallas: autorización, credenciales de la empresa, verificación y confirmación. La confirmación significa que Emisso aceptó la solicitud; el PDF se obtiene en segundo plano.

Si incrustas el enlace, el mensaje emisso:connect con status: "connected" confirma esa aceptación, sin esperar el PDF. Al pulsar Continuar, el retorno agrega status=connected y connection_id a tu redirect_uri; salir antes de aceptar devuelve status=failed, sin ID de conexión. Sigue consultando el ID de solicitud para conocer su resultado: salir de la pantalla no cancela el trabajo. Recargar un acuse válido muestra la confirmación, sin volver a pedir la clave ni abrir acceso al SII.

Crear una solicitud

La API key necesita sii:carpeta_tributaria:generar. La solicitud se crea con POST /api/v1/connect_sessions, con mode: "create", connector_code: "sii" y el bloque collection. No admite conexión existente, reauth, credential_scheme, emitir ni alcances.

La cabecera Idempotency-Key es obligatoria: hasta 128 caracteres ASCII visibles, sin espacios. Usa una estable por solicitud y conserva la misma identidad de API key al reintentar. Repetirla con el mismo contenido devuelve el mismo enlace mientras la solicitud espera autorización; después devuelve los identificadores y el estado de esa solicitud, sin enlace ni token. Con contenido distinto devuelve idempotency_conflict. El enlace dura 24 horas y es secreto; no lo publiques ni lo registres en logs.

const API = "https://connect.emisso.ai/api/v1";
const auth = { Authorization: `Bearer ${process.env.EMISSO_CONNECT_API_KEY}` };

const res = await fetch(`${API}/connect_sessions`, {
  method: "POST",
  headers: {
    ...auth,
    "Content-Type": "application/json",
    // Estable por solicitud: recupera el enlace pendiente o el estado de la solicitud ya aceptada.
    "Idempotency-Key": "application_42_carpeta_v1",
  },
  body: JSON.stringify({
    mode: "create",
    connector_code: "sii",
    collection: {
      kind: "sii_tax_folder",
      mode: "once",
      folder_type: "credit",
      expected_rut: "76123456-0",
      purpose: "Evaluación comercial solicitada por el cliente",
      external_reference: "application_42",
    },
    allowed_origins: ["https://tu-aplicacion.example"],
    redirect_uri: "https://tu-aplicacion.example/solicitud",
  }),
});
const { data: solicitud, error } = await res.json();
if (error) throw new Error(JSON.stringify(error));
// Guarda siempre solicitud.collection_request_id.
if (solicitud.url) {
  // Abre este enlace con el widget hosted mientras espera autorización.
} else {
  // Ya fue aceptada o terminó: consulta la solicitud existente, sin crear otra.
}

La respuesta (201) trae en data collection_request_id y collection_status. Al crearla o recuperar el enlace pendiente también incluye la sesión con url y expires_at; el status de esa sesión no es el estado de la carpeta. Después de aceptar el enlace, un reintento conserva los mismos identificadores y devuelve connection_id, document_id, error_code y expires_at, sin recuperar el token.

Consultar y descargar

const id = solicitud.collection_request_id;
const consulta = await (await fetch(`${API}/collection_requests/${id}`, { headers: auth })).json();
if (consulta.error) throw new Error(JSON.stringify(consulta.error));
const resultado = consulta.data;
if (resultado.status === "ready" && resultado.document?.available) {
  const documento = resultado.document.id;
  const pedido = await (await fetch(`${API}/collection_documents/${documento}/download`, { headers: auth })).json();
  if (pedido.error) throw new Error(JSON.stringify(pedido.error));
  // pedido.data.url vence en pedido.data.expires_in segundos (300).
}

Endpoints: GET /api/v1/collection_requests/:id y GET /api/v1/collection_documents/:id/download. La descarga devuelve una URL firmada al PDF original privado. El resultado incluye SHA-256, tamaño, fecha de generación y retención. El archivo se elimina a los 30 días; los metadatos sensibles se purgan a los 90 días.

Emitir el enlace de descarga y cancelar efectivamente una solicitud quedan en la bitácora de control con el actor y la credencial que los solicitaron. La URL firmada no se guarda en esa bitácora; ese registro acredita la emisión del enlace, no que el destinatario haya descargado el archivo.

Estados: awaiting_authorization, queued, processing, ready, failed, inconclusive, expired, canceled. inconclusive significa que pudo ocurrir una emisión cuya respuesta no se confirmó, o que el SII ya generó la carpeta y Emisso no completó la entrega del PDF. Emisso no repite ese POST automáticamente: revisa el resultado antes de pedir otra carpeta. expired corresponde a una autorización vencida antes de iniciar la emisión.

failed indica una falla definitiva o intentos agotados antes de iniciar la emisión; error_code explica la causa. Si la entrega falla tras emitir, el estado es inconclusive, incluso cuando el código identifica un PDF inválido o un contribuyente distinto. Revisa la carpeta emitida: esos problemas no se solucionan generando otra.

POST /api/v1/collection_requests/:id/cancel cancela solicitudes que no están ejecutándose. Si hay trabajo activo devuelve connection_busy. Cancelar no revoca una carpeta emitida por el SII.

Webhooks

Suscribe sii.carpeta_tributaria.ready y sii.carpeta_tributaria.failed mediante la configuración de webhooks existente. sii.carpeta_tributaria.failed cubre todo final sin carpeta: failed, inconclusive, expired y canceled; el estado exacto viene en data.status. Usan la firma y los reintentos habituales. Deduplica por la cabecera webhook-id y consulta la API para recuperar el estado si el webhook no llega.

El evento contiene los identificadores de solicitud, sesión, conexión y documento, external_reference, estado, identity_verified y error_code. Emisso no agrega el PDF, el RUT del contribuyente, la contraseña, el código/clave del repositorio SII ni la URL firmada. Solo ready habilita la descarga.

Usa un identificador opaco en external_reference, como application_42: ese valor se copia al evento. No pongas un RUT ni otros datos personales; la purga de la carpeta no borra los eventos de webhook que ya se publicaron.

La conexión temporal sirve exclusivamente para esta solicitud. No permite RCV, emisión de DTE, sincronizaciones programadas ni renovar credenciales. El plazo de acceso de 15 minutos comienza con el primer intento de verificación y no se renueva al reintentar. El enlace admite hasta cinco intentos. Cerrar y purgar las credenciales precede al resultado terminal y su evento.

En esta página