Pupul Identity docs

Two verbs. A scoped, consented identity token, gated by how a person types.

The base URL is https://noctaracorp.com. All endpoints are JSON over HTTPS and CORS-open. There are no SDKs to install for the core flow; it is three HTTP calls.

Honest scope: keystroke presence is a v1 confidence signal, not a calibrated biometric with published false-accept/reject rates. The token always carries an honest presence label. Your app decides how much to trust it.

The model

A person has a read on file (a word and a rhythm, taken once at noctaracorp.com). They enroll a keystroke signature. When your app needs their identity, they authorize a scoped grant by typing their phrase; you receive a token. You verify the token to read the consented claims and the presence label.

enroll   Enroll a keystroke signature

POST /api/identity-enroll

{
  "email":   "person@example.com",
  "phrase":  "their word or short phrase",
  "samples": [ [ {"k":"a","d":0,"u":92}, ... ], ...x4 ]
}

Each sample is the keystroke timing of one typed attempt: per key, d = keydown ms and u = keyup ms, both relative to the first keydown. Send at least 3 (4 is better). We store only a derived reference, never the phrase. Returns { ok, enrolled, self_min }.

read + verify   Request a scoped, presence-gated grant

POST /api/identity-grant

{
  "email":   "person@example.com",
  "app_id":  "your.app",
  "scope":   "word rhythm force",
  "phrase":  "their phrase",
  "kd":      [ {"k":"a","d":0,"u":90}, ... ],
  "require_presence": true
}

Allowed scopes: word, rhythm, force, half_truth, compliance_lever. The person consents to exactly these. With require_presence: true, the grant returns 401 unless the keystroke rhythm verifies. Returns a signed token plus the presence result:

{
  "ok": true,
  "token": "<jwt>",
  "scope": "word rhythm force",
  "presence": { "level": "verified", "confidence": 0.77 },
  "expires_at": "..."
}
presence.levelmeaning
verifiedkeystroke rhythm matched (confidence ≥ 0.65). Token amr includes keystroke.
weakpartial match (0.5 to 0.65). Treat with caution.
faileddid not match. With require_presence, the grant is refused.
unverifiedno keystroke sample sent, or no enrollment on file. Email-only trust.

verify   Verify a token you received

POST /api/identity-verify with { token }, or Authorization: Bearer <token>. Returns the consented claims and presence:

{
  "ok": true, "valid": true,
  "claims": {
    "sub": "<mark>", "aud": "your.app", "scope": "word rhythm force",
    "amr": ["email","keystroke"], "presence": "verified", "presence_conf": 0.77,
    "word": "...", "rhythm": "...", "force": "...", "exp": 0
  }
}

Revoked or expired tokens return 401. A person can revoke any grant from their identity page; verification fails immediately after.

Why presence matters

Email and passwords prove what a person knows. As agents act on people's behalf, the question becomes whether a real, specific human is present at the moment of consent. The presence label is an honest answer to that, bound into the token, so a relying party can require it for high-stakes actions and skip it for low-stakes ones.

Request a key and a design-partner slot.