Base URL

https://api.boxowl.me/api/v1

All API traffic is JSON over HTTPS. The API subdomain serves no HTML — this documentation is the only human-readable reference.

Authentication

BoxOwl supports three authentication methods. Only one may be used per request.

JWTs expire after 24 hours; rotate via POST /api/v1/auth/refresh. Agent tokens carry an explicit expiresAt (default 1 year); a daily reminder job notifies users 7 days before expiry. All three credential types can be revoked at any time.

Rate Limits

Limits are enforced per IP+identity via Bucket4j with a token-bucket algorithm. Each tier has a burst capacity (max tokens) and a sustained refill rate.

TierBurstSustainedApplies to
Auth2010 / min/api/v1/auth/login, register, refresh, reset-password
Admin6030 / min/api/v1/admin/*
UI600200 / minUser JWT traffic from app/extension/web
API300100 / minAgent tokens and org API keys
Rotate11 / hourCredential rotation endpoints

Rate limit headers are included in every response: X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset.

Error Format

All errors follow a consistent JSON structure with LLM-friendly hints:

{
  "error": "BOX-409-001",
  "message": "Email or handle already in use",
  "hint": "Choose a different handle or log in instead.",
  "suggestedAction": "Try a unique handle or use POST /auth/login",
  "retryable": false
}

Endpoints

POST /auth/register
Create a new BoxOwl account. Returns user ID and optional MFA secret.
POST /auth/login
Authenticate and receive a JWT. Requires MFA code if enabled.
POST /auth/refresh
Rotate an expired JWT using a valid refresh token.
POST /auth/reset-password
Request a password reset email. Token expires in 1 hour.
GET /vault/*
Read vault categories. 23 categories ship today: identity, birth, addresses, emails, phones, socialLinks, links, externalIdentities, documents, travelDocuments, emergencyContacts, medicalBasics, dietary, education, workHistory, paymentMethods, loyaltyPrograms, vehicles, pets, anthropometrics, demographics, preferences, secureNotes. paymentMethods and secureNotes are end-to-end encrypted; servers store ciphertext only.
PUT /vault/*
Upsert vault items. Creates or replaces the full category payload.
PATCH /vault/*
Partial update of vault fields. Only sends changed values.
GET /perch
Dashboard summary: completion percentage, item counts, and quick-action CTAs.
GET /profile/css
Read the user's custom public profile CSS.
PUT /profile/css
Update custom CSS. Sanitized server-side for safety.
GET /u/{handle}
Public profile resolution. Accepts text/html or application/json.
GET /.well-known/did.json
did:web discovery document. W3C compliant.
GET /did/{handle}
Resolve a user's DID document by handle.
GET /schema/presentation
Get the UI presentation structure (groups and category ordering).
GET /schema/data
Get the canonical JSON schema for all personal data categories.
POST /api/v1/agents/batch
Batch update up to 50 operations. Partial application supported.
POST /api/v1/agents/query
Natural language query interface for AI agents. Regex-based intent matching.
GET /api/v1/agents/schema/{category}
Schema introspection: field types, required flags, and enum values per category.
POST /orgs/{slug}/api-keys
Create a scoped API key for the PDaaS organization.
GET /orgs/{slug}/connections
List all connected customer accounts for the org.
GET /orgs/{slug}/vault/{userId}/{category}
Read a customer's vault category (consent-gated).
PUT /orgs/{slug}/vault/{userId}/{category}
Upsert a customer's vault category data.
PATCH /orgs/{slug}/vault/{userId}/{category}
Partially update a customer's vault category.
DELETE /orgs/{slug}/vault/{userId}/{category}/{itemId}
Delete a specific item from a customer's vault.
POST /orgs/{slug}/webhooks
Subscribe to PDaaS events.
DELETE /orgs/{slug}/webhooks/{id}
Unsubscribe from events.
GET /orgs/{slug}/audit-log
Read audit log for all vault operations.
GET /orgs/{slug}/gdpr/export/{userId}
GDPR DSAR export for a connected user.
DELETE /orgs/{slug}/gdpr/erase/{userId}
GDPR erasure request for a connected user.
GET /orgs/{slug}/smrt
Read SMRT configuration: enabled, domain allowlist, passthrough mode. Public — no auth.
PUT /orgs/{slug}/smrt
Update SMRT configuration. Requires org admin authentication.
POST /api/v1/smrt/session
Mint the global X-BoxOwl-Smrt JWT (Tier 1) — rotating session UID + opt-in preference profile, RS256, 10-min TTL. Requires user auth. Called by the extension at login and every 10 min.
POST /api/v1/smrt/batch-mint
Batch-mint per-org X-BoxOwl-Identity JWTs (Tier 2/3) for a list of org slugs — pairwise orgUid, name, verified, embedded SMRT profile, RS256, 30-min TTL. PDaaS True orgs also get a tags claim.
GET /api/v1/smrt/domains/all
Global list of every registered org domain. ETag-supported. Drives X-BoxOwl-Smrt injection in the extension.
GET /api/v1/smrt/connections/domains
Per-user list of connected-org domains derived from active OrgConnection records. ETag-supported. Drives X-BoxOwl-Identity injection.
GET /api/v1/me/smrt-profile
Read the user's SMRT preference profile (age band, region, style roots, color palette, interests). Defaults returned if no row exists.
PUT /api/v1/me/smrt-profile
Upsert the user's SMRT preference profile.
POST /api/v1/pdaas/true/sync
PDaaS True batch pull — given { orgUids, scopes }, returns the latest vault data for up to 100 users per call. Org API key required.
GET /api/v1/pdaas/true/events?since=
PDaaS True missed-events recovery — replay customer.vault.user-updated events since a timestamp. 30-day retention.
GET /smrt/ping
Transparent 1x1 GIF for SMRT header injection validation. No auth.
GET /.well-known/smrt-jwks.json
SMRT JWKS — RS256 public keys for verifying both X-BoxOwl-Smrt and X-BoxOwl-Identity JWTs.

PDaaS

See the PDaaS API Reference for full documentation on API key authentication, organization management, consent-gated vault access, webhook events, and error codes specific to multi-tenant PDaaS.

SMRT

See the SMRT Integration Guide for setup, header reference, server examples, and privacy model for the Site-aware Member Recognition Technology.

Swagger UI

Interactive API documentation is available at:

https://api.boxowl.me/swagger-ui.html

This is auto-generated from the backend OpenAPI spec and kept in sync on every deployment.