Authentication & API keys
How your backend authenticates with Darkel: create an API key, send it with every request, and keep it safe.
The dashboard signs you in with your email or Google account. Your code authenticates differently — with an API key scoped to one workspace. This page covers creating, using, rotating and securing those keys.
One base URL, key-based environments
Every API request goes to the same host, whether you are testing or in production:
https://api.darkel.ngYou never switch URLs to change environment. Instead, the API key you send selects it:
| Key prefix | Acts on | Charges |
|---|---|---|
dk_test_… | Your sandbox workspace | Play money |
dk_live_… | Your live workspace | Real prepaid balance |
Going to production is a one-line change: replace the dk_test_ key in your config with a dk_live_ key. Nothing else moves.
Create an API key
Open Developers → API keys
In the dashboard, go to the Developers section and open API keys.
Create a key
Give it a clear name (e.g. “Checkout service” or “Staging worker”) so you can recognise it later, then create it.
Copy it into your secrets
The full key is shown once, on creation — copy it into your secrets manager or environment variable right away. We only store a one-way hash of it, so it can never be shown again; if you lose it, revoke that key and create a new one.
A key created in a sandbox workspace is automatically a dk_test_ key; one created in a live workspace is a dk_live_ key. The environment comes from the workspace you created it in.
Send the key with every request
Pass your key in the X-Api-Key header on every request.
curl https://api.darkel.ng/v1/whatsapp/messages \
-H "X-Api-Key: dk_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "to": "+2348012345678", "template": { "name": "hello_world" } }'The key identifies the workspace; you do not send any account ID. Requests run against the workspace that owns the key.
Examples in your language
The same send request in a few languages — switch tabs to copy the one you need.
const res = await fetch("https://api.darkel.ng/v1/whatsapp/messages", {
method: "POST",
headers: {
"X-Api-Key": process.env.DARKEL_API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({
to: "+2348012345678",
template: {
name: "order_confirmation",
languageCode: "en_US",
components: [
{ type: "body", parameters: [{ type: "text", text: "Ada" }] },
],
},
}),
});
const { data } = await res.json();
if (!res.ok) throw new Error("Send failed");
console.log("Queued:", data.id);Responses are wrapped in an envelope — { message, data, statusCode, success } — so the message record is under data. See API reference.
Rotate & revoke keys
Treat keys like passwords. Rotate them periodically and immediately if one might be exposed.
- Rotate — create a new key, deploy it, then revoke the old one. Because multiple keys can be active at once, you can do this with zero downtime.
- Revoke — disables a key immediately; any request using it starts failing with
401. - Delete — removes a revoked key from your list entirely.
- Each key shows when it was last used, so you can spot unused or rogue keys.
Never expose a key in client code
API keys send messages and spend your balance. Keep them on your server only — never in a browser, mobile app, or public repository. If a key leaks, revoke it right away and rotate.
Authentication errors
| Status | Meaning | Fix |
|---|---|---|
401 Unauthorized | Missing, malformed, revoked or wrong key | Check the X-Api-Key header and that the key is active |
403 Forbidden | Key is valid but WhatsApp is not enabled for the workspace | Enrol in WhatsApp under Billing |
400 Bad Request | The request body failed validation | Check the field names and formats against the API reference |