From Protocol to Production: Launching the IPCHA API Service
A deep dive into building and deploying a complex protocol (IPCHA) as a fully rentable API service, covering FastAPI, Next.js, Prisma, and key lessons from the trenches of a rapid development cycle.
It’s 12:15 UTC, and I've just pushed the final commit, watched the CI pipelines glow green, and seen PR #133 merge into main. The feeling of a major feature fully deployed, tested, and documented is always exhilarating. Today, we're celebrating the launch of the IPCHA Protocol API Service—a monumental effort that transformed a complex protocol into a rentable, robust, and user-friendly offering.
This post will walk you through the journey: from the core protocol implementation to building a full-fledged API, dashboard, and CLI integration, all while sharing the critical lessons learned along the way.
The Mission: IPCHA to the World
Our primary goal was ambitious: take the newly developed IPCHA (Inter-Protocol Claim Hashing and Arbitration) protocol, implement its 15 distinct modules, and expose it as a scalable, rentable API service. This wasn't just about functionality; it was about productization—complete with authentication, rate limiting, metering, a customer dashboard, and even Bring Your Own Key (BYOK) integration.
The journey encompassed:
- IPCHA Protocol Implementation: The core logic, written in Python.
- FastAPI Sidecar: The high-performance API layer.
- REST Proxy & Middleware: The public-facing gateway with robust access control.
- Prisma & PostgreSQL: For data persistence, tokens, and usage logs.
- Next.js Dashboard: A rich UI for customers and administrators.
- ShellAI CLI API: Extending functionality to command-line users.
- End-to-End Testing & Documentation: Ensuring reliability and usability.
And as of today, it's all live on main.
From Python Modules to a Public-Facing API
The foundation of this service is the IPCHA protocol itself. Over the past sessions, we meticulously crafted 15 Python modules across ipcha/, src/arbitration/, benchmarks/, sdrl_claims/, and scripts/. With 78 unit tests ensuring its internal integrity, the core protocol was solid, committed as b34b44f.
But a protocol isn't a product until it's accessible. This is where the API layer came in.
The FastAPI Powerhouse
We opted for a FastAPI sidecar (ipcha/api.py, ipcha/Dockerfile) to serve the Python-based IPCHA logic. This provided 10 high-performance endpoints, seamlessly integrated into our Docker Compose setup. It’s fast, robust, and leverages Python's strengths.
Data Persistence and Security
For managing API tokens, usage logs, and job states, we designed a Prisma schema with IpchaApiToken, IpchaUsageLog, and IpchaJob models. Crucially, we implemented Row-Level Security (RLS) policies in prisma/rls.sql to ensure data isolation between tenants.
A dedicated token service (src/server/services/ipcha-token-service.ts) was built to issue secure nyx_ip_ tokens, hashed with SHA-256 for integrity.
The Next.js & TypeScript Ecosystem
Our frontend and API gateway were built on Next.js and TypeScript, providing a unified developer experience.
- Sidecar Client: A robust
callIpcha()function (src/server/services/ipcha-client.ts) handles communication with the FastAPI sidecar. - REST Middleware: This is the heart of our rentable service. In
src/app/api/v1/ipcha/middleware.ts, we implemented:- Authentication: Verifying API tokens.
- Rate Limiting: Preventing abuse.
- Daily Quota Management: Enforcing usage limits.
- Metering: Tracking API calls for billing.
- REST Proxy: The public-facing API (
src/app/api/v1/ipcha/_proxy.tsand 11 route files) routes all sync and async requests to the sidecar, applying the middleware policies. - Bring Your Own Key (BYOK): A critical enterprise feature, our
validate/route.tsresolves tenant API keys by decryptingapiKey.encryptedKeyand passes it securely via anX-LLM-Api-Keyheader. - tRPC Router: For internal and dashboard communication, a dedicated
ipcha.tstRPC router provides both customer and admin access. - Dashboard: Located at
src/app/(dashboard)/dashboard/ipcha/, our new dashboard features 8 tab components, offering customers full visibility into their IPCHA usage, tokens, and job status. - ShellAI CLI API: To extend the reach, we integrated 8 new endpoints, 3 services, and 20 tests into our existing CLI API (
src/app/api/v1/cli/), allowing command-line access to IPCHA functionalities.
Quality and Deployment
A project of this scale demands rigorous testing. With 78 Python unit tests for the core protocol and 20 tests for the CLI API, we had strong foundational coverage. The final step was end-to-end validation. Our integration test report (docs/reports/2026-03-15-ipcha-api-integration-test.md) proudly shows 14/14 tests passing, covering everything from scoring and sanitization to arbitration, routing, evaluation, and access control, with full data flow traces documented.
The culmination of this effort was PR #133, merging feat/cli-api into main at 2026-03-15 11:50 UTC, after all CI checks (Unit Tests, Lint & Typecheck, E2E Tests) passed flawlessly.
Lessons Learned: Navigating the Hurdles
No complex project is without its challenges. Here are some of the key "pain points" we encountered and how we overcame them, hopefully saving you some headaches!
1. Prisma's Stricter JSON Types
- The Problem: We initially tried to use
Record<string, unknown>for a Prisma Json field, expecting flexibility. However, Prisma'sInputJsonValueis much stricter, leading toTS2322type errors. - The Workaround: For compatibility, we found that
JSON.parse(JSON.stringify(body))effectively converts arbitrary objects into a structure that Prisma'sInputJsonValuecan accept, ensuring type safety without sacrificing too much flexibility.
2. Next.js fetch() Caching Gotchas
- The Problem: When calling our FastAPI sidecar from Next.js, we noticed stale data in the playground. Next.js 14, by default, caches
fetch()results, which is great for static content but problematic for dynamic API calls. - The Workaround: The fix was simple but crucial: adding
cache: "no-store"to ourcallIpcha()function inipcha-client.ts. This explicitly tells Next.js not to cache the fetch results, ensuring fresh data on every request.
3. Dockerignore's Broad Strokes
- The Problem: Our
.dockerignorefile was set to exclude alltests/directories for a leaner production image. However, we neededtests/evaluation/for specific runtime checks. - The Workaround: We added an exception:
!tests/evaluationto the.dockerignorefile. This allows specific subdirectories to be included while maintaining the general exclusion rule. A good reminder to be precise with ignore files!
4. PostgreSQL Type Casting in Prisma Raw Queries
- The Problem: When executing raw SQL queries via Prisma's
$queryRaw, we encounteredoperator does not exist: uuid = texterrors. Prisma was passingctx.tenantIdas a string, but our PostgreSQL column expected auuidtype. - The Workaround: Explicit type casting in the SQL query itself saved the day:
${ctx.tenantId}::uuid. This tells PostgreSQL to treat the incoming string as a UUID, resolving the type mismatch.
5. tRPC Union Return Types from .catch()
- The Problem: In our
systemHealthtRPC router, we tried to return a default object using.catch(() => ({ total: 0 }))for error handling. This created a union return type that TypeScript couldn't easily narrow, making field access (.total) problematic without verbose checks. - The Workaround: We extracted a
const defaultMetrics = { ... }object and explicitly typed thecallIpcharesult ascallIpcha<typeof defaultMetrics>. Then, we handled the.then(r => r.total)separately. This maintains type safety and avoids the union type complexity.
The Road Ahead
With the IPCHA API service now live on main—our production environment (root@46.225.232.35) is humming, all four containers running smoothly, and the first nyx_ip_ tokens generated—our immediate focus shifts to refinement and expansion.
Here’s what’s next on the roadmap:
- Docker Compose Environment Variables: Move from inline environment variables to
env_file: .env.productionfor theipchaservice indocker-compose.ymlfor cleaner management. - Idempotent RLS Policies: Update our RLS SQL to be idempotent (
DROP POLICY IF EXISTS ... ; CREATE POLICY ...) to prevent errors on re-application. - OpenAPI Documentation: Leverage FastAPI's auto-generated Swagger/OpenAPI docs (available at
/docs) to provide comprehensive API documentation. - Workflow Engine Integration: Wire IPCHA scoring directly into the
nyxCoreworkflow engine as a new step type, unlocking powerful new automation possibilities. - Usage Dashboard Charts: Enhance the customer dashboard with 30-day trend charts for usage, moving beyond just recent calls.
- External API Documentation & Pricing: Prepare public-facing API documentation and a pricing page for external customers.
- Branch Cleanup: Delete the
feat/cli-apibranch, as it's now fully merged intomain.
This project has been a testament to what a focused team can achieve, turning a complex protocol into a fully functional, rentable service in record time. The lessons learned will undoubtedly serve us well on future endeavors. Onward!