Start here
Local quickstart
Run the API locally, create a project, and try both an automatic decision and a human review.
Before you start
- A local checkout of the Kernall repository. If needed, request source access.
- Node.js 22.13.0 or newer, npm, and curl.
- A terminal opened at the repository root. These examples use a POSIX-style shell, such as the default macOS shell.
- A trusted local machine. Localhost automatically uses a development identity.
1. Start the development server
npm ci
npm run devWait for the local URL to appear. The default is http://localhost:3000; use the printed URL if your instance uses another port. Leave this terminal running.
The app connects to your Supabase project. Configure SUPABASE_URL, SUPABASE_PUBLISHABLE_KEY, and SUPABASE_SECRET_KEY in a local .env.local file before starting.
2. Create your project
Open a second terminal:
export KERNALL_BASE_URL="http://localhost:3000"
curl --fail-with-body -X POST "$KERNALL_BASE_URL/api/projects/bootstrap" \
-H 'Content-Type: application/json' \
-d '{"name":"My first project"}'The first successful response has status 201 and includes project, policy, api_keys, and a raw api_key. Save that secret; it is shown once. Repeating the request loads the same project with status 200, without revealing the key again.
export KERNALL_API_KEY="paste-the-key-returned-by-bootstrap"Use the full key from bootstrap, not the dashboard demo key. If you lost it, see key rotation.
3. Check a sample action
curl --fail-with-body "$KERNALL_BASE_URL/api/check" \
-H "Authorization: Bearer $KERNALL_API_KEY" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: quickstart-navigation-1' \
-d '{
"action_type": "navigate",
"destination": "https://example.com",
"task_context": "Learning how action checks work"
}'With the default policy, expect decision: "approved", data_type_detected: null, and a check_id. The response also contains safe log metadata. A customized policy may produce another decision.
This request does not navigate to example.com. Your application performs the approved action.
4. Try a human review
curl --fail-with-body "$KERNALL_BASE_URL/api/check" \
-H "Authorization: Bearer $KERNALL_API_KEY" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: quickstart-submit-1' \
-d '{
"action_type": "submit",
"data": "Sample form content",
"destination": "https://example.com/form",
"task_context": "Testing a human review"
}'The default policy pauses every submit action, even with ordinary sample text. The important response fields are:
{
"decision": "requires_human",
"reason": "Action \"submit\" requires human confirmation for this project.",
"confirmation_id": "<confirmation-id>",
"confirmation_url": "http://localhost:3000/dashboard/confirmations/<confirmation-id>",
"data_type_detected": null,
"check_id": "<check-id>"
}Use your actual confirmation_id to resolve this sample action through the local owner endpoint:
# Use the confirmation_id from your check response.
export KERNALL_CONFIRMATION_ID="paste-the-confirmation-id"
# Local development: the reviewer resolves this specific action.
curl --fail-with-body -X POST \
"$KERNALL_BASE_URL/api/confirmations/$KERNALL_CONFIRMATION_ID/resolve" \
-H 'Content-Type: application/json' \
-d '{"decision":"approved"}'curl --fail-with-body \
"$KERNALL_BASE_URL/api/confirmations/$KERNALL_CONFIRMATION_ID/status" \
-H "Authorization: Bearer $KERNALL_API_KEY"The last response should show status: "approved" and decision: "approved". To test denial on a new review, send {"decision":"denied"} to its resolve endpoint.
5. Connect your own workflow
Choose your policy, integrate checks, and decide how an owner will review requests. Start with sample data.
Reuse an idempotency key only for a retry of the same action. For a new experiment, use a new key or Kernall returns the original result. Stop the server with Ctrl+C when finished.