Skip to main content

Step 1: Configure Your Environment

Get your API key

Sign up at www.kanall-app.online. After email verification your API key is shown once — copy it.

Prefer the API? Register programmatically:

curl -X POST https://kanall.onrender.com/register \
-H "Content-Type: application/json" \
-d '{
"name": "StarLine Gas",
"email": "ops@starlinegas.ng",
"password": "your-secure-password"
}'

Then verify the OTP sent to your email:

curl -X POST https://kanall.onrender.com/auth/verify-email \
-H "Content-Type: application/json" \
-d '{
"tenantId": "550e8400-e29b-41d4-a716-446655440000",
"otp": "847291"
}'

Response:

{
"apiKey": "ten_sk_4a3b2c1d...",
"warning": "Store this API key securely — it will not be shown again."
}

:::danger Copy your API key now Kanall stores only a one-way hash. Once this response is closed, the raw key is gone. Rotate it from the dashboard at any time — but you cannot retrieve it. :::


Configure your environment

Add the API key to your backend's environment — never in source code.

# .env
KANALL_API_KEY=ten_sk_4a3b2c1d...
KANALL_BASE_URL=https://kanall.onrender.com

Create a Kanall API client

A thin wrapper around HTTP so you never repeat auth headers across your integration. Copy the version that matches your stack:

// kanall.js
const BASE_URL = process.env.KANALL_BASE_URL || 'https://kanall.onrender.com'
const API_KEY = process.env.KANALL_API_KEY

async function kanall(method, path, body) {
const res = await fetch(`${BASE_URL}${path}`, {
method,
headers: {
'X-API-Key': API_KEY,
...(body ? { 'Content-Type': 'application/json' } : {}),
},
body: body ? JSON.stringify(body) : undefined,
})

const data = await res.json()

if (!res.ok) {
throw new Error(data.error ?? `Kanall error ${res.status}`)
}

return data
}

module.exports = { kanall }

Set your webhook URL

Tell Kanall where to send payment notifications. Do this once — every virtual account you provision will deliver to this endpoint automatically.

const { kanall } = require('./kanall')

await kanall('POST', '/auth/webhook-url', {
url: 'https://app.starlinegas.ng/webhooks/kanall',
})

For local development, put your ngrok tunnel URL here and update it whenever the tunnel changes. Individual accounts can override this URL with their own callbackUrl — useful when testing a single account locally while production accounts remain on the main endpoint.


Verify your setup

const { kanall } = require('./kanall')

const result = await kanall('GET', '/v1/accounts')

Response:

{ "accounts": [], "pagination": { "hasMore": false } }

An empty accounts list means your key is valid and you are ready for the next step.


Next: Provision distributor accounts →