Authentication
Passwordless sign-in for people, OAuth tokens for integrations and agents.
Password sign-in is disabled by design — operators authenticate with a passkey, a magic link, or an email OTP.
Rekamedika accepts exactly two kinds of credentials, and every request is scoped to the tenant of the authenticated user:
better-auth session cookie, set by a passwordless sign-in against
/api/auth/*. In production the cookie is
__Secure-better-auth.session_token on .rekamedika.com (works across the
dashboard and the API).
Request a credential — one of:
# Magic link (5-minute, single-use)
curl -X POST https://api.rekamedika.com/api/auth/sign-in/magic-link \
-H 'Content-Type: application/json' \
-d '{"email":"you@your-hospital.example"}'
# Email OTP (6 digits, 5-minute, 3 attempts)
curl -X POST https://api.rekamedika.com/api/auth/email-otp/send-verification-otp \
-H 'Content-Type: application/json' \
-d '{"email":"you@your-hospital.example","type":"sign-in"}'Complete sign-in — open the emailed link, or submit the OTP to
POST /api/auth/sign-in/email-otp. Passkeys (WebAuthn, conditional UI) skip
email entirely — see the
passkey endpoints.
Call the API — the session cookie authenticates /trpc/* and
/satusehat/* requests from allow-listed origins.
For integrations and AI agents. The API is its own OAuth 2.0 / OIDC provider
(better-auth oidcProvider): discovery at
/api/auth/.well-known/openid-configuration, dynamic client registration at
POST /api/auth/oauth2/register, authorization-code + PKCE at
/api/auth/oauth2/authorize → /api/auth/oauth2/token.
curl https://api.rekamedika.com/trpc/pasien.list \
-H 'Authorization: Bearer YOUR_ACCESS_TOKEN'Tokens carry scopes: queries need
simrs:read, mutations need simrs:write — and RBAC still applies on top.
There is also a device-authorization flow (RFC 8628) under
/api/auth/device/* for input-constrained clients.
Trying endpoints from these docs
The playground on each API page sends requests directly from your browser to api.rekamedika.com with your own token — this docs site never proxies or stores credentials. Browser calls are subject to the API's CORS allow-list (server-side callers are unaffected); the generated cURL snippets work from anywhere.
Is this page helpful?