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.
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.
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 }.
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.level | meaning |
|---|---|
verified | keystroke rhythm matched (confidence ≥ 0.65). Token amr includes keystroke. |
weak | partial match (0.5 to 0.65). Treat with caution. |
failed | did not match. With require_presence, the grant is refused. |
unverified | no keystroke sample sent, or no enrollment on file. Email-only trust. |
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.
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.