Nodda Docs

Sync

Un sync extrae datos de la fuente y los persiste. Corre fuera del request: la API crea una corrida durable y responde 202 de inmediato; el procesamiento real ocurre en un workflow asíncrono. Sigue el avance con GET /sync-runs/{runId} o suscríbete a webhooks.

Gatillar un sync

POST /connections/{id}/sync

Cuerpo (todo opcional):

CampoTipoNotas
scopesstring[]scopes a sincronizar (p. ej. ["rcv"]). Deben estar habilitados en la conexión. Si se omite, se usan todos los enabled_scopes de la conexión
metadataobjectmetadatos por scope para esta corrida (p. ej. { "period": "2026-05" } para RCV)

El trigger de las corridas creadas por este endpoint es siempre manual.

Coalescing: si ya existe una corrida queued y aún no despachada para la misma conexión, se reutiliza en lugar de crear una nueva. El sync_id devuelto puede corresponder a una corrida existente.

curl -X POST https://app.nodda.cl/api/connections/3f1c9e2a-7b44-4d51-9a0e-1c2d3e4f5a6b/sync \
  -H "Authorization: Bearer nodda_sk_tu_token_aqui" \
  -H "Content-Type: application/json" \
  -d '{ "scopes": ["rcv"], "metadata": { "period": "2026-05" } }'

Respuesta (202) — el recurso va al tope (sin data):

{
  "sync_id": "9b8c7d6e-5f4a-3b2c-1d0e-9f8a7b6c5d4e",
  "connection_id": "3f1c9e2a-7b44-4d51-9a0e-1c2d3e4f5a6b",
  "scopes": ["rcv"],
  "status": "queued"
}

El 202 significa que la corrida quedó encolada (queued), no que ya terminó.

Metadatos por scope

Los metadatos (metadata) se aplican al scope correspondiente. Cada fuente define los suyos:

FuenteScopeCampos
siircvperiod (string YYYY-MM)
siiguiasperiod (string YYYY-MM), issueType (issued|received, opcional)
banco_securitydirectasperiod (string YYYY-MM)
banco_securitymasivasperiod (string YYYY-MM)
banco_securitymovimientosperiod (string YYYY-MM)
bci_pymemovimientosperiod (string YYYY-MM)

Puedes consultar el sync_metadata de cada scope en el descriptor de conexión.

Listar corridas de sync

GET /connections/{id}/sync-runs

Devuelve las 10 corridas más recientes de la conexión, de la más nueva a la más antigua.

curl https://app.nodda.cl/api/connections/3f1c9e2a-7b44-4d51-9a0e-1c2d3e4f5a6b/sync-runs \
  -H "Authorization: Bearer nodda_sk_tu_token_aqui"

Respuesta (200):

{
  "data": [
    {
      "id": "9b8c7d6e-5f4a-3b2c-1d0e-9f8a7b6c5d4e",
      "connection_id": "3f1c9e2a-7b44-4d51-9a0e-1c2d3e4f5a6b",
      "scopes": ["rcv"],
      "scope_outcomes": [],
      "trigger": "manual",
      "status": "running",
      "started_at": "2026-06-09T10:30:00.000Z",
      "finished_at": null,
      "error_code": null,
      "error_message": null,
      "records_found": 42,
      "records_created": 15,
      "records_updated": 8,
      "progress": {
        "stage": "fetching_rcv_detail",
        "message": "Procesando documentos",
        "updated_at": "2026-06-09T10:30:45.000Z"
      },
      "created_at": "2026-06-09T10:30:00.000Z"
    }
  ]
}

Obtener una corrida de sync

GET /connections/{id}/sync-runs/{runId}

Devuelve una corrida de sync en detalle, incluyendo scope_outcomes por scope e input_metadata (los metadatos de entrada con secretos redactados). Usa este endpoint para polling hasta que la corrida termine.

curl https://app.nodda.cl/api/connections/3f1c9e2a-7b44-4d51-9a0e-1c2d3e4f5a6b/sync-runs/9b8c7d6e-5f4a-3b2c-1d0e-9f8a7b6c5d4e \
  -H "Authorization: Bearer nodda_sk_tu_token_aqui"

Respuesta (200):

{
  "data": {
    "id": "9b8c7d6e-5f4a-3b2c-1d0e-9f8a7b6c5d4e",
    "connection_id": "3f1c9e2a-7b44-4d51-9a0e-1c2d3e4f5a6b",
    "scopes": ["rcv", "guias"],
    "scope_outcomes": [
      {
        "scope": "rcv",
        "status": "ok",
        "records_found": 42,
        "period": "2026-05",
        "error_code": null,
        "error_message": null,
        "notices": []
      },
      {
        "scope": "guias",
        "status": "failed",
        "records_found": null,
        "period": "2026-05",
        "error_code": "fetch_error",
        "error_message": "No se pudo conectar al portal",
        "notices": []
      }
    ],
    "trigger": "manual",
    "status": "partial",
    "started_at": "2026-06-09T10:30:00.000Z",
    "finished_at": "2026-06-09T10:31:15.000Z",
    "error_code": null,
    "error_message": null,
    "records_found": 42,
    "records_created": 15,
    "records_updated": 8,
    "progress": null,
    "input_metadata": { "period": "2026-05" },
    "created_at": "2026-06-09T10:30:00.000Z"
  }
}

Polling

Haz polling sobre GET /sync-runs/{runId} hasta que status sea terminal:

statusSignificado
queuedencolada, esperando despacho
runningen ejecución
succeededtodos los scopes completaron sin error (pueden incluir notices informativos)
partialalgunos scopes completaron, otros fallaron (ver scope_outcomes)
failedla corrida falló completamente

Los estados succeeded y partial son terminales. Revisa scope_outcomes para el detalle por scope cuando el estado es partial.

Campos de una corrida de sync

CampoTipoNotas
idUUIDidentificador de la corrida
connection_idUUIDconexión asociada
scopesstring[]scopes sincronizados en esta corrida
scope_outcomesobject[]resultado por scope (ver abajo)
triggerstringmanual · scheduled · system
statusstringqueued · running · succeeded · failed · partial
started_atdatetime | nullcuándo empezó (null si aún queued)
finished_atdatetime | nullcuándo terminó (null si en curso)
error_codestring | nullcódigo de error si la corrida falló totalmente
error_messagestring | nullmensaje de error con secretos redactados
records_foundnumber | nullregistros descubiertos en total
records_creatednumber | nullregistros nuevos persistidos
records_updatednumber | nullregistros actualizados
progressobject | nullavance sanitizado: { stage, message, updated_at }
input_metadataobjectmetadatos de entrada con secretos redactados (solo en GET /{runId})
created_atdatetimecuándo se creó la corrida

Campos de scope_outcomes[]

CampoTipoNotas
scopestringnombre del scope
statusstringok · partial · failed
records_foundnumber | nullregistros descubiertos para este scope
duration_msinteger | nullWall-clock milliseconds this scope took during the sync run.
periodstring | nullperiodo (YYYY-MM) sincronizado para este scope; null en scopes point-in-time (ej. saldos)
error_codestring | nullcódigo de error si este scope falló
error_messagestring | nullmensaje de error con secretos redactados
noticesobject[]avisos informativos { code, message } que no degradan la corrida (ver abajo)

progress.stage se limita a una lista blanca de etapas conocidas (p. ej. sii_login, fetching_rcv_detail, projecting_rcv_documents, completed); los mensajes redactan RUTs y secretos.

Avisos (notices)

Cada scope_outcomes[] incluye notices: condiciones informativas y esperadas que no degradan el estado de la corrida. A diferencia de un error, un aviso no cambia el status del scope (ok) ni del run (succeeded).

Caso típico: SII solo conserva el detalle de las guías de los últimos 6 meses. Para períodos más viejos el scope guias igual termina ok, pero deja un aviso sii.guias.out_of_window:

{
  "scope": "guias",
  "status": "ok",
  "records_found": 0,
  "error_code": null,
  "error_message": null,
  "notices": [
    { "code": "sii.guias.out_of_window", "message": "2 period(s) outside the 6-month detail window" }
  ]
}

Cada aviso es { code, message }: code es estable y pensado para programar contra él; message es legible y va con secretos redactados.

Errores

  • 400 validation_error — cuerpo inválido (JSON malformado o tipos incorrectos).
  • 404 connection_not_found — la conexión no existe o no pertenece a tu organización.
  • 404 sync_run_not_found — la corrida no existe en esa conexión.
  • 422 scope_not_supported — alguno de los scopes pedidos no existe en el conector de la fuente.
  • 422 scope_not_enabled — alguno de los scopes pedidos no está habilitado en la conexión.
  • 422 invalid_sync_metadata — los metadatos de sync no pasan la validación del scope.

Catálogo completo en Errores.

On this page