Authentication

How to authenticate API requests to Credo using your public and secret keys.

Every request to the Credo API must include an API key in the Authorization header. Credo uses two types of keys, each scoped to specific operations.

API keys

KeyPrefixUse forEnvironment
Public Key0PUB...Initializing transactions (client-safe)Sandbox or Production
Secret Key-Verifying transactions, sensitive operationsSandbox or Production

Get your keys from SettingsDeveloperAPI Keys in the sandbox dashboard or production dashboard.

Keep your secret key safe

Your secret key grants full access to verify and query transactions. Never expose it in frontend code, mobile apps, Git repositories, or client-side bundles. Store it in environment variables on your server.

Sending authenticated requests

Include your API key in the Authorization header of every request. There is no Bearer prefix - pass the key directly.

const response = await fetch("https://api.credodemo.com/transaction/initialize", {
  method: "POST",
  headers: {
    "Authorization": process.env.CREDO_PUBLIC_KEY,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    amount: 50000,
    email: "customer@example.com",
    currency: "NGN",
    bearer: 0,
    channels: ["CARD", "BANK"],
    initializeAccount: 0,
  }),
});
import requests

response = requests.post(
    "https://api.credodemo.com/transaction/initialize",
    headers={
        "Authorization": os.environ["CREDO_PUBLIC_KEY"],
        "Content-Type": "application/json",
    },
    json={
        "amount": 50000,
        "email": "customer@example.com",
        "currency": "NGN",
        "bearer": 0,
        "channels": ["CARD", "BANK"],
        "initializeAccount": 0,
    },
)
$ch = curl_init("https://api.credodemo.com/transaction/initialize");
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST => true,
    CURLOPT_HTTPHEADER => [
        "Authorization: " . getenv("CREDO_PUBLIC_KEY"),
        "Content-Type: application/json",
    ],
    CURLOPT_POSTFIELDS => json_encode([
        "amount" => 50000,
        "email" => "customer@example.com",
        "currency" => "NGN",
        "bearer" => 0,
        "channels" => ["CARD", "BANK"],
        "initializeAccount" => 0,
    ]),
]);
$response = curl_exec($ch);
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;

public class AuthenticationExample {
    public static void main(String[] args) throws Exception {
        String json = """
            {
                "amount": 50000,
                "email": "customer@example.com",
                "currency": "NGN",
                "bearer": 0,
                "channels": ["CARD", "BANK"],
                "initializeAccount": 0
            }
            """;

        HttpRequest request = HttpRequest.newBuilder()
            .uri(URI.create("https://api.credodemo.com/transaction/initialize"))
            .header("Authorization", System.getenv("CREDO_PUBLIC_KEY"))
            .header("Content-Type", "application/json")
            .POST(HttpRequest.BodyPublishers.ofString(json))
            .build();

        HttpClient client = HttpClient.newHttpClient();
        HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());

        System.out.println(response.body());
    }
}
using System.Text;
using System.Text.Json;

var payload = new
{
    amount = 50000,
    email = "customer@example.com",
    currency = "NGN",
    bearer = 0,
    channels = new[] { "CARD", "BANK" },
    initializeAccount = 0
};

var json = JsonSerializer.Serialize(payload);
var content = new StringContent(json, Encoding.UTF8, "application/json");

var client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", Environment.GetEnvironmentVariable("CREDO_PUBLIC_KEY"));

var response = await client.PostAsync("https://api.credodemo.com/transaction/initialize", content);
var result = await response.Content.ReadAsStringAsync();

Console.WriteLine(result);

Which key to use

OperationKey
Initialize a transactionPublic key
Verify a transactionSecret key
Direct card charge (initiate)Secret key
Direct card charge (authorize)Secret key
Webhook signature verificationSecret key

Transaction initialization uses the public key because it runs in contexts where the key may be visible (browser, mobile app). All other operations require the secret key and must happen server-side.

Sandbox vs production keys

Each environment has its own key pair. They are not interchangeable.

SandboxProduction
Dashboardapp.credodemo.comapp.credocentral.com
API base URLapi.credodemo.comapi.credocentral.com
Real chargesNoYes
Keys work cross-environmentNoNo

A common pattern is to use environment variables to switch between them:

const BASE_URL = process.env.NODE_ENV === "production"
  ? "https://api.credocentral.com"
  : "https://api.credodemo.com";

const API_KEY = process.env.NODE_ENV === "production"
  ? process.env.CREDO_LIVE_PUBLIC_KEY
  : process.env.CREDO_TEST_PUBLIC_KEY;

Authentication errors

If authentication fails, you'll receive one of these responses:

StatusMessageCause
401UnauthorizedMissing or invalid API key
403ForbiddenKey doesn't have permission for this operation (e.g., using public key to verify)

If you're getting 401 errors:

  1. Check that you're sending the key in the Authorization header (not a query parameter)
  2. Confirm you're using the right key for the right environment (sandbox key won't work on production)
  3. Verify the key hasn't been regenerated - regenerating invalidates the old key
  4. Make sure there's no extra whitespace or line breaks in the key

Regenerating keys

If your keys are compromised:

  1. Go to SettingsDeveloperAPI Keys
  2. Click Regenerate next to the compromised key
  3. Update your application with the new key immediately

Regenerating a key invalidates the previous one immediately. Any requests using the old key will fail with a 401 error. Plan for minimal downtime when rotating keys.

Next steps

Was this page helpful?

Last updated on

On this page