Back to Arky

Authentication & Account

User authentication, sessions, and account management

Manage operator authentication, sessions, and platform accounts through sdk.account.

Arky uses a magic-link email flow for admin/platform users. Request a code, verify it, and tokens are returned. Access tokens are short-lived (1 hour); refresh tokens last 7 days.

Note

These endpoints authenticate admin/platform users (store owners, team members). For storefront account login, use the CRM account flow.

Authentication (sdk.account.auth)

Request Auth Code

Request a magic link code for email authentication.

POST /v1/auth/code
SDK: sdk.account.auth.code(params)

Parameters

Name Type Description
email required string User email address
const challenge = await sdk.account.auth.code({
  email: 'user@example.com',
});

  // Keep challenge.challenge_id for the verify call.
  // The user receives the verification code by email.

Verify Auth Code

Verify the code received via email. On success, tokens are automatically set.

POST /v1/auth/verify
SDK: sdk.account.auth.verify(params)

Parameters

Name Type Description
challenge_id required string Challenge ID returned by the code request
code required string Verification code from email
const result = await sdk.account.auth.verify({
  challenge_id: challenge.challenge_id,
  code: '123456',
});

// The browser SDK stores the issued session internally.
console.log('Logged in successfully');

Response:

{
	"id": "session_abc123",
	"access_token": "eyJhbGciOiJIUzI1NiIs...",
	"refresh_token": "eyJhbGciOiJIUzI1NiIs...",
	"access_expires_at": 1704067200,
	"refresh_expires_at": 1704672000,
	"created_at": 1704063600,
	"is_verified": true
}

Refresh Token

Refresh an expired access token.

POST /v1/auth/refresh
SDK: sdk.account.auth.refresh(params)

Parameters

Name Type Description
refresh_token required string Refresh token from previous auth
const result = await sdk.account.auth.refresh({
refresh_token: 'eyJhbGciOiJIUzI1NiIs...',
});

console.log('Access token refreshed successfully');

Store Authentication

For multi-tenant applications, authenticate users against a specific store.

Request Store Auth Code

POST /v1/stores/{storeId}/auth/code
SDK: sdk.account.auth.storeCode(storeId, params)

Parameters

Name Type Description
storeId required string Store ID to authenticate against
email required string User email address
const challenge = await sdk.account.auth.storeCode('store_abc123', {
  email: 'contact@example.com',
});

  // Keep challenge.challenge_id for the storeVerify call.

Verify Store Auth Code

POST /v1/stores/{storeId}/auth/verify
SDK: sdk.account.auth.storeVerify(storeId, params)

Parameters

Name Type Description
storeId required string Store ID
challenge_id required string Challenge ID returned by the store code request
code required string Verification code from email
const result = await sdk.account.auth.storeVerify('store_abc123', {
  challenge_id: challenge.challenge_id,
  code: '123456',
});

// The browser SDK stores the issued session internally.
console.log('Operator logged in');

Account Management (sdk.account)

Get Current User

Get the authenticated platform account.

GET /v1/accounts/me
SDK: sdk.account.getMe({})
const user = await sdk.account.getMe({});

console.log('User ID:', user.id);
console.log('Email:', user.email);

Response:

{
	"id": "acc_abc123",
	"email": "user@example.com",
	"lifecycle": {
		"last_login_at": 1704067200,
		"onboarding_completed": true
	}
}

Update Account

Update the current account. API tokens and sessions are separate resources and are not embedded in this command.

PUT /v1/accounts
SDK: sdk.account.update(params)
const result = await sdk.account.update({});
console.log(result.success);

Search Accounts

Search for accounts (admin function).

GET /v1/accounts/search
SDK: sdk.account.search(params)

Parameters

Name Type Description
query optional string Search query
limit optional number Items per page
cursor optional string Pagination cursor
const result = await sdk.account.search({
	query: "john",
	limit: 20,
});

result.items.forEach((account) => {
	console.log(account.email, account.id);
});

Delete Account

Permanently delete the current user’s account.

DELETE /v1/accounts
SDK: sdk.account.delete(params)
Warning

This action is irreversible. All user data will be permanently deleted.

await sdk.account.delete({});

Sessions

Each successful verify or storeVerify call creates a separate account session. Sessions are not embedded in Account.

List Sessions

GET /v1/accounts/me/sessions
SDK: sdk.account.session.list()
const page = await sdk.account.session.list();
for (const session of page.items) {
	console.log(session.id, session.status, session.refresh_expires_at);
}

Revoke Session

DELETE /v1/accounts/me/sessions/{id}
SDK: sdk.account.session.revoke(id)
await sdk.account.session.revoke("session_abc123");

API Tokens

API tokens are separate long-lived credentials for backend automation. Send their value through the Authorization: Bearer header.

List API Tokens

GET /v1/accounts/me/api-tokens
SDK: sdk.account.apiToken.list()

Create API Token

POST /v1/accounts/me/api-tokens
SDK: sdk.account.apiToken.create(params)
const created = await sdk.account.apiToken.create({
	name: "CI deployment",
	expires_at: null,
});

// `value` is returned at creation time; store it securely.
const secret = created.value;

Rename or Revoke API Token

PUT /v1/accounts/me/api-tokens/{id}
SDK: sdk.account.apiToken.update(params)
DELETE /v1/accounts/me/api-tokens/{id}
SDK: sdk.account.apiToken.revoke(id)
await sdk.account.apiToken.update({
	id: "token_abc123",
	name: "CI deployment",
});
await sdk.account.apiToken.revoke("token_abc123");
Tip

Use API tokens for backend automation and account sessions for interactive admin access.


Complete Auth Flow Example

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

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

let pendingChallengeId: string | null = null;

async function requestLoginCode(email: string) {
	const challenge = await sdk.account.auth.storeCode("store_abc123", { email });
	pendingChallengeId = challenge.challenge_id;
}

async function verifyLogin(code: string) {
	if (!pendingChallengeId) throw new Error("Request a login code first");
	await sdk.account.auth.storeVerify("store_abc123", {
		challenge_id: pendingChallengeId,
		code,
	});
	pendingChallengeId = null;
	return sdk.account.getMe({});
}

await sdk.logout();