Getting started

Quickstart

Take a UK limited company from a cold start to a funded business loan in five calls: mint an OAuth token, create an application, submit it for AI decisioning, read the outcome, then wire webhooks — all against the sandbox, with no real money moved.

This walkthrough uses the partner/v1 ring, where server-to-server integrations live. Everything below runs against https://sandbox.credicorp.co.uk; switch the base URL to https://api.credicorp.co.uk when you go live. You should be able to complete the whole flow in about ten minutes. If you prefer a typed client, the PHP, Node.js and Python SDKs wrap every call shown here.

Sandbox is deterministic. The same test company number and amount always produce the same decision, so you can script every branch — approve, refer, decline — before launch. See Sandbox & test data for the full matrix.

Before you start

You need a sandbox project, which gives you a client_id and client_secret. Request one from the developer team — sandbox approval is automatic. Keep the secret server-side; it is never safe in a browser or mobile binary.

Base URL
https://sandbox.credicorp.co.uk
Token URL
https://sandbox.credicorp.co.uk/oauth/token
Ring
partner/v1 (server-to-server)
Content type
application/json on every request body

Export your credentials so the snippets below run verbatim:

bash
export CC_CLIENT_ID="cid_sbx_3Nf9…"
export CC_CLIENT_SECRET="csk_sbx_a71c…"
export CC_BASE="https://sandbox.credicorp.co.uk"

1. Get an access token

Exchange your client credentials for a short-lived bearer token using the OAuth 2.0 client-credentials grant. Request only the scopes this flow needs.

POST/oauth/token
bash
curl -s "$CC_BASE/oauth/token" \
  -d "grant_type=client_credentials" \
  -d "client_id=$CC_CLIENT_ID" \
  -d "client_secret=$CC_CLIENT_SECRET" \
  -d "scope=applications:write decisions:read payments:write"
javascript
import Credicorp from "@credicorp/sdk";

const cc = new Credicorp({
  clientId: process.env.CC_CLIENT_ID,
  clientSecret: process.env.CC_CLIENT_SECRET,
  environment: "sandbox",
});
// The SDK mints, caches and refreshes tokens for you.
php
use Credicorp\Client;

$cc = new Client([
  'client_id'     => getenv('CC_CLIENT_ID'),
  'client_secret' => getenv('CC_CLIENT_SECRET'),
  'environment'   => 'sandbox',
]);

Response 200 OK

json
{
  "access_token": "eyJhbGciOiJFUzI1NiIsImtpZCI6…",
  "token_type": "Bearer",
  "expires_in": 3600,
  "scope": "applications:write decisions:read payments:write"
}

Save the token and reuse it until roughly sixty seconds before expires_in elapses. Minting a token per request quickly hits rate limits. Pass it as Authorization: Bearer <token> on everything that follows — the snippets assume it is exported as $TOKEN.

2. Create an application

An application is the unit of lending. You create one for a UK incorporated borrower identified by its Companies House number, then either hand the applicant to our hosted journey via handoff_url or drive a white-label flow yourself. Always send an Idempotency-Key so a retried POST never creates a duplicate — see Idempotency.

POST/partner/v1/applications
bash
curl -s "$CC_BASE/partner/v1/applications" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Idempotency-Key: qs-001" \
  -H "Content-Type: application/json" \
  -d '{
    "business": { "company_number": "00000401" },
    "amount_pence": 2500000,
    "term_months": 12,
    "purpose": "working_capital",
    "redirect_uri": "https://yourapp.example/return",
    "reference": "PO-4471"
  }'
javascript
const app = await cc.applications.create({
  business: { companyNumber: "00000401" },
  amountPence: 2_500_000,
  termMonths: 12,
  purpose: "working_capital",
  reference: "PO-4471",
}, { idempotencyKey: "qs-001" });

console.log(app.id, app.status); // app_8Kd2c9Qm created
python
app = cc.applications.create(
    business={"company_number": "00000401"},
    amount_pence=2_500_000,
    term_months=12,
    purpose="working_capital",
    reference="PO-4471",
    idempotency_key="qs-001",
)
print(app.id, app.status)  # app_8Kd2c9Qm created

Key body parameters

FieldTypeDescription
business.company_numberstringreqCompanies House number of the borrowing entity. In sandbox, use a test number.
amount_penceintegerreqRequested principal in pence. Minimum £1,000 (100000).
term_monthsintegerreqRequested term, 3–60 months.
purposestringoptOne of working_capital, asset, expansion, refinance.
referencestringoptYour own reference, echoed back on every object and webhook.

Response 201 Created

json
{
  "id": "app_8Kd2c9Qm",
  "object": "application",
  "status": "created",
  "amount_pence": 2500000,
  "term_months": 12,
  "reference": "PO-4471",
  "handoff_url": "https://apply.credicorp.co.uk/s/3fa7…",
  "created_at": "2026-06-29T10:00:00Z"
}

Redirect the applicant to handoff_url to capture identity, open-banking permissions and the principals' details. When they finish, the application transitions to submitted and decisioning begins automatically.

3. Read the decision

Credicorp's AI decision is authoritative: a completed decision is the platform's answer, not an advisory score for a human to re-key. Once the engine has run, fetch the outcome from the Decisioning API.

GET/partner/v1/applications/{id}/decision
bash
curl -s "$CC_BASE/partner/v1/applications/app_8Kd2c9Qm/decision" \
  -H "Authorization: Bearer $TOKEN"

Response 200 OK

json
{
  "id": "dec_5Qm2Kd9c",
  "object": "decision",
  "application": "app_8Kd2c9Qm",
  "outcome": "approved",
  "offer": {
    "amount_pence": 2500000,
    "term_months": 12,
    "apr_bps": 1490,
    "repayment_pence": 225417
  },
  "reasons": ["affordability_pass", "identity_verified"],
  "decided_at": "2026-06-29T10:01:12Z"
}
OutcomeWhat it means
approvedAn offer is attached. Present it; on acceptance the loan funds.
referredManual underwriting needed. Wait for a follow-up decision.completed.
declinedNot approved; reasons explains why. Surface them honestly.

Force any outcome in sandbox. The requested amount_pence drives the result: ask for £25,000 to approve, and the magic decline and refer amounts to test the other branches. Full list under Magic amounts.

4. Wire up webhooks

Decisioning, funding and repayment are asynchronous, so never poll in a tight loop — subscribe to webhooks and react to events. Register an HTTPS endpoint and the event types you care about.

POST/partner/v1/webhook_endpoints
bash
curl -s "$CC_BASE/partner/v1/webhook_endpoints" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://yourapp.example/hooks/credicorp",
    "events": [
      "application.submitted",
      "decision.completed",
      "application.funded",
      "payment.succeeded"
    ]
  }'

Each delivery is signed. Verify the Credicorp-Signature header against your endpoint's signing secret before trusting the body, and reject anything that fails. A delivered event looks like this:

json
{
  "id": "evt_9c2Kd5Qm",
  "type": "decision.completed",
  "created": "2026-06-29T10:01:12Z",
  "data": {
    "application": "app_8Kd2c9Qm",
    "outcome": "approved"
  }
}

Return a 2xx within ten seconds to acknowledge. Anything else is retried with exponential back-off, so make your handler idempotent — dedupe on the event id. While building, you can replay any past event from the dashboard or the API. The full event catalogue and the signature scheme are in the Webhooks reference.

Next steps

That is the whole spine: token → application → decision → webhook. From here:

  • Collect repayments. Funded loans repay over open banking via PISP. See the Payments API for variable recurring payments and one-off collections.
  • Understand the model. Core concepts covers rings, the object graph, ID prefixes and the full application lifecycle.
  • Cover every branch. Work through Sandbox & test data so approve, refer and decline are all tested before launch.
  • Harden auth. Read OAuth 2.0 and request signing before requesting live credentials.

When you are ready, swap sandbox.credicorp.co.uk for api.credicorp.co.uk, point at your live client_id, and request production access from [email protected]. No code changes beyond the base URL and credentials are required.