Authentication

API keys

API keys identify your project to the Credicorp platform. Each key carries a prefix that tells you — and any scanner — exactly what it is, what environment it belongs to, and whether it's safe to expose.

Roadmap — not yet available. Named API keys are on the roadmap; today authentication uses OAuth 2.0 client credentials only. Documentation is provided so you can design against the planned shape. Build against the live token + MCP surface today; availability will be announced on the changelog.

Keys vs. OAuth. Secret keys are the credential you exchange for an OAuth bearer token — they pair with your client_id at the token endpoint. Publishable keys and webhook secrets serve narrower jobs described below. The API itself is always called with a bearer token, never with a raw key.

Key prefixes

Every Credicorp key is prefixed so its purpose and environment are unmistakable on sight. Treat the prefix as authoritative: a sk_live key moves real money; a sk_sandbox key never can.

PrefixKeyEnvironmentExposure
sk_live_Secret keyProductionsecret Server-side only
sk_sandbox_Secret keySandboxsecret Server-side only
pk_live_Publishable keyProductionpublic Safe in browsers
pk_sandbox_Publishable keySandboxpublic Safe in browsers
whsec_Webhook signing secretPer endpointsecret Server-side only

Secret keys — sk_live / sk_sandbox

The full-power credential. A secret key plus your client_id mints OAuth tokens that can create applications, pull decisions and instruct payments. It must never appear in front-end code, a mobile binary, a public Git repo, a log line or a webhook payload. If a secret key is exposed, treat it as compromised and rotate it.

bash
# sk_* is the client_secret in the OAuth exchange
curl -s https://hub.credicorp.co.uk/oauth/token \
  -d "grant_type=client_credentials" \
  -d "client_id=$CC_CLIENT_ID" \
  -d "client_secret=sk_live_8Kd2c9QmReHv…" \
  -d "scope=applications:write decisions:read"

Publishable keys — pk_live / pk_sandbox

Safe to embed in a browser or mobile app. A publishable key can only do front-end-safe things: initialise the hosted apply widget, tokenise an applicant's details before they reach your server, and start a PISP bank-selection screen. It cannot read applications, pull decisions or move money. There is nothing to protect — exposure is expected.

html
<script src="https://js.credicorp.co.uk/v1/apply.js"></script>
<script>
  const apply = Credicorp.apply("pk_live_3fa7Qe9mZ…");
  apply.mount("#apply-widget", { amountPence: 2500000, termMonths: 12 });
</script>

Webhook signing secrets — whsec

Issued per endpoint when you register a webhook. Credicorp signs every delivery with this secret so you can prove the payload came from us and wasn't tampered with. It is a verification secret, not a credential — it can't call the API. Keep it server-side and feed it to your signature check. Full verification recipe in Request signing roadmap.

json
# Register an endpoint → the response includes its whsec
{
  "id": "whk_5Tg1aB",
  "url": "https://yourapp.com/webhooks/credicorp",
  "events": ["decision.completed", "payment.settled"],
  "secret": "whsec_9mQ2…",
  "status": "active"
}

Environment binding

A key is welded to one environment for its whole life. There is no flag, header or parameter that crosses a sandbox key into production — the prefix is the boundary, and the API enforces it.

EnvironmentBase URLKeysEffect
Sandboxhub.credicorp.co.uk/partner/v1sk_sandbox / pk_sandboxSimulated decisions & payments. No real money, no real applicants.
Productionhub.credicorp.co.uk/partner/v1sk_live / pk_liveReal applications, AI decisioning and PISP disbursement.

Mixing environments is the #1 support ticket. A sk_sandbox key against a production application returns 401 environment_mismatch — the request is rejected, never silently downgraded. Key the right credential off your own NODE_ENV / APP_ENV so the two can't be swapped by accident.

Secure storage

Secret keys (sk_*, whsec_*) are bearer credentials: whoever holds one can act as your project. Store them accordingly.

  • Inject from a secrets manager — AWS Secrets Manager, GCP Secret Manager, HashiCorp Vault, Doppler — at deploy time. Read them as environment variables; don't bake them into images.
  • Never commit keys to source control. Add .env to .gitignore and ship a .env.example with placeholders. Credicorp keys are detected by GitHub secret scanning — a pushed live key is auto-reported to us and quarantined.
  • Never log a full key. If you must log for support, log only the prefix and last four (sk_live_…Hv9k).
  • Scope by service. Give each service its own project and key so you can rotate one without redeploying the world.
  • Don't put secret keys in a browser, mobile app, CLI distributed to users, or front-end build. Anything a user can decompile is public — use a pk_* key there.
bash
# .env  (git-ignored)
CC_CLIENT_ID=cc_client_8Kd2c9Qm
CC_SECRET_KEY=sk_live_8Kd2c9QmReHv…
CC_WEBHOOK_SECRET=whsec_9mQ2…

# .gitignore
.env
.env.*.local

Managing keys

Create, list and revoke keys from the developer dashboard, or programmatically with a token carrying partner:manage.

MethodEndpointPurpose
GET/partner/v1/keysList keys with their prefix, last-four and last-used time. Full secret is never returned again.
POST/partner/v1/keysCreate a new key. The full secret is shown once in the response.
POST/partner/v1/keys/{id}/rollBegin a rotation: issue a successor with an overlap window.
DELETE/partner/v1/keys/{id}Revoke a key immediately. Cannot be undone.

The full secret is displayed exactly once, at creation. We store only a hash — we can't show it to you again and neither can support. If you lose it, roll the key.

Zero-downtime rotation

Rolling a secret key issues a successor and opens an overlap window during which both keys authenticate. You move traffic, confirm, then retire the predecessor — no maintenance window, no failed requests.

bash
curl -s -X POST https://hub.credicorp.co.uk/partner/v1/keys/key_7Hn3/roll \
  -H "Authorization: Bearer $TOKEN" \
  -d '{ "overlap_hours": 48 }'

# → 201 Created — new secret shown once
{
  "id": "key_9Lp4",
  "secret": "sk_live_NewSecretShownOnce…",
  "predecessor": "key_7Hn3",
  "predecessor_expires_at": "2026-07-01T09:00:00Z"
}
  1. Roll — capture the new sk_live from the response (shown once).
  2. Deploy the new key to your secrets manager and roll your fleet. The predecessor still works.
  3. Verify the dashboard shows the new key in use and the predecessor idle.
  4. Retire — let the predecessor lapse at predecessor_expires_at, or DELETE it early.

Revocation

Revocation is instant and irreversible. The moment a key is revoked, every new token request with it fails 401 key_revoked. Tokens already minted under that key remain valid until they expire (≤ 1 hour) — if you need to kill those too, revoke the outstanding tokens from the OAuth dashboard.

Leaked a key? Revoke first, ask questions later. Don't wait for an orderly roll — a live secret key in the wrong hands can move money. Revoke it, issue a fresh one, redeploy, then audit how it escaped. Webhook secrets (whsec_) are rotated the same way from the endpoint's settings.


Next: verify that the webhook deliveries Credicorp signs with your whsec are genuine and untampered — see Request signing roadmap.