Authentication and API keys
Every request to the Kalle API is signed with an API key. Keys belong to a workspace, and everything a key spends is billed to that workspace.
Sending your key
Put the key in the Authorization header as a bearer token. Requests without a valid key get a 401 response.
Authorization: Bearer kalle_sk_...This request lists the models your key can use. It is a quick way to check that a key works:
curl https://api.kalle.build/v1/models \
-H "Authorization: Bearer $KALLE_API_KEY"const response = await fetch("https://api.kalle.build/v1/models", {
headers: { Authorization: `Bearer ${process.env.KALLE_API_KEY}` },
});
console.log(await response.json());import os
import requests
response = requests.get(
"https://api.kalle.build/v1/models",
headers={"Authorization": f"Bearer {os.environ['KALLE_API_KEY']}"},
)
response.raise_for_status()
print(response.json())package main
import (
"fmt"
"io"
"net/http"
"os"
)
func main() {
req, _ := http.NewRequest("GET", "https://api.kalle.build/v1/models", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KALLE_API_KEY"))
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(string(out))
}require "json"
require "net/http"
uri = URI("https://api.kalle.build/v1/models")
request = Net::HTTP::Get.new(uri)
request["Authorization"] = "Bearer #{ENV.fetch("KALLE_API_KEY")}"
response = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(request) }
puts JSON.pretty_generate(JSON.parse(response.body))<?php
$ch = curl_init("https://api.kalle.build/v1/models");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer " . getenv("KALLE_API_KEY"),
],
]);
echo curl_exec($ch);import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class KalleExample {
public static void main(String[] args) throws Exception {
HttpRequest request = HttpRequest.newBuilder(URI.create("https://api.kalle.build/v1/models"))
.header("Authorization", "Bearer " + System.getenv("KALLE_API_KEY"))
.GET()
.build();
HttpResponse<String> response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
}
}Creating keys
Create keys in Kalle API in the Appmake console. Owners and admins of a workspace can create and delete keys.
- Every key starts with
kalle_sk_, so secret scanners and your own reviews can spot it. - The full key is shown once, when you create it. Appmake stores a hash and the last four characters, so nobody can show it to you again, us included.
- Give each app, server or environment its own key. You can then see usage per key and remove one without touching the others.
Rotating a key
Rotate keys on a schedule and straight away if one may have leaked:
- Create a new key in Kalle API.
- Deploy the new key to every place that uses the old one.
- Check the usage chart until the old key has no new requests.
- Delete the old key. Requests that still use it get a
401response from that moment.
Keeping keys safe
- Store keys in environment variables or a secret manager, never in source code.
- Add
kalle_sk_to the patterns your secret scanner looks for. - If a key shows up somewhere public, delete it first and investigate afterwards.