What it is and when to use it
A consent link is a URL you create for a subject (a person or a company identified by their document) so the holder can authorize read access to their banking data through a secure connection flow. Once the holder grants it, CBPay derives positive facts (accounts, balances, income and expense activity over the last 90 days) and feeds them to the subject’s credit file — the Qscore reflects them on the next report. Use it when the subject has little or no credit history and their banking activity is the strongest evidence of their real payment capacity — for example a tenant with no bureau record, or a supplier asking for better commercial terms.- You create the link (optionally emailed to the holder, with your organization’s branding).
- The holder opens it, sees your brand and the declared purpose, connects their bank through the secure widget and confirms — or declines.
- CBPay validates that the bank-verified document matches the subject’s
doc_idexactly (an account owned by a different document can never grant the consent), derives the facts and notifies you by webhook.
How the flow works
The link is a capability URL: the 128-bit token in it is the authorization to view and decide. It works without any login, shows only your brand, the purpose and the holder’s masked document (last 4 characters), and expires after a TTL you choose (7 days by default, 30 maximum).Step by step
1
Create the consent link
POST /v1/qscore/consents — requires the risk service flag and a verified account. The idempotency_key is mandatory: creating sends an email when email is provided, and a retry with the same key returns the original consent with idempotency_hit: true instead of creating a duplicate.Request
Response 201
country— ISO alpha-2, required. Coverage today:CL.doc_id— required, validated with the country’s check digit (Chilean RUT, e.g.11111111-1).subject_type—personorcompany; inferred from the document if omitted.purpose— required:credit_evaluation,tenant_screening,hiring,supplier_onboardingorother. Data protection law requires declaring it.self_accessis rejected here — your own report goes throughPOST /v1/qscore/my-report.email— optional; if present, the holder receives the link in a branded email from your organization.expires_in_days— optional; default 7, maximum 30.
consent_url with the holder (or let the email deliver it).2
The holder opens the link
The public page first loads The public view never exposes the holder’s email, full document, internal IDs or the token itself.
GET /platform/consent/{token} (no authentication) to show your brand, the declared purpose and the masked document:Response 200
3
The holder connects their bank
Choosing Authorize calls The page mounts the banking widget with those credentials; the holder authenticates with their bank and authorizes the connection. The widget returns an
POST /platform/consent/{token}/begin, which opens a secure bank-connection session:Response 200
exchange_token to the page.4
The consent is granted
The page sends Before sealing the grant, CBPay verifies two things and rejects otherwise:
POST /platform/consent/{token}/complete with the exchange_token:Request
Response 200
- the banking connection is
active— otherwise409 link_inactive; - the document verified by the bank matches the subject’s
doc_idexactly (both normalized) — otherwise409 holder_mismatch.
risk_consent_granted webhook.5
Track the consent
Response 200
GET /v1/qscore/consents/{id} returns a single consent (another account’s consent answers 404 not_found). A pending link past its expires_at flips to expired the next time it is read.6
Revoke if needed
POST /v1/qscore/consents/{id}/revoke cancels a consent (for example when the operation fell through). A consent that was already granted, revoked or expired answers 409 already_decided. Revoking emits the risk_consent_revoked webhook.Response 200
States
A consent is decided exactly once: every terminal state rejects further transitions with
409 already_decided.
Errors
Public (holder) endpoints share an IP throttle with the verification surfaces: 30 requests per minute per IP — a429 rate_limited response means slow down. A nonexistent or malformed token always answers a generic 404 not_found (anti-enumeration).
See the error catalog for the full list.
Webhooks
Subscribe to these events to get notified when the holder decides:doc_id travels full in the webhook (it is your own account’s data), so you can reconcile against the subject you created the link for.
How it feeds the Qscore
Granting a consent triggers a background derivation: CBPay reads the link’s accounts and activity (last 90 days), aggregates positive facts — accounts count, available and current balances, income and expense totals — and persists them to the subject’s credit file. Raw movements are never stored nor exposed (data minimization). Every Qscore report generated afterwards re-derives the subject’sgranted consents, so the positive data is fresh in each report. No extra call is needed on your side.
FAQ
Does the holder need a CBPay account?
Does the holder need a CBPay account?
No. The link is fully public and works without login — the 128-bit token in the URL is the authorization. The holder only sees your brand, the purpose and their masked document.
What if the holder connects an account owned by someone else?
What if the holder connects an account owned by someone else?
The grant is rejected with
409 holder_mismatch: the document verified by the bank must match the subject’s doc_id exactly. An account owned by a different document can never grant the consent — this is the identity proof of the flow.Can I revoke a consent after it was granted?
Can I revoke a consent after it was granted?
A granted consent is a terminal state and rejects transitions (
409 already_decided). To stop using the data, stop generating reports for the subject; the banking connection itself is managed by the holder at their bank.How long does the link live?
How long does the link live?
7 days by default, configurable with
expires_in_days up to 30. An expired link flips to expired and can no longer be used — create a new one.Is the email mandatory?
Is the email mandatory?
No. Without
email you get the consent_url in the response and share it yourself (WhatsApp, SMS, your own email). With email, CBPay sends a branded email on your behalf. Either way the create call needs an idempotency_key.Which countries are covered?
Which countries are covered?
Coverage today: Chile (
CL). More corridors are added as banking aggregation becomes available in each country — creating a link for an uncovered country fails at connect time with 502 provider_error.What data exactly is derived?
What data exactly is derived?
Aggregated facts only: number of accounts, available/current balance totals, currency, institutions, first observation date, and income/expense/movement totals over 90 days. Individual transactions are never stored nor exposed.