One identity layer for Australian real estate.
Add “Sign in with Agent ID” to your product in 30 minutes. Standards-based OAuth 2.1 + OpenID Connect, with claims tailored to real estate — agency context, role, licence, verified status.
Quickstart
Three steps from zero to a working sign-in.
# Sandbox (use in your staging + local dev)
https://sandbox.agent-id.com.au/.well-known/openid-configuration
# Live (use only in production)
https://agent-id.com.au/.well-known/openid-configurationSandbox + Live, fully isolated
Two physical environments, identical code, separate databases. Test with confidence; ship with safety.
Each environment issues its own credentials. A token issued by sandbox cannot be validated against live (and vice versa) — the JWKS and issuer URL are different. Read the full mental model.
Drop-in Next.js integration
Auth.js handles PKCE, code exchange, JWKS validation, and refresh rotation. You write 30 lines.
import NextAuth from "next-auth";
const { handlers } = NextAuth({
providers: [
{
id: "agent-id",
name: "Agent ID",
type: "oidc",
issuer: process.env.AGENT_ID_ISSUER!, // sandbox or live URL
clientId: process.env.AGENT_ID_CLIENT_ID!,
clientSecret: process.env.AGENT_ID_CLIENT_SECRET!,
authorization: { params: { scope: "openid profile email" } },
checks: ["pkce", "state"],
},
],
callbacks: {
async jwt({ token, profile, account }) {
if (account && profile) {
const meta = (profile as any).user_metadata ?? {};
token.agentId = meta.agent_id;
token.agencyId = meta.agency_id;
token.role = meta.role;
token.verified = meta.verified;
token.brandingUrl = meta.branding_url;
token.mode = meta.mode; // "test" | "live"
token.accessToken = account.access_token;
}
return token;
},
},
});
export { handlers as GET, handlers as POST };Express + openid-client, Python + Authlib, raw OIDC — see the full integration guide for samples.
What you get in the token
All Agent ID-specific data lives under user_metadata. Standard OIDC claims are at the root.
| Claim | Type | Description |
|---|---|---|
| agent_id | UUID | Stable Agent ID. Use as your foreign key. |
| professional_name | string | Public-facing name. May differ from full_name. |
| agency_id | UUID | null | Active agency context. Null = independent agent. |
| agency_name | string | null | Agency trading name. |
| role | enum | null | principal | admin | sales | property_mgr | support |
| verified | boolean | Agent passed FrankieOne KYC + state licence check. |
| agency_verified | boolean | Agency passed ABN + corporate licence verification. |
| licence_state | enum | null | VIC | NSW | QLD | WA | SA | TAS | ACT | NT |
| branding_url | URL | null | Agency manifest if a current agency is set, else agent manifest, else null. |
| mode | "test" | "live" | Defence-in-depth: which environment issued the token. |
REST endpoints
Bearer-authenticated. Call with the access token from your OIDC client.
/v1/meFull agent + active agency snapshot. Always fresh — use this when claims may be stale.
/v1/agencies/{id}Agency profile. 403 if the calling agent isn't a member.
/v1/agencies/{id}/brandingBranding manifest with versioned asset URLs. Cache for 60s.
/v1/agents/{id}/brandingIndependent-agent branding manifest. Used when agency_id is null.
Ready to integrate?
Get sandbox credentials in under a day. Live credentials follow once your integration is reviewed.