Quickstart
Create an app, give it a key, and sign a person in with an emailed link. You need a terminal and a site you can run locally.
1. Create an account and an app
Sign in at app.dianthan.com with your email. You don't set a password. Then create your first app from the CLI:
npx dianthan login
npx dianthan apps create "Field Notes" --domain fieldnotes.localhost --signup openThe domain tells Dianthan where sign-in links may send people back to. --signup open lets anyone who signs in become a customer of this app; leave it off to allow invited people only.
Use
<name>.localhostfor local development. Browsers resolve it to your own machine, and unlike plainlocalhost, it gives each app a domain of its own.
2. Create a server key
npx dianthan keys create --app fieldnotes --name web-serverDIANTHAN_URL=https://api.dianthan.com
DIANTHAN_APP_ID=app_8Jq2…
DIANTHAN_KEY=dn_live_4f9c…The key is shown once. Put these three lines in your site's server environment (for example .env.local). Never send the key to a browser; it can act for any user of the app.
3. Send a sign-in link
From your server, ask Dianthan to email a link:
curl https://api.dianthan.com/v1/auth/magic-link \
-H "Content-Type: application/json" \
-d '{
"email": "ada@example.com",
"app_id": "app_8Jq2…",
"return_to": "http://fieldnotes.localhost:3000/auth/callback"
}'The response is always 202, whether or not the address has an account, so the endpoint can't be used to find out who your users are.
4. Exchange the grant
When Ada clicks the link, she confirms on a Dianthan page and lands on your return_to URL with a single-use grant parameter. Your callback route exchanges it for a session:
export async function GET(req: Request) {
const grant = new URL(req.url).searchParams.get("grant");
const res = await fetch(`${process.env.DIANTHAN_URL}/v1/auth/grants/exchange`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ grant }),
});
const session = await res.json();
// session.access_token (short-lived JWT), session.refresh_token (opaque)
const out = Response.redirect(new URL("/", req.url));
out.headers.append("Set-Cookie", `dn_refresh=${session.refresh_token}; HttpOnly; Secure; SameSite=Lax; Path=/`);
return out;
}Grants last a few minutes and work once. Store the refresh token in an httpOnly cookie on your own domain. Keep the access token in memory or in a short-lived cookie, and refresh it with POST /v1/auth/refresh.
5. Ask who is signed in
curl https://api.dianthan.com/v1/me \
-H "Authorization: Bearer $ACCESS_TOKEN"{
"id": "usr_x81…",
"email": "ada@example.com",
"name": null
}That's a working sign-in. From here: