Skip to content
Prosperas
  • Quiénes Somos
  • Contacto
    • Marketplace Soporte
    • Ventas
  • Recursos
    • Docs
    • Blog
  • Quiénes Somos
  • Contacto
    • Marketplace Soporte
    • Ventas
  • Recursos
    • Docs
    • Blog

Descripción general / Overview

2
  • Descripción general
  • Overview

Onboarding

2
  • Onboarding y aprovisionamiento
  • Onboarding and provisioning

Postbacks

2
  • Sistema de postback
  • Postback system

Flujo embebido / Embedded Flow

2
  • Flujo Embebido — cómo embebernos
  • Embedded Flow — how to embed with us

Datos de producto / Product Data

2
  • Requisitos de datos del producto
  • Product data requirements
View Categories
  • Home
  • Docs
  • Postbacks
  • Postback system

Postback system

10 min read

🇨🇴 Leer en español →

Overview #

When a consumer applies for one of your products through Prosperas,
you process that application on your side (approve it, disburse it,
reject it). A postback is how you tell Prosperas what
happened, in near real time, so we can update the lead status, reconcile
revenue, and keep the consumer experience in sync.

The integration is deliberately small: one endpoint, one
credential, one payload shape.

Property Value
Direction You → Prosperas (you call us)
Endpoint POST {BASE_URL}/client_app/webhook/lender/loan-status
Auth X-API-KEY header (recommended) or
source-IP allowlist
Body format JSON, snake_case
Events application, approval,
disbursement, rejected
Success 200 OK with a JSON acknowledgement
Retries You retry on 5xx / network errors (we
do not retry you)

{BASE_URL} is the Prosperas base URL for your market
(Colombia / Mexico). Prosperas will give you the exact staging and
production URLs during onboarding.


Authentication #

Every postback must authenticate. Prosperas checks the API
key first
, then the source IP. If neither
matches a registered credential, the request is rejected with
403.

API key (recommended) #

Send your key in the HTTP header:

X-API-KEY: <your-key>
  • The header name is case-insensitive
    (X-API-KEY, x-api-key, X-Api-Key
    all work).
  • The key is matched by exact string. No prefix, no
    Bearer, no encoding.

IP allowlist (alternative) #

If you were provisioned by IP, no header is required — we read your
source IP from X-Forwarded-For, then
X-Real-IP, then the socket peer.

  • The match is exact string against the IP we
    registered.
  • No CIDR / subnet ranges are supported. Every
    individual egress IP you use must be registered. If your infrastructure
    rotates IPs, use the API key method instead.

The “a lead must exist” rule #

Authentication is not only about the credential — it is bound to a
real lead. A request succeeds only when all of the
following hold:

  1. Your credential (key or IP) matches a registered lender origin,
    and
  2. the click_id in the request resolves to a lead,
    and
  3. that lead belongs to a product owned by your lender
    account.

If your credential is valid but the click_id does not
resolve to one of your leads, you still get
403 (not 404). In practice
this means: a wrong, unknown, or foreign click_id
returns 403.

Security note: There is no HMAC / request-signing on
this endpoint. Protect your API key like any other secret: store it in a
secrets manager, never commit it, never send it in plaintext, and ask
Prosperas to rotate it if it is ever exposed.


The tracking id
(click_id) #

click_id is the single identifier that ties a consumer’s
journey together across Prosperas and your systems.

  • Prosperas generates it and hands it to you at the moment the
    consumer is redirected to you (as the tracking / click identifier in the
    hand-off URL).
  • You must store it and echo it back — exactly — in every
    postback
    for that application.
  • It carries no personal data; it is an opaque
    reference.

Accepted formats:

Format Example Notes
Bare UUID 7e1c2f1f-9b4d-4c1d-9f6c-2f3c1a2b4d5e
orgname_UUID claro_7e1c2f1f-9b4d-4c1d-9f6c-2f3c1a2b4d5e Exactly one underscore

More than one underscore, or an unparseable UUID, returns
400.


Request contract #

Method: POST (recommended). A
GET variant exists with the same fields as query
parameters, but POST with a JSON body is the supported server-to-server
method.

Headers:

Content-Type: application/json
X-API-KEY: <your-key>

Body (JSON, snake_case):

{
  "click_id": "claro_7e1c2f1f-9b4d-4c1d-9f6c-2f3c1a2b4d5e",
  "event": "approval",
  "occurred_at": "2026-07-01T12:34:56Z",
  "data": {
    "provider": "your-brand",
    "client": {
      "email": "consumer@example.com",
      "fullName": "Ana Gomez",
      "firstName": "Ana",
      "lastName": "Gomez",
      "idNumber": "1234567890",
      "phoneNumber": "3001234567",
      "returningCustomer": false
    }
  }
}

Field reference #

Field Type Required Notes
click_id string Yes The tracking id described above. Echo it exactly.
event string Yes One of application, approval,
disbursement, rejected. Lowercase
only
— uppercase is rejected with 422.
occurred_at string — ISO-8601 timestamp of when the event happened on your side (e.g.
2026-07-01T12:34:56Z).
data object — Optional audit blob. Recognized keys: provider (string)
and client (object below).
data.client object — Optional consumer data. See next section.

The data.client
object (optional) #

data.client lets you enrich the consumer record.
All fields are optional.

Field Type Notes
email string
firstName string Used only if fullName is absent.
lastName string Used only if fullName is absent.
fullName string Takes priority: first token → first name, remainder → last
name.
idNumber string National ID / document number.
phoneNumber string
returningCustomer boolean Defaults to false if omitted. See the caution
below.

Important — we never overwrite consumer-entered
data.
data.client only fills fields that are
currently empty on the consumer’s record. Anything the
consumer already provided in the Prosperas flow wins. This protects data
the consumer explicitly entered.

Caution — returningCustomer is not
sticky.
If you omit returningCustomer on a
postback, it is treated as false. If you rely on this flag,
send it explicitly on every postback where it should be
true.


Events & lifecycle #

Send one postback per status transition, using the event that matches
what happened:

event Meaning Required?
application The consumer’s application was received / started on your side. Optional
approval The application was approved. Yes
disbursement Funds were disbursed. Yes
rejected The application was rejected. Yes

application is accepted but optional — send it if you
have a meaningful “application received” milestone; otherwise the three
terminal outcomes (approval, disbursement,
rejected) are what matter most.

Send events in the order they occur. Prosperas
tolerates events arriving out of order, but in-order delivery keeps the
lead history clean.


Responses & status codes #

Success body (200 OK):

{
  "ok": true,
  "lead_id": 12345,
  "status": "APPROVAL",
  "user_id": 6789
}
  • ok — always true on success.
  • lead_id — the Prosperas lead the event was recorded
    against.
  • status — the internal status your event mapped to
    (APPLICATION / APPROVAL /
    DISBURSEMENT / REJECTED).
  • user_id — the consumer record id, when available.

Status codes:

Code Meaning What you should do
200 Event recorded. Done.
400 Malformed click_id (bad UUID or too many
underscores).
Fix the click_id; do not retry
unchanged.
403 Auth failed or the click_id doesn’t
resolve to one of your leads.
Check your key/IP and that you’re echoing the correct
click_id. Do not blindly retry.
404 Session not found (rare edge, after auth succeeds). Verify the click_id; contact Prosperas if it
persists.
422 Validation error — e.g. camelCase clickId, uppercase
event, wrong types.
Fix the payload shape (see common mistakes below). Do
not retry unchanged.
5xx Transient Prosperas-side error. Retry with exponential backoff (see below).

Common mistakes
(read this before you build) #

These four mistakes account for almost every failed first
integration. Avoid them:

❌ Don’t ✅ Do
Use camelCase clickId in the body Use snake_case click_id — camelCase →
422
Send event: "APPROVAL" (uppercase) Send lowercase approval — uppercase →
422
Assume the endpoint is public / no auth Send X-API-KEY (or call from an
allowlisted IP) — else 403
Put the API key in a query string or expect the pixel to
authenticate
Send the key in the X-API-KEY header
on a POST

Retries & delivery
guarantees #

  • You own retries. Prosperas does
    not retry you. On a 5xx or a network
    failure, retry the postback with exponential backoff
    (e.g. 1s, 2s, 4s, 8s…), up to a sensible ceiling.
  • Do not retry on 4xx. A
    400, 403, or 422 means the
    request is wrong — fix it and send a corrected request instead of
    hammering the same payload.
  • The endpoint is not idempotent. Each accepted
    postback records a new event. If you retry after a request that actually
    succeeded (but whose response you missed), you may create a duplicate
    event. Keep retries bounded and prefer retrying only on confirmed
    failures.
  • Every request is logged on our side (with your API
    key masked) for support and reconciliation.

Worked examples #

Happy path — approval (POST) #

curl -X POST "{BASE_URL}/client_app/webhook/lender/loan-status" \
  -H "Content-Type: application/json" \
  -H "X-API-KEY: <your-key>" \
  -d '{
    "click_id": "claro_7e1c2f1f-9b4d-4c1d-9f6c-2f3c1a2b4d5e",
    "event": "approval",
    "occurred_at": "2026-07-01T12:34:56Z",
    "data": { "provider": "your-brand" }
  }'

Response — 200 OK:

{ "ok": true, "lead_id": 12345, "status": "APPROVAL", "user_id": 6789 }

Disbursement with
consumer enrichment (POST) #

curl -X POST "{BASE_URL}/client_app/webhook/lender/loan-status" \
  -H "Content-Type: application/json" \
  -H "X-API-KEY: <your-key>" \
  -d '{
    "click_id": "7e1c2f1f-9b4d-4c1d-9f6c-2f3c1a2b4d5e",
    "event": "disbursement",
    "occurred_at": "2026-07-01T15:00:00Z",
    "data": {
      "provider": "your-brand",
      "client": { "fullName": "Ana Gomez", "idNumber": "1234567890" }
    }
  }'

Error — camelCase field
(422) #

# WRONG: "clickId" (camelCase) instead of "click_id"
curl -X POST "{BASE_URL}/client_app/webhook/lender/loan-status" \
  -H "Content-Type: application/json" \
  -H "X-API-KEY: <your-key>" \
  -d '{ "clickId": "7e1c2f1f-...", "event": "approval" }'
# → 422 Unprocessable Entity (field "click_id" is required)

Error — missing / wrong
credential (403) #

# No X-API-KEY header and IP not allowlisted → 403
curl -X POST "{BASE_URL}/client_app/webhook/lender/loan-status" \
  -H "Content-Type: application/json" \
  -d '{ "click_id": "7e1c2f1f-...", "event": "approval" }'
# → 403 Forbidden

Quick reference #

Endpoint POST {BASE_URL}/client_app/webhook/lender/loan-status
Auth header X-API-KEY: <your-key> (case-insensitive)
Required body fields click_id (snake_case), event
(lowercase)
Events application · approval ·
disbursement · rejected
Optional body fields occurred_at (ISO-8601), data,
data.client
Success 200 →
{ ok, lead_id, status, user_id }
Client errors 400 bad click_id · 403 auth/lead ·
404 session · 422 validation
Retry on 5xx / network only, exponential backoff
Signing None (no HMAC) — protect the API key

Important notes #

Casing: top-level fields are snake_case (click_id, occurred_at). The nested data.client object uses camelCase (fullName, idNumber, returningCustomer) — this is intentional, not a bug.

Response: you send event lowercase (approval); the response returns status in UPPERCASE (APPROVAL). This is expected.

Idempotency & retries: the endpoint is not idempotent and Prosperas does not retry you. If a timeout leaves you without a response after we recorded the event, a retry creates a duplicate event. Recommendation: retry only on 5xx or network errors, with exponential backoff (1s, 2s, 4s…, max 3 attempts), and dedupe on your side by click_id + event + occurred_at. (Note: your decision/submission API in the Embedded Flow MUST be idempotent by tracking ID — that direction we do retry.)


Last verified: 2026-07-01 · v1.1 · matches
Lender-Postback-Integration-Guide.md

Updated on July 1, 2026
lang-en

What are your Feelings

  • Happy
  • Normal
  • Sad

Share This Article :

  • Facebook
  • X
  • LinkedIn
  • Pinterest
Sistema de postbackSistema de postback
Table of Contents
  • Overview
  • Authentication
    • API key (recommended)
    • IP allowlist (alternative)
    • The "a lead must exist" rule
  • The tracking id (click_id)
  • Request contract
    • Field reference
    • The data.client object (optional)
  • Events & lifecycle
  • Responses & status codes
  • Common mistakes (read this before you build)
  • Retries & delivery guarantees
  • Worked examples
    • Happy path — approval (POST)
    • Disbursement with consumer enrichment (POST)
    • Error — camelCase field (422)
    • Error — missing / wrong credential (403)
  • Quick reference
  • Important notes
Prosperas

El Mayor Marketplace de Crédito

  • Plataforma
  • Quiénes Somos
  • Soporte
  • Política de Privacidad
    • Política de Privacidad – Colombia
    • Política de Privacidad – Mexico
  • SLAs
  • Blog
  • Contacto
  • Términos & Condiciones
    • Términos y Condiciones – Colombia
    • Términos y Condiciones – México

C60s Inc.- 2022 Todos los derechos reservados