Launch on 01/01/2027Licenses available from 01/01/2027
PreviewThis page documents the release that launches on 01/01/2027. Packages, images and sign-up open then, and details may change before it.
Docs / Guides / Integrate: full

Integrate: full

Ready
TL;DR

The whole path from zero to a signed approval, from your backend’s side. You create an opaque user once, hand them the app, invite their device with a QR, and from then on ask for a signed approval whenever an action matters — and verify it. Six calls, no cryptography on your side. Each step links to its detailed guide.

Who this is for: the engineer wiring the full integration — not just one step-up guard, but the complete lifecycle. This page is the spine; every step points to a deep-dive and to the exact API reference call.

Ydentifi is six calls from your backend. Steps 1–3 onboard a user once; steps 4–5 repeat every time an action is worth protecting. You never touch a key or a signature — the app and SDK do that; your side is these calls plus your own screens.

1 · Create userone opaque id
→
2 · Give the appthey install it
→
3 · Invite devicea QR to scan
→
4 · Ask approvalper action
→
5 · Verifysigned outcome
ⓘ Prefer just one guarded action?

If you only want to protect a single high-stakes operation without changing your login, the shorter Integrate: step-up is the faster read. This page is the full lifecycle.

1–3 Onboarding — once per user

1  Create the user#

Mint one opaque identity per real person and store the returned opaque_id next to your own record. That token is the entire link between your world and Ydentifi — you keep the person, Ydentifi only ever sees the id.

// Once per real person. The RP is identified by its mTLS cert (no body).
opaqueID, err := client.CreateUser(ctx)
if err != nil { /* handle */ }
saveOpaqueID(myUserID, opaqueID) // one more column in your users table
your_users  ·  your existing database
emailname…ydentifi_opaque_id
pete.mitchel@acme.examplePete Mitchell…dkfjvfisdg8f7a1c9e2b…
jo.tan@acme.exampleJo Tan…9b2e7c4a1f0d5583c410…

→ Detail: Manage RPs & users · CreateUser in the API reference

2  Get the app into their hands#

The user installs the Ydentifi authenticator from the App Store or Google Play. It stays a blank shell — no accounts, nothing to configure — until your enrollment QR in step 3 wakes it for your deployment. If you would rather the ceremony live inside your own app, embed the SDK instead; the rest of this page is identical either way.

→ Detail: When to embed · Swift SDK

3  Invite their device#

Mint a single-use invite for that user and render qr_payload as a QR. The user scans it in the app; the device attests it is genuine, generates a hardware-bound key, and enrolls — all without you handling any of it. When the call returns, that person has a phone that can approve.

inv, err := client.IssueEnrollmentInvite(ctx, ydentifi.IssueEnrollmentInviteRequest{
    OpaqueID:   opaqueID,
    TTLSeconds: 300,
})
if err != nil { /* handle */ }
renderQR(inv.QRPayload) // the user scans this in the Ydentifi app

→ Detail: Enroll & link devices · IssueEnrollmentInvite

4–5 Authorization — every action worth protecting

4  Ask for approval when it matters#

When a protected action happens — a transfer, a settings change, a login you want hardened — issue a challenge over the exact action at the strength you require. Put the specifics in context: it is hashed into the signature, so what the user approves is what actually happens.

ch, err := client.IssueAuthChallenge(ctx, ydentifi.IssueAuthChallengeRequest{
    OpaqueID:    opaqueID,
    Context:     []byte("Approve a $4,200 transfer to ...8842"),
    MinStrength: ydentifi.AuthStrengthBiometric, // level 2 — biometric, no passcode fallback
    TTLSeconds:  120,
})
if err != nil { /* handle */ }
renderQR(ch.QREncoded) // or push it to the already-enrolled device

→ Detail: Authorize an action · IssueAuthChallenge

5  Verify the signed outcome#

Block until the terminal result — no polling, no webhook. The deployment verifies the device signature and refuses any approval below the tier you asked for; on approval you read the tier it actually reached and the location it reported, then act. Treat everything that is not APPROVED as a no.

// Blocks until terminal; the SDK holds the stream and returns the verdict.
result, err := client.AwaitChallenge(ctx, ch.ChallengeID)
if err != nil { return deny() }
switch result.Status {
case ydentifi.ChallengeStatusApproved:
    return proceed(result) // result.AuthStrength may beat the floor you asked for
default:
    return deny() // default-closed: anything but APPROVED is a no
}

→ Detail: Authorize an action · AwaitChallenge

6  Manage over time#

From here it is steady state. Steps 4–5 repeat per action; onboarding only recurs when someone joins or changes device. As people and phones change, the same API covers it: list a user’s devices, revoke a swapped phone or ban a stolen one, issue a recovery invite for a lost device, or lock a user. Each change is a line in the deployment’s own logs.

→ Detail: Manage RPs & users · Enroll & link devices (recovery) · API reference

ⓘ That is the whole surface

Six calls: CreateUser, IssueEnrollmentInvite, IssueAuthChallenge, AwaitChallenge, and the device-management calls. No keys, no secrets, no cryptography on your side — the app holds the private key in hardware and the server does the verifying. You write the calls above and your own UX around them.

Opens on 01/01/2027

Available at launch

Until then, you can try the whole ceremony on your own phone.