Developer documentation
The XityConnect Platform is a plain HTTP JSON API. There is no SDK to trust — only signatures to verify.
Authentication model
There are no passwords. A client holds an Ed25519 private key and proves possession by signing a server-issued challenge:
json.dumps({address, challenge}, sort_keys=True, separators=(',',':')) — i.e. {"address":"xity1…","challenge":"…"} with keys in alphabetical order. Sign with Ed25519; send the signature as hex.Authorization: Bearer <token> on authenticated calls.The private key never leaves the client. Registration (/auth/signup) accepts only a client-generated public key in PEM — server-side key handling returns 410 Gone, permanently.
Conventions
- Base URL: the platform host (default development port
8086). - All bodies and responses are JSON (
Content-Type: application/json). - Errors are FastAPI-shaped:
{ "detail": "human readable reason" }with a 4xx/5xx status. - Unexpected server errors return an opaque reference — quote it when contacting the operator.
- Browser origins must be allowlisted server-side (
XITY_CORS_ORIGINS); the API never allows*with credentials. - Addresses are
xity1+ 40 hex chars, derived assha256d(public_key)[:20].
Endpoints
GET/healthLiveness probe.
POST/auth/signupRegister an account from a client-generated public key. Creates the wallet, the identity record, and a WALLET_BIND transaction.
POST/auth/challenge?address=xity1…Issue a one-time auth challenge.
POST/auth/signinVerify the challenge signature and open a session.
POST/auth/signout-allRevoke every session for the caller.
Auth: Bearer
GET/walletThe caller's wallet: type, balance, bound identity.
Auth: Bearer
GET/wallet/transactions?limit=50The caller's transaction history (PII-scrubbed).
Auth: Bearer
GET/identityThe caller's identity record (private evidence excluded).
Auth: Bearer
POST/verify/requestIssue a verification code for email/phone/device/wallet. The code is logged server-side and relayed by the operator; it is NEVER returned by the API.
Auth: Bearer
POST/verify/confirm?method=email&code=…Confirm a code. On success the method is timestamped on chain. Codes expire in 10 minutes and work once.
Auth: Bearer
POST/recovery/startInitiate recovery. Starts the 24-hour clock and notifies the wallet owner. Proofless by design.
GET/recovery/status/{request_id}Status of a request. The linked address is never disclosed.
GET/recovery/pendingThe caller's pending recovery requests.
Auth: Bearer
POST/recovery/cancelCancel a pending request. Owner-only — requires the owner's session.
Auth: Bearer
POST/recovery/enroll/guardians?guardians=xity1a&guardians=xity1bReplace the enrolled guardian set. Each guardian must be a registered wallet; minimum two.
Auth: Bearer
GET/recovery/guardiansList the caller's enrolled guardians.
Auth: Bearer
POST/recovery/backup-codeProvision (or replace) the caller's single-use backup code. Returned exactly once.
Auth: Bearer
POST/recovery/device-tokenProvision (or replace) a trusted-device recovery token. Returned exactly once.
Auth: Bearer
POST/recovery/completeComplete a recovery after the waiting period with a per-method proof, rotating the wallet key.
GET/profileThe caller's presentation profile.
Auth: Bearer
PUT/profileUpdate display name / preferences / privacy settings.
Auth: Bearer
GET/permissionsList the caller's grants in both directions: made by them and held by them.
Auth: Bearer
POST/permissions/grantDelegate scoped access. Scopes/levels are a closed allowlist; admin and wildcards are rejected.
Auth: Bearer
GET/notifications?unread_only=falseThe caller's notifications.
Auth: Bearer
POST/vault/storeStore a claim in the vault. Sealed with a SHA-256 integrity hash verified on every read.
Auth: Bearer
GET/vault/{key}Read a claim. Owner-only; tampered values are refused.
Auth: Bearer
GET/chain/infoChain the platform anchors to.
