Authentication
Sign in storefront customers and operator accounts with email codes
Arky has two separate sign-in surfaces:
initializefromarky-sdk/storefrontkeeps a store’s customer sessions;createAdminfromarky-sdk/adminkeeps an operator account session.
Storefront Customers
import { initialize } from "arky-sdk/storefront";
import { createOrderToken } from "arky-sdk/utils";
const arky = initialize("arky_pk_...", {
locale: "en",
createVisitorIdentity: () => ({
customer_id: crypto.randomUUID(),
session_id: crypto.randomUUID(),
}),
createSessionId: () => crypto.randomUUID(),
createId: () => crypto.randomUUID(),
createOrderToken,
});
A first stateful call (a cart, a form, a chat) starts a visitor session: a customer with a visitor token, kept by the SDK. To sign the customer in, ask for a code and verify it:
const requested = await arky.customer.requestCode({
email: "ana@example.com",
language: "en",
});
console.log(requested.email_verification.expires_at);
await arky.customer.verify({ code: "123456" });
const me = await arky.customer.getMe();
if (me.customer.type.type === "verified") console.log(me.customer.type.email);
- The code email’s id comes from your
createId. When the answer is lost, requesting the same address in the same language again reuses that id, so the customer gets one email; passidyourself to pick it. languageis the language of the code email, one of the store’s languages.- The code email goes out with the template the store selected for
sign_in_code, from its sending address. A code request is refused at once while the store has none selected, the template has no text inlanguage, the sending address isn’t ready or the store’s email is paused, so show your own message then. See Store Email. - A code lasts ten minutes and allows five wrong tries; an address gets at most one new code a
minute. When the publishable key has a bot check, send the provider’s token as
bot_check_token. verifymakes the signed-in session under an id from yourcreateSessionId, and the customer’s email becomesverified. If another customer of the store already holds that address, the visitor’s cart and history move to that customer and the session continues as them.
Change The Email
On a signed-in session, requestCode starts an email change instead of a sign-in. The code goes to
the new address, and changeEmail proves it:
await arky.customer.requestCode({
email: "ana.new@example.com",
language: "en",
});
await arky.customer.changeEmail({ code: "654321" });
The session stays signed in and the email becomes the new verified address. The customer’s other
signed-in sessions end, and the old address gets the store’s email_changed email in the language
of the code request. A change to an address another verified customer holds is refused, and so is
the code request while the store has no email_changed email selected. A token refresh in between
keeps the pending change, so the code still completes it.
updateMe can’t replace or remove a proven email; only a code changes it. To sign in as someone
else instead, call logout first.
Read the session, follow changes, or sign out:
console.log(arky.session.get(), arky.isAuthenticated);
const stop = arky.onAuthStateChanged((session) => {
console.log(session?.customer.id ?? "signed out");
});
await arky.customer.logout();
stop();The arky_pk_... key identifies the store and is safe in browser code. It signs nobody in.
Never put a secret key in storefront code; the SDK creates and stores the customer’s own session
tokens.
Operator Accounts
import { createAdmin } from "arky-sdk/admin";
const sdk = createAdmin({ apiUrl: "https://api.arky.io" });
const pending = await sdk.account.auth.requestCode({ email: "lena@example.com" });
await sdk.account.auth.verify({ session_id: pending.session_id, code: "123456" });
const account = await sdk.account.getMe();
The Arky sign-in code is one of Arky’s own emails, sent from Arky’s address. For a store’s own
login page, pass the store’s id to both calls: sdk.account.auth.requestCode({ email, store_id })
and sdk.account.auth.verify({ session_id, code, store_id }). The Admin client keeps and refreshes
its session.
For trusted jobs, create one of the store’s secret keys and pass it as secretKey; see
API keys.
Expired Codes
A customer code is accepted only by the session that asked for it, and an account code only with
its own session_id. When a code expires, ask for a new one instead of retrying old state.
try {
await arky.customer.verify({ code: "000000" });
} catch (error) {
console.error(error instanceof Error ? error.message : "Verification failed");
}