Developer Docs

Build on Etornie

REST API reference, AI features, and Solana attestation guides. Everything you need to embed IP workflows into your stack.

Public SDK ships with v0.2 — the API below is stable.
Quickstart
Up and running in 5 minutes
Authentication
JWT + wallet sign-in
Cases API
CRUD + status workflow
AI & RAG
EtornieGPT + indexing
IP Agent
Deadline scanning
Webhooks
Case event subscriptions
Wallet sign-in
ed25519 nonce flow
Errors
Status codes & retries

Quickstart

Login, list cases, and create one in three calls. Replace $TOKEN with the JWT you receive from /auth/login.

# 1. Login
curl -X POST https://api.etornie.com/auth/login \
  -H "Content-Type: application/json" \
  -d '{"email":"you@firm.com","password":"..."}'

# 2. List cases (RBAC-filtered)
curl https://api.etornie.com/cases \
  -H "Authorization: Bearer $TOKEN"

# 3. Create a trademark case
curl -X POST https://api.etornie.com/cases \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"type":"trademark","client_id":"clt_9x12","jurisdiction":"us_uspto","deadline_days":42}'

Authentication

Etornie supports two authentication methods: email + password (JWT) and Solana wallet sign-in (ed25519 nonce). Both issue the same access & refresh tokens.

JWT — email + password

POST /auth/register/request    // sends 6-digit OTP
POST /auth/register/verify     // confirms OTP & creates account
POST /auth/login                // returns access + refresh JWT
POST /auth/refresh              // rotates access token
GET  /auth/me                   // current user profile

Access token TTL: 30 minutes. Refresh token TTL: 7 days. Configure via ACCESS_TOKEN_EXPIRE_MINUTES and REFRESH_TOKEN_EXPIRE_DAYS.

Wallet sign-in (Phantom & Solflare)

// 1. Request a nonce
POST /auth/wallet/nonce
  { "public_key": "5xyz..." }

// 2. Sign with ed25519 in the wallet, then verify
POST /auth/wallet/verify
  { "public_key": "5xyz...",
    "signature":  "base58...",
    "role":       "client" }    // or "lawyer"

Nonces are single-use, Redis-backed, and expire after 5 minutes. The admin role cannot be self-assigned via wallet sign-up.

Cases API

Cases auto-number themselves (ETR-YYYY-NNNN) and move through a typed status workflow: openin_progressunder_reviewclosed.

POST   /cases                     // admin, lawyer
GET    /cases                     // RBAC-filtered list
GET    /cases/{id}                // participants only
PATCH  /cases/{id}                // admin, assigned lawyer
POST   /cases/{id}/notes          // add a note
GET    /cases/{id}/notes          // list notes
POST   /cases/{id}/documents      // upload
GET    /documents/{id}/download   // download

Guest-client support: pass guest_client_email instead of client_id. The case is auto-linked when the guest registers.

AI & RAG

EtornieGPT (Llama 3.3 70B Versatile via Groq) with optional RAG over your indexed dossier. Embeddings via Together AI, stored in pgvector.

POST  /ai/index/{document_id}    // admin, lawyer
POST  /ai/search                 // similarity (RBAC-filtered)
POST  /ai/chat                   // simple or RAG-augmented

Search results are filtered by RBAC before being passed to the model — users never see content they aren’t authorised to read.

IP Agent

An autonomous deadline scanner. Default reminder intervals are 30 / 7 / 1 days; minute-based reminders fire on the day of the deadline.

POST /agents/ip/scan-deadlines      // admin
GET  /agents/ip/upcoming-deadlines  // admin, lawyer
POST /agents/ip/configure           // admin

Reminders are routed via WhatsApp Business Cloud API and EmailJS. Duplicates are prevented automatically.

Webhooks

Subscribe to case-level events from your own backend. Payloads are HMAC-signed.

case.created
case.updated
case.deadline      // fires on every reminder
case.note.created
document.uploaded
agent.notification.sent
attestation.minted // Solana on-chain confirmation

Errors & retries

Need something we don't document yet?

Email info@etornie.com — we triage developer questions same-day during the beta.

View on GitHub See pricing