Back to Arky

Authentication

Authenticate storefront contacts and platform operators with verification codes

Arky has two explicit authentication surfaces:

  • initialize from arky-sdk/storefront authenticates customers on a storefront.
  • createAdmin from arky-sdk/admin authenticates platform operators and store team members.

Both use an email verification code. The request returns a challenge_id; keep it and send it with the code. A code without its challenge cannot be verified.

Storefront Contact Authentication

Create one storefront store for the browser application:

import { initialize } from "arky-sdk/storefront";

const storefront = initialize("arky_pk_...", {
	market: "us",
	locale: "en",
});

Request a code and retain the returned challenge:

const identified = await storefront.identify({
	email: "contact@example.com",
	verify: true,
});

const challengeId = identified.verification_challenge?.challenge_id;
if (!challengeId) throw new Error("Verification challenge was not created");

Verify the code entered by the customer:

await storefront.verify({
	challenge_id: challengeId,
	code: "123456",
});

const contact = await storefront.me();
console.log(contact.email);

The browser SDK persists the storefront session internally as an arky_vst_... visitor token. It sends that token only after a stateful operation creates the visitor session. Read current state through the store, subscribe to changes, or log out through the same instance:

const session = storefront.session.get();
const stop = storefront.onAuthStateChanged((nextSession) => {
	console.log(nextSession?.contact.email ?? "signed out");
});

await storefront.logout();
stop();
Note

Calling identify() without an email creates or resumes the anonymous storefront contact used for carts and other pre-login activity. Authentication is established only after verify succeeds.

Important

The arky_pk_... publishable key identifies the Store and is safe in browser code. It is not a visitor or Admin credential. Never put a Personal API Token in storefront code; the SDK creates and persists arky_vst_... visitor sessions itself.

Platform Operator Authentication

Use the admin client for operators, never the storefront contact client:

import { createAdmin } from "arky-sdk/admin";

const admin = createAdmin({
	baseUrl: "https://api.arky.io",
	storeId: "store_abc123",
	market: "us",
});

const challenge = await admin.account.auth.code({
	email: "operator@example.com",
});

await admin.account.auth.verify({
	challenge_id: challenge.challenge_id,
	code: "123456",
});

const account = await admin.account.getMe({});
console.log(account.email);

For a store-branded operator challenge, use account.auth.storeCode and account.auth.storeVerify with the same challenge_id rule.

const challenge = await admin.account.auth.storeCode("store_abc123", {
	email: "operator@example.com",
});

await admin.account.auth.storeVerify("store_abc123", {
	challenge_id: challenge.challenge_id,
	code: "123456",
});

The admin client also persists its browser session internally:

console.log(admin.isAuthenticated);
await admin.logout();

Error Handling

Do not retry verification with a challenge from another request. If the challenge is missing or expired, request a new code.

try {
	await storefront.verify({ challenge_id: challengeId, code: "000000" });
} catch (error) {
	console.error(error instanceof Error ? error.message : "Verification failed");
}

Next Steps