Get started
Authentication
Every request is authenticated with your secret key, sent as a Bearer token over HTTPS. This page covers the header, the two key types and the errors you get when something is wrong.
On this page
Bearer authentication
Send your secret key in the Authorization header with the Bearer scheme. There is no separate login call, session or token exchange: the key identifies your account on each request.
Authorization: Bearer kp_test_sk_4f9a2c7e1b8d4a6f9c3e5d7b- Requests must use HTTPS. Plain HTTP calls are not accepted.
- The key goes only in the header, never in the URL or the request body, so it does not end up in logs or browser history.
- Test keys only reach test data, the only kind that exists today. When live keys arrive, each key type will stay in its own environment.
curl https://api.krokopay.app/v1/charges/chg_4Fp9KzW1xQm7Rt \ -H "Authorization: Bearer $KROKOPAY_SECRET_KEY"Publishable and secret keys
Your account has two test keys. They are not interchangeable:
| Key | Prefix | Where it lives | What it can do |
|---|---|---|---|
| Secret | kp_test_sk_ | Your server only | Every endpoint in this documentation |
| Publishable | kp_test_pk_ | Safe to embed in a web page | Nothing yet: reserved for future client-side use |
Every documented endpoint requires the secret key. Payment details are collected by the hosted checkout, so your front end never needs a key to take a payment. The publishable key exists so a future client-side feature can ship without changing your key setup; which endpoints it will open is to be announced.
Warning: Never ship the secret key to a browser or app
Authentication errors
Authentication problems are reported with the usual error object. Do not retry them: the same request will fail the same way until the key is fixed.
| Status | type | code | Cause |
|---|---|---|---|
401 | authentication_error | missing_api_key | No Authorization header, or not in the Bearer <key> form. |
401 | authentication_error | invalid_api_key | The key is malformed, unknown, or was replaced by a roll. |
403 | permission_error | secret_key_required | A publishable key was used on an endpoint that needs the secret key. |
HTTP/1.1 401 UnauthorizedContent-Type: application/json{ "error": { "type": "authentication_error", "code": "missing_api_key", "message": "No API key provided. Send it as `Authorization: Bearer <secret key>`." }}HTTP/1.1 401 UnauthorizedContent-Type: application/json{ "error": { "type": "authentication_error", "code": "invalid_api_key", "message": "The API key provided is not valid." }}HTTP/1.1 403 ForbiddenContent-Type: application/json{ "error": { "type": "permission_error", "code": "secret_key_required", "message": "This endpoint requires a secret key (kp_test_sk_…). Publishable keys cannot call it." }}Good practices
- Read the key from an environment variable such as
KROKOPAY_SECRET_KEY, never from source code. - Use one place in your code to build the
Authorizationheader, so a roll means changing one variable. - Treat a
401in production code as an alert for your team, not as a user-facing error. - Never log full request headers. If you need to identify a key in logs, keep only its prefix.