Integrate lending
Embed UK business lending into your product end-to-end: create an application, hand off to underwriting (hosted or white-label), react to the decision, then fund and collect — all driven by webhooks, never polling.
This guide stitches the Apply, Decisioning, Accounts and Payments APIs into one working flow. Everything below runs against the sandbox first — swap your test token for a live one to ship. You will need a partner OAuth client with the applications:write, payments:write and webhooks:read scopes; see OAuth 2.0 for the client-credentials grant.
Credicorp lends only to UK incorporated bodies corporate — limited companies and LLPs. You always create an application against a Companies House number, never against an individual consumer.
The lifecycle at a glance
An application moves through a fixed set of states. Your integration reacts to three of the transitions; the rest are informational.
| Step | State | What you do |
|---|---|---|
| 1. Create | created | POST an application, receive a handoff_url. |
| 2. Handoff | created → submitted | Send the applicant to the hosted journey, or drive white-label. |
| 3. Decision | in_review → approved/declined | Handle decision.completed. |
| 4. Fund | approved → funded | Handle application.funded; an account now exists. |
| 5. Collect | account lifecycle | Schedule repayments, reconcile payment.*. |
1 · Create an application
Send the borrowing entity's company_number, the requested principal in pence, and a term. Always attach an Idempotency-Key so a network retry never opens two applications — see Idempotency. Pass your own reference and it is echoed back on every object and webhook, which makes reconciliation trivial.
Key parameters
| Field | Type | Description | |
|---|---|---|---|
business.company_number | string | req | Companies House number of the borrower. |
amount_pence | integer | req | Requested principal in pence. Min £1,000. |
term_months | integer | req | 3–60 months. |
purpose | string | opt | working_capital, asset, expansion, refinance. |
redirect_uri | string | opt | Where to return the applicant after the hosted flow. |
reference | string | opt | Your reference, echoed on every object & event. |
curl -s https://api.credicorp.co.uk/partner/v1/applications \ -H "Authorization: Bearer $TOKEN" \ -H "Idempotency-Key: $(uuidgen)" \ -d '{ "business": { "company_number": "16093826" }, "amount_pence": 2500000, "term_months": 12, "purpose": "working_capital", "redirect_uri": "https://yourapp.com/return", "reference": "ord_5512" }'
import { Credicorp } from '@credicorp/sdk'; const cc = new Credicorp({ token: process.env.CREDICORP_TOKEN }); const app = await cc.applications.create({ business: { company_number: '16093826' }, amount_pence: 2500000, term_months: 12, purpose: 'working_capital', redirect_uri: 'https://yourapp.com/return', reference: 'ord_5512', }, { idempotencyKey: crypto.randomUUID() }); console.log(app.handoff_url);
use Credicorp\Client; $cc = new Client(getenv('CREDICORP_TOKEN')); $app = $cc->applications->create([ 'business' => ['company_number' => '16093826'], 'amount_pence' => 2500000, 'term_months' => 12, 'purpose' => 'working_capital', 'redirect_uri' => 'https://yourapp.com/return', 'reference' => 'ord_5512', ], idempotencyKey: $ref); echo $app->handoff_url;
Response 201 Created
{
"id": "app_8Kd2c9Qm",
"object": "application",
"status": "created",
"amount_pence": 2500000,
"term_months": 12,
"reference": "ord_5512",
"handoff_url": "https://apply.credicorp.co.uk/s/3fa7…",
"created_at": "2026-06-29T10:00:00Z"
}2 · Hand off to underwriting
You have two ways to take the applicant the rest of the way. Pick one per integration; most partners start hosted and graduate to white-label once they need brand control.
Hosted journey
Redirect the applicant to the handoff_url. Credicorp collects identity, open-banking accounts and director confirmation, runs decisioning, and returns the user to your redirect_uri with the application id appended. This is the fastest path to live: identity, AML and consent are all handled for you, and the screens inherit a neutral skin you can theme with your logo and accent colour in the dashboard.
The hosted journey is the only path that requires no PII to touch your servers. If reducing your compliance scope matters, start here.
White-label flow
Drive the journey from your own UI and call the APIs directly. You collect the inputs, submit identity through the Identity API, attach open-banking data, then move the application to submitted. You own every pixel; in return you take on the identity, consent and accessibility obligations. The decisioning, pricing and funding mechanics are identical — only who renders the screens changes.
| Hosted | White-label | |
|---|---|---|
| Time to live | Hours | Days–weeks |
| Brand control | Logo & accent | Full |
| Identity / AML | Credicorp handles | You orchestrate via Identity API |
| PII on your servers | None | Yours to secure |
3 · React to the decision
Decisioning is AI-led and authoritative — it returns an outcome, indicative pricing and machine-readable reasons in seconds. Do not poll in a tight loop. Subscribe to the decision.completed event and let it push the result to you the instant the engine resolves. The event body mirrors the decision object.
{
"id": "evt_7Hn",
"type": "decision.completed",
"created": "2026-06-29T10:00:03Z",
"data": {
"application_id": "app_8Kd2c9Qm",
"outcome": "approved",
"amount_pence": 2500000,
"apr": 14.9,
"reasons": ["affordability_ok", "credit_ok"],
"reference": "ord_5512"
}
}Branch on outcome: approved means an offer is available at the returned amount_pence / apr; referred means a human underwriter will resolve it to approved/declined later (you will get a second event); declined carries reasons you can surface or suppress. Always verify the signature before trusting the body — recompute the HMAC from the Credicorp-Signature header per Request signing.
4 · Fund and collect
On an approved application, disbursement is the platform's job; you simply wait for application.funded, at which point an account exists. To take repayments, create a recurring collection schedule against the account's mandate over PISP rails — bank-to-bank, no card networks.
curl -s https://api.credicorp.co.uk/partner/v1/payments/schedules \ -H "Authorization: Bearer $TOKEN" \ -H "Idempotency-Key: sch-ord_5512" \ -d '{ "account_id": "acc_2Wd", "amount_pence": 220833, "cadence": "monthly", "start_date": "2026-07-29", "count": 12 }'
await cc.payments.schedules.create({ account_id: 'acc_2Wd', amount_pence: 220833, cadence: 'monthly', start_date: '2026-07-29', count: 12, }, { idempotencyKey: 'sch-ord_5512' });
From here, reconciliation is event-driven. Subscribe to payment.paid, payment.failed and payment.refunded; each carries the account_id and your reference so you can match it to your ledger in one lookup. Watch account.in_arrears to drive your own dunning, and read live balances any time from GET /partner/v1/accounts/{id}.
Acknowledge every webhook with a 2xx within 10 seconds, then do the slow work afterwards. Blocking the response risks a retry storm. Handlers must be idempotent, keyed on event.id — deliveries can arrive more than once.
Go-live checklist
| Item | |
|---|---|
| ✓ | Live OAuth client provisioned with least-privilege scopes; secrets stored server-side only. |
| ✓ | Webhook endpoint registered over HTTPS; Credicorp-Signature verified in constant time. |
| ✓ | Every POST sends a stable Idempotency-Key held across the whole retry loop. |
| ✓ | Handlers for decision.completed, application.funded and payment.* are idempotent. |
| ✓ | Declines surfaced or suppressed per your policy; referred handled as a non-final state. |
| ✓ | Tested end-to-end in the sandbox before flipping the token to live. |
Reselling rather than embedding? See Distribute Credicorp for tracked introductions and revenue share.
