Protección app icon
OpenFinance LabIngestion engineering for consumer finance apps
Colombia · AFP · Ingestion engineering notes

Protección (com.ProteccionApp): wiring pension & cesantías reads into a daily data feed

A Colombian AFP affiliate has three balances inside one app — Pensión Obligatoria, Pensión Voluntaria (+Protección), and cesantías — and a PDF locker (Certifácil) sitting next to them. This page describes how we turn that into a freshness-window-driven feed under the user's own consent, while the Finanzas Abiertas perimeter for AFPs is still being operationalised.

App snapshot

AppProtección — Administradora de Fondos de Pensiones y Cesantías Protección S.A. (Grupo SURA)
Package / store idcom.ProteccionApp (Android); iOS App Store id 1015636587
PublisherPensiones y Cesantías Protección, Medellín, Antioquia (per Google Play listing)
Version observed4.3.1, last updated 22 May 2024, per the apps.apple.com Colombia listing
Country / regimeColombia. SFC-supervised AFP under Finanzas Abiertas perimeter (Decreto 0368 de 2026)
Product perimeterPensión Obligatoria, Pensión Voluntaria / +Protección, Cesantías, Certifácil PDFs, pension-request tracking
Data feed shapeJSON snapshot per (affiliate, product) plus binary blob for certificate PDFs
Ingestion cadenceDefault daily 02:00 COT pull; on-demand /refresh for user-triggered views; certificate fetch on request
Sync windowConfigurable 15 min / 1 h / 24 h; missed pulls retried with jittered back-off for 6 h
SDK targetsPython 3.11, Node 20, optional Go 1.22 client
Engagement (snapshot row)Source-code delivery from US$300, paid on acceptance; or pay-per-call hosted endpoint, no upfront. 1–2 week build cycle.

Reachable surfaces (and what stays out)

Protección's consumer surface is the official Android/iOS app plus the Portal Afiliados web channel. Under explicit affiliate consent, both expose the same read perimeter. The scope below is what we treat as in-bounds for an ingestion build; anything beyond is left alone.

Out of bounds for this build: any write that moves money or changes the affiliate's fund, scraping aggregate fund-performance numbers Protección publishes for the market, and anything that would touch another affiliate's record.

What ships in the build

The output is concrete software, not a memo. Order of priority:

  1. Runnable Python (3.11) and Node (20) source — a small library that authenticates against the affiliate channel under the user's consent, pulls the snapshot for the requested products, returns a normalised JSON payload, and writes the raw response next to it for replay.
  2. Sync & freshness design — a scheduler module with the freshness windows from the snapshot row, plus a single /refresh endpoint that fires an on-demand pull and updates your store under the same consent token.
  3. Reconciliation logic — snapshot diffing per (affiliate, product, captured_at), typed alerts for balance jumps outside tolerance, missing-product detection, and a freshness SLO check that raises before a downstream consumer reads stale data.
  4. Automated test harness — recorded-fixture tests covering each product surface, a contract test that fails when the upstream JSON shape drifts, and a smoke test wired for CI.
  5. Secondary, on request: an OpenAPI description of the shipped contract, a one-page authentication-flow note, and a short compliance memo aligned to the Finanzas Abiertas trajectory under Decreto 0368/2026.

Sample call against the shipped contract

The hosted variant exposes one endpoint per product family, plus a certificate retrieval call. Calls are scoped by the consent token issued when the affiliate authorises the link.

# Python 3.11
from openfinance_lab import ProteccionClient

cli = ProteccionClient(consent_token=CONSENT)

# 1) Pension + cesantías snapshot for one affiliate, single round trip
snap = cli.snapshot(products=["pension_obligatoria",
                              "pension_voluntaria",
                              "cesantias"],
                    freshness="1h")     # accept up to 1h-old cached snapshot

print(snap["pension_obligatoria"]["balance_cop"],
      snap["pension_obligatoria"]["fund"],          # e.g. "moderado"
      snap["captured_at"])                          # ISO-8601, COT

# 2) Force a fresh read (on-demand refresh path)
fresh = cli.refresh(products=["cesantias"])

# 3) Pull a Certifácil PDF by type (afiliacion | aportes_retenciones | pensionado)
pdf = cli.certificate(kind="aportes_retenciones", year=2025)
open("cert.pdf", "wb").write(pdf.bytes)

# Response shape (truncated)
# {
#   "affiliate_id": "CO-CC-...redacted...",
#   "captured_at": "2026-05-31T02:14:07-05:00",
#   "pension_obligatoria": {"balance_cop": 184320500, "fund": "moderado",
#                           "last_contribution": "2026-05-15"},
#   "cesantias": {"balance_cop": 6420100,
#                 "employers": [{"nit": "...", "balance_cop": 6420100}]},
#   "pension_voluntaria": {"balance_cop": 21500000,
#                          "alternatives": [{"name": "+Protección Moderado",
#                                            "balance_cop": 21500000}]}
# }

Where teams plug this in

Freshness, reconciliation & failure modes

The ingestion layer is built around three knobs the consumer controls:

Failure modes we model explicitly: affiliate consent revoked mid-cycle, Protección affiliate channel down or rate-limiting, certificate generation queue delay (Certifácil is asynchronous in practice), and product appearing/disappearing in the payload when an affiliate changes plan. Each surfaces as a typed error a consumer can match on, not a 500.

Interface evidence

Screens captured from the public Play Store listing for com.ProteccionApp, used to anchor field names and product surfaces during the build.

Protección app screen 1 Protección app screen 2 Protección app screen 3 Protección app screen 4 Protección app screen 5 Protección app screen 6 Protección app screen 7 Protección app screen 8

Regulatory framing (Colombia)

Protección S.A. is one of four private AFPs operating in Colombia alongside the public Colpensiones, and is supervised by the Superintendencia Financiera de Colombia with policy set by the Unidad de Regulación Financiera. Open Finance was first established as a voluntary regime under Decreto 1297 de 2022 and then replaced by Decreto 0368 de 2026, which makes data-sharing mandatory across SFC-supervised entities — pension fund managers included.

That puts Protección inside the perimeter of supervised entities for Finanzas Abiertas, with one practical caveat: the SFC's technical standards (APIs, data schemas, consent UX) and the AFP go-live date are still being operationalised, on a different track from core deposit banking. Until those rails are live for AFPs, the route we build against is user-consented access to the affiliate channel, with the same contract designed to migrate onto the regulated route once it is published.

Sources & engineering notes

The Protección particulars on this page were checked against the app's public store listings, Protección's own affiliate-portal documentation, and the current Colombian Open Finance regime. Citations link out for verification.

Common questions

How fresh is the Protección data you return?

Pension and cesantías balances are pulled on the cadence the consumer needs — most teams pick daily after 02:00 COT, with on-demand refresh when a user opens their dashboard. Certifácil PDFs are fetched only when the user (or app) asks for one, so we do not stale-cache a tax document.

Batch or realtime — which do you build?

Both. The default is a scheduled pull on a freshness window you pick (15-minute, hourly, daily). For event-style flows we expose a /refresh endpoint that runs an on-demand fetch under the user's consent and writes through to your store. Push from Protección itself is not part of the picture.

Which Protección balances and documents can a consenting user share?

Anything the user can already read in the app or affiliate portal: Pensión Obligatoria balance and fund, Pensión Voluntaria / +Protección plan holdings, cesantías balance and movements, pension-request status, and Certifácil PDFs (afiliación, aportes y retenciones, pensionado).

How is the data reconciled — what stops silent drift?

Each pull writes a snapshot keyed by (affiliate-id, product, captured_at). A nightly job diffs the latest two snapshots per product; balance jumps outside a configurable tolerance, missing products, or a stale capture older than the freshness SLO raise a typed alert on your side.

Does this rely on Decreto 0368 / Finanzas Abiertas being live for AFPs?

No. Decreto 0368 de 2026 brings AFPs into the SFC Open Finance perimeter, but the technical standards and AFP go-live are still being defined. We work today through user-consented access to the affiliate channel, and migrate the same contract to a regulated route once the AFP rails ship.

What SDK targets do you ship against?

Python 3.11 and Node 20 are the defaults; we also publish a thin Go client when teams ask. The contract is the same JSON shape on all of them, so a Python ingestor and a Node consumer see identical fields.

Pricing and how to start

Builds for Protección run on one of these footings, picked when we scope: source-code delivery from US$300, paid after the code is delivered and you are satisfied with the tests passing on your side; or a pay-per-call hosted endpoint on our infrastructure, no upfront fee, billed against the calls your system actually makes. Either way the cycle is 1 to 2 weeks from kick-off to a working ingestion against a sample affiliate account. To start a scope conversation, write in via /contact.html with the products you need (pensión obligatoria / voluntaria / cesantías / Certifácil), your preferred freshness window, and whether you want source or hosted.

ProtecciónAFP ColombiaFinanzas AbiertasSFC perimeter Disclaimer: Protección is the registered consumer app of Administradora de Fondos de Pensiones y Cesantías Protección S.A.; this page describes user-consented ingestion patterns built by OpenFinance Lab and is not affiliated with Grupo SURA.

Reviewed 2026-05-31 · OpenFinance Lab ingestion engineering notes