Getting started
Register a Hekana app, send a store through the consent screen, exchange the code for a token and call the Apps API. Which SDK packages exist.
On this page
This page takes an app from registration to a first Apps API call. Every request below is to the Hekana API at https://api.hekana.com/api/v1. Replies are wrapped as { "success": true, "data": ..., "requestId": "..." }, including the OAuth token reply; read data.
Read this first. The OAuth flow only runs for approved apps, and approval is a manual review. You can register and submit today, but you cannot obtain a token for a draft app. Plan to build against the response shapes in the API reference until the review passes.
Packages: what exists
| Package | State |
|---|---|
@hekana/apps-sdk | Typed Apps API client (HekanaApps), verifyWebhook() and a hekana-apps CLI. TypeScript source in the Hekana repository. Not published to npm. |
hekana-sdk | A read-only client for the separate agent API (products, orders, customers). Not on npm. It does not call the Apps API. |
create-hekana-app | Scaffolds a project that uses hekana-sdk. Not on npm, so npx create-hekana-app does not work yet. |
Until @hekana/apps-sdk is released, call the API over HTTP as shown below. Its method names (orders.list, data.put, checkoutExtensions.put) mirror the endpoints, so moving to it later is a small change.
1. Register the app
Registering is a call made with the session of a store owner or admin (the developer is a store, and the app belongs to it).
{
"name": "Reorder reminders",
"redirect_uris": ["https://example.com/hekana/callback"],
"scopes": ["read_orders", "read_customers", "send_messages"],
"type": "confidential"
}redirect_uris: 1 to 10 addresses. They must behttps(plainhttponly forlocalhostand127.0.0.1) with no fragment, and are matched exactly.scopes: up to 20, from the list in Authentication and scopes.type:confidential(default) gets a client secret;publichas none and relies on PKCE alone.
The reply holds the app, its clientId (starts with hkna_) and, for a confidential app, clientSecret. The secret is shown once. Keep it on your server. POST /oauth/apps/:id/rotate-secret replaces it and shows the new one once.
The app starts as a draft. Before you can submit it, add its listing (see Testing and going live), then call POST /oauth/apps/:id/submit.
2. Send a store owner to the consent screen
After approval, send the store owner to the Hekana dashboard page /oauth/authorize with these query parameters:
client_id=<your client id>
redirect_uri=<one of your registered redirect URIs>
scope=read_orders read_customers
state=<random value you check on return>
code_challenge=<base64url SHA-256 of your code verifier>
code_challenge_method=S256PKCE with S256 is required; plain is refused. scope must be a subset of what the app registered. The owner sees the app name and the scopes, and approves or denies. On approval the browser returns to your redirect_uri with code and your state. A code lives 60 seconds and works once.
3. Exchange the code for tokens
const res = await fetch("https://api.hekana.com/api/v1/oauth/token", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
grant_type: "authorization_code",
code, // from the redirect
redirect_uri, // the same one
client_id: process.env.HEKANA_CLIENT_ID,
client_secret: process.env.HEKANA_CLIENT_SECRET, // confidential apps
code_verifier, // the verifier behind your code_challenge
}),
});
const { data } = await res.json();
// data: { access_token, token_type: "Bearer", expires_in: 3600, refresh_token, scope }Store both tokens per store. The access token lasts one hour; see Authentication for refresh.
4. Call the API
const res = await fetch("https://api.hekana.com/api/v1/apps-api/orders?limit=5", {
headers: {
Authorization: `Bearer ${accessToken}`,
"Hekana-Api-Version": "2026-10-01",
},
});
const { data } = await res.json();
// data: { data: [...orders], total, page, limit, nextCursor }The token decides the store. There is no store id in any request.
5. Listen for events
Subscribe with POST /apps-api/webhooks and verify every delivery. See Webhooks.
The hekana-apps CLI
The command in the SDK source is a thin command line over the same client, for poking at an installation: orders list, products list|get, customers list|get, data list|get|put|delete and verify-webhook. It reads the token from the HEKANA_TOKEN environment variable (never an argument) and prints JSON. It ships as TypeScript source with the SDK and has the same publishing status.