Start with
the truth: as a Lender, you embed nothing #
This is the number-one misunderstanding, so we’ll make it crystal
clear from the very first line: in the embedded flow, your
institution does NOT embed any Prosperas widget, SDK, or
iframe. It’s the other way around.
Prosperas hosts the entire Consumer experience and calls YOUR
API. The Consumer browses your institution’s offers, fills in
their information, and picks an offer — all inside the Prosperas
interface, never leaving it. Only at the very end — once the application
has been submitted and accepted for processing — does Prosperas redirect
the Consumer to your portal to sign or close the deal.
Put another way: you don’t build or maintain an origination UI for
the Consumer. You expose two real-time API capabilities; we own the
experience end to end.
Production reference: the Origin
Wasti operates under exactly this model today. If you
want a real case to validate your integration against, that’s the
one.
Who builds what (at a glance) #
| Responsibility | Who owns it |
|---|---|
| Consumer UI (browse offers, enter data, choose an offer) | Prosperas |
| Decision and submission API that Prosperas consumes | You (the Lender) |
| Final portal to sign/close (post-redirect) | You (the Lender) |
| Status postbacks back to Prosperas | You (the Lender) |
| Adapter that translates the Prosperas model to your API | Prosperas |
The
contract asymmetry (and why it works in your favor) #
Before we get into the capabilities, understand how technical
responsibilities are split — because the first direction is a direct
benefit to you:
-
Prosperas → Lender: we adapt to YOUR existing
API. We don’t ask you to implement a fixed Prosperas contract
or replicate another Lender’s contract (such as Wasti’s). Our
integration layer builds a per-Lender adapter: the
protocol, the authentication, the endpoints, and the field names are
yours. The exact field mapping is agreed during
onboarding. There is no rigid schema you have to conform to. -
Lender → Prosperas: here the contract is ours.
Status postbacks (approval, disbursement, rejection) follow a
Prosperas-defined format, and your institution adapts to it. Full
details are in the Postback System guide.
This asymmetry gives you the freedom to expose your decision and
submission API with your own design, while we keep consistency on the
notification side across every Lender in the marketplace.
The two required
capabilities #
Your integration comes down to two logical
capabilities — and note: not necessarily two single endpoints. You can
split each one into several calls (for example, a token step and a
separate document-validation step) or merge them into fewer calls, as
long as you honor the input/output below.
| # | Capability | What Prosperas sends you (input) | What you return to Prosperas (output) |
|---|---|---|---|
| 1 | Real-time credit decision (pre-approval) | Tracking ID + the Consumer’s identity and income | A decision (approved / rejected /pending) and, if approved, the available offer catalog |
| 2 | Application submission | Tracking ID (+ your system’s application reference, if applicable) + the Consumer’s complete data + the chosen offer |
A final status + a redirect URL to your portal |
Hard requirements that
cannot be skipped #
No matter how you split or merge calls, these two rules are
non-negotiable:
- The decision with offers must arrive
before the Consumer completes the rest of the
application. Prosperas needs to know which offers to display before it
keeps collecting data. - The redirect URL must arrive at the
end, once the application has been submitted. Without that URL
we can’t complete the hand-off of the Consumer to your portal.
If your decisioning process is asynchronous (manual review, external
validation), respond with a pending status and resolve it
later via polling or callback — but the “decision + offers first,
redirect last” rule still applies.
What the calls
look like (illustrative example) #
Illustrative example — the real format adapts to YOUR
API. The bodies below are only a mental model so you understand
what information travels in each direction. They are not a rigid
contract: the actual field names, structure, protocol, and
authentication are agreed during onboarding and mapped against your
existing API. Do not implement this literally.
Capability 1 —
Credit decision (pre-approval) #
Prosperas calls you with the Consumer’s identity and income:
// Prosperas → Lender (illustrative request)
{
"trackingId": "b3f1c2a4-5d6e-7f80-9a1b-2c3d4e5f6a7b",
"consumer": {
"documentType": "CC",
"documentNumber": "1234567890",
"fullName": "First Last",
"monthlyIncome": 3200000,
"currency": "COP"
}
}
You respond with the decision and, if you approve, the offer
catalog:
// Lender → Prosperas (illustrative response — approved case)
{
"trackingId": "b3f1c2a4-5d6e-7f80-9a1b-2c3d4e5f6a7b",
"decision": "approved", // approved | rejected | pending
"offers": [
{
"offerId": "OF-001",
"amount": 5000000,
"termMonths": 24,
"monthlyPayment": 265000,
"annualRate": 0.28
}
]
}
If you reject or the decision is pending, you send no offers:
// Lender → Prosperas (illustrative response — rejected)
{
"trackingId": "b3f1c2a4-5d6e-7f80-9a1b-2c3d4e5f6a7b",
"decision": "rejected",
"reason": "consumer_not_eligible" // business decision, NOT a technical failure
}
Capability 2 — Application
submission #
With the Consumer’s offer already chosen, Prosperas sends you the
complete data:
// Prosperas → Lender (illustrative request)
{
"trackingId": "b3f1c2a4-5d6e-7f80-9a1b-2c3d4e5f6a7b",
"lenderApplicationRef": "APP-99182", // optional: your reference, if applicable
"selectedOfferId": "OF-001",
"consumer": {
"documentType": "CC",
"documentNumber": "1234567890",
"fullName": "First Last",
"email": "consumer@example.com",
"phone": "+573001234567"
// ...rest of the complete form data
}
}
You respond with the final status and the redirect URL to the portal
where the Consumer signs:
// Lender → Prosperas (illustrative response)
{
"trackingId": "b3f1c2a4-5d6e-7f80-9a1b-2c3d4e5f6a7b",
"status": "submitted",
"redirectUrl": "https://portal.yourlender.com/sign?ref=APP-99182"
}
Again: the exact names (trackingId,
decision, offers, redirectUrl,
etc.) are illustrative. In your real integration we use
your field names.
The tracking ID: one
identifier, one journey #
Every application that goes through the embedded flow carries a
tracking ID (a UUID) that Prosperas generates when the
Consumer’s journey begins. It’s the internal reference for that session
and the backbone of end-to-end traceability:
- It travels as
trackingIdin every call Prosperas makes
to your API (pre-approval and submission). - It travels as
clickId/click_idin the
redirect URL of the final hand-off to your portal. - Your institution must echo it — exactly — in every
status postback you send back to Prosperas, so we connect each
notification to the correct journey.
One tracking ID = one journey. It carries no
personal data about the Consumer: it’s an opaque identifier meant
strictly for cross-system correlation. For the full lifecycle, see the
“tracking ID lifecycle” in the Overview, and for the
exact format in notifications, the Postback System.
What
we expect from your API (non-functional requirements) #
Because the Consumer waits live inside the Prosperas
flow, your decision and submission API must meet clear expectations
around latency and failure behavior:
- Latency target: p95 under 5 seconds per call.
- Prosperas timeouts: 15 to 30 seconds. If we don’t
get a response in time, we retry up to 3 times with
backoff. - Idempotency is mandatory, keyed by tracking ID:
precisely because we retry, your API must be idempotent by
tracking ID. Receiving the same call more than once must not
produce duplicate decisions or duplicate applications. Return the result
from the first time. - Distinguish a rejection from a technical failure:
your API must tell apart a Consumer rejection (a
business decision: didn’t qualify, didn’t meet risk policy) from a
technical failure (internal error, downstream service
timeout). This distinction is key so Prosperas knows when to retry and
when not to.
Watch out:
idempotency runs in opposite directions #
This is the point that trips up integrators the most, so pay
attention — the two directions behave the opposite way:
| Direction | Who retries | Is the receiver idempotent? | What’s on you |
|---|---|---|---|
| Prosperas → Lender (decision / submission) | Prosperas (up to 3 times) | Yes — YOUR API must be, by tracking ID | Deduplicate by tracking ID and return the same result on retries |
| Lender → Prosperas (postbacks) | You (Prosperas does NOT retry you) | No — the postback endpoint is not idempotent | You own your retries; keep them bounded and retry only on confirmed failures, because a retry over a postback that actually landed can create a duplicate event |
In short: when Prosperas calls you, guarding against
duplicates is your responsibility (idempotency by tracking ID). When you
call Prosperas with a postback, avoiding duplicates is also your
responsibility (bounded retries) — but for a different reason:
the postback endpoint records every accepted event and does not
deduplicate. Full details are in the Postback
System.
Next steps #
- Postback System — how to notify Prosperas of status
changes using the tracking ID (and why that direction is not
idempotent). - Product Data Requirements — what information we
need about your offers so they render correctly in the catalog the
Consumer sees.
Last verified: 2026-07-01 · v1.1
