> For the complete documentation index, see [llms.txt](https://docs-sdk.crypto-chief.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs-sdk.crypto-chief.com/processing/kotlin/authentication.md).

# Authentication

How the Crypto Chief Kotlin SDK authenticates and signs every request.

Every request to the Crypto Processing API is authenticated with two HTTP headers. **The SDK builds and sets them for you** — you only provide your Merchant ID and API key.

```
Merchant:  <your Merchant ID>
Signature: hex(md5(base64(canonicalJSON(body)) + API_KEY))
```

## Credentials

Both values come from your dashboard → **Integration** tab:

* **Merchant ID** — identifies your project.
* **API key** — the **signing secret**. It never leaves your server; the SDK uses it to compute the `Signature` and to verify incoming webhooks.

{% hint style="warning" %}
Treat the API key like a password. Load it from an environment variable and keep it server-side — never commit it or ship it in client apps.
{% endhint %}

## Initialize the client

```kotlin
val client = CryptoChiefClient.create {
    merchantId = System.getenv("CRYPTO_CHIEF_MERCHANT_ID")
    apiKey     = System.getenv("CRYPTO_CHIEF_API_KEY")
}
```

`CryptoChiefClient` is safe to share across coroutines and implements `Closeable` — wrap calls with `client.use { ... }` or call `close()` when your service shuts down to release the OkHttp pool.

For Java callers, `create` is a static factory, and anything beyond the two credentials goes through the builder's setters:

```java
CryptoChiefClient client = CryptoChiefClient.create("MERCHANT_ID", "API_KEY");

// or, to configure more than the credentials:
Options.Builder builder = Options.builder();
builder.setMerchantId("MERCHANT_ID");
builder.setApiKey("API_KEY");
builder.setMaxRetries(3);

CryptoChiefClient configured = new CryptoChiefClient(builder.build());
```

## Configuration options

```kotlin
import java.time.Duration

val client = CryptoChiefClient.create {
    merchantId        = "MERCHANT_ID"
    apiKey            = "API_KEY"
    baseUrl           = "https://api-processing.crypto-chief.com"  // default
    requestTimeout    = Duration.ofSeconds(60)
    maxRetries        = 3                                          // retry 5xx + transport errors
    initialRetryDelay = Duration.ofMillis(200)
    maxRetryDelay     = Duration.ofSeconds(5)
    userAgent         = "my-service/1.0"
    rsaPrivateKey     = RsaKeyLoader.loadPrivateKeyFromFile("./rsa_private.pem") // optional
    httpClient        = mySharedOkHttp                             // optional — share connection pool
}
```

When you supply your own `httpClient`, the SDK never closes it — that's your responsibility.

{% hint style="info" %}
**Test mode** is a per-project toggle in the dashboard, not a separate base URL. Point a test-mode project's credentials at the same client.
{% endhint %}

## How signing works

The client serialises the body to canonical JSON (recursively sorted keys, compact, UTF-8), base64-encodes the bytes, appends your API key, and MD5-hashes the result to produce the `Signature`. The same scheme verifies [webhooks](/processing/kotlin/guides/webhooks.md), so one secret secures both directions.
