Get started

Quickstart

This guide takes you from nothing to a working API call in about fifteen minutes. You'll register an app, connect your own Arkaayu account to it and read your profile from /api/me.

What you needAn Arkaayu account (free, created in the Arkaayu app), a server or local machine that can run a small web app, and a redirect URI for that app — http://localhost:3000/callback is fine while you're testing.

1. Create an Arkaayu account#

The developer console uses the same account as the Arkaayu app, and your Arkaayu account must already exist — you can't sign up in the console. If you don't have one yet, install the Arkaayu app on your phone and sign up there.

Use an email address you check: if you've turned on two-step sign-in, the console asks for a one-time code, which arrives by email from noreply@arkaayu.com. Add that address to your contacts so the code doesn't land in spam.

Your own account is automatically a test user of every app you create, so you can test with your own data. If you have an Arkaayu watch, pair it and let it sync once so there's something to read.

2. Sign in to the console and accept the Developer Terms#

Open the developer console and sign in with your Arkaayu email and password (and the emailed code, if two-step sign-in is on). The first time, you'll be asked for a display name (shown to reviewers, not to users), an optional company name and website, and to accept the Arkaayu Developer Terms.

3. Create an app#

Click Create app and fill in:

  • Name — what users will see on the consent screen. It can't contain "Arkaayu" or "Healaxy".
  • Redirect URIs — one per line, up to 5. For local development use http://localhost:3000/callback; production URIs must use https.
  • Scopes — tick only what you need. For this quickstart, read:profile is enough.

When you save, the console shows your client ID (starts with hx_) and client secret (starts with hxs_). The secret is shown only once: put it straight into your password manager or secrets store. If you lose it, rotate it from the app page.

Keep the secret on your serverNever ship the client secret inside a mobile app, desktop app or browser JavaScript. Anyone who can read your app's code can read the secret.

New apps start in test mode: they work for you and up to 25 test users you add by email.

4. Send the user to Arkaayu to sign in#

Arkaayu uses the OAuth 2.0 authorization code flow with PKCE. Your server creates a random code_verifier and state, keeps them in the user's session, and redirects the browser to the authorize endpoint:

Node.js

import crypto from "node:crypto";

const CLIENT_ID = process.env.ARKAAYU_CLIENT_ID;          // hx_...
const REDIRECT_URI = "http://localhost:3000/callback";

app.get("/connect", (req, res) => {
  const verifier = crypto.randomBytes(32).toString("base64url");
  const challenge = crypto.createHash("sha256").update(verifier).digest("base64url");
  const state = crypto.randomBytes(16).toString("base64url");
  req.session.arkaayu = { verifier, state };

  const url = new URL("https://api.arkaayu.health/oauth/authorize");
  url.search = new URLSearchParams({
    response_type: "code",
    client_id: CLIENT_ID,
    redirect_uri: REDIRECT_URI,
    scope: "read:profile",
    state,
    code_challenge: challenge,
    code_challenge_method: "S256",
  });
  res.redirect(url.toString());
});

Python

import base64, hashlib, os, secrets
from urllib.parse import urlencode
from flask import redirect, session

CLIENT_ID = os.environ["ARKAAYU_CLIENT_ID"]   # hx_...
REDIRECT_URI = "http://localhost:3000/callback"

@app.get("/connect")
def connect():
    verifier = secrets.token_urlsafe(48)
    challenge = base64.urlsafe_b64encode(
        hashlib.sha256(verifier.encode()).digest()).rstrip(b"=").decode()
    state = secrets.token_urlsafe(16)
    session["arkaayu"] = {"verifier": verifier, "state": state}

    params = {
        "response_type": "code",
        "client_id": CLIENT_ID,
        "redirect_uri": REDIRECT_URI,
        "scope": "read:profile",
        "state": state,
        "code_challenge": challenge,
        "code_challenge_method": "S256",
    }
    return redirect("https://api.arkaayu.health/oauth/authorize?" + urlencode(params))

The user signs in on an Arkaayu page, sees which data you're asking for, and approves. Arkaayu then redirects back to your redirect URI with ?code=...&state=....

5. Exchange the code for tokens#

In your callback handler, check that state matches what you stored, then exchange the code (valid for 5 minutes, single use) at the token endpoint:

Node.js

app.get("/callback", async (req, res) => {
  const saved = req.session.arkaayu;
  if (!saved || req.query.state !== saved.state) return res.status(400).send("State mismatch");
  if (req.query.error) return res.send("You didn't connect Arkaayu. No problem!");

  const r = await fetch("https://api.arkaayu.health/oauth/token", {
    method: "POST",
    headers: {
      "Content-Type": "application/x-www-form-urlencoded",
      Authorization: "Basic " + Buffer.from(`${CLIENT_ID}:${process.env.ARKAAYU_CLIENT_SECRET}`).toString("base64"),
    },
    body: new URLSearchParams({
      grant_type: "authorization_code",
      code: req.query.code,
      redirect_uri: REDIRECT_URI,
      code_verifier: saved.verifier,
    }),
  });
  const tokens = await r.json();
  if (!r.ok) return res.status(400).send(tokens.error_description || tokens.error);

  // Store tokens.access_token and tokens.refresh_token (encrypted) for this user.
  await saveTokens(req.user.id, tokens);
  res.redirect("/connected");
});

Python

import requests
from flask import request, abort

@app.get("/callback")
def callback():
    saved = session.pop("arkaayu", None)
    if not saved or request.args.get("state") != saved["state"]:
        abort(400, "State mismatch")
    if request.args.get("error"):
        return "You didn't connect Arkaayu. No problem!"

    r = requests.post(
        "https://api.arkaayu.health/oauth/token",
        auth=(CLIENT_ID, os.environ["ARKAAYU_CLIENT_SECRET"]),
        data={
            "grant_type": "authorization_code",
            "code": request.args["code"],
            "redirect_uri": REDIRECT_URI,
            "code_verifier": saved["verifier"],
        },
        timeout=10,
    )
    tokens = r.json()
    if not r.ok:
        abort(400, tokens.get("error_description", tokens["error"]))

    # Store tokens["access_token"] and tokens["refresh_token"] (encrypted) for this user.
    save_tokens(current_user.id, tokens)
    return redirect("/connected")

6. Call the API#

Send the access token as a bearer token. /api/me needs the read:profile scope:

curl

curl https://api.arkaayu.health/api/me \
  -H "Authorization: Bearer $ACCESS_TOKEN"

Node.js

const r = await fetch("https://api.arkaayu.health/api/me", {
  headers: { Authorization: `Bearer ${accessToken}` },
});
const me = await r.json();
console.log(me.data.firstName);

Python

r = requests.get(
    "https://api.arkaayu.health/api/me",
    headers={"Authorization": f"Bearer {access_token}"},
    timeout=10,
)
print(r.json()["data"]["firstName"])
Response
{
  "data": {
    "id": 123,
    "firstName": "Priya",
    "lastName": "Sharma",
    "email": "priya.sharma@example.com"
  },
  "scope": "read:profile"
}

That's it — you're connected. Access tokens last an hour; use the refresh token to get a new one without asking the user again (see Refreshing tokens).

Next steps#

Questions or something unclear? Write to developers@arkaayu.com.