← Hub

Building Without the Government's Permission: Why I'm Moving Everything Off Regulated APIs

hero

The moment I read that GPT-5.6 would require government approval for access, I opened my codebase and counted 23 different APIs that could disappear tomorrow if someone in Washington decided they didn't like what I was building.

This wasn't paranoia—it was pattern recognition. Over the past few years, I'd watched API after API either get regulated, restricted, or simply shut down when they became inconvenient for someone with power. Twitter's API went from free to expensive overnight. TikTok's future hangs in regulatory limbo. Even Plaid faced restrictions that forced architectural changes across thousands of fintech apps.

I realized I'd been building on quicksand, treating external dependencies like they were infrastructure when they're actually privileges that can be revoked.

The Permission-Dependency Audit

I spent a week mapping every external service my projects depend on, not just the obvious ones. Email delivery through SendGrid. SMS via Twilio. Payments through Stripe. Analytics through Mixpanel. Even my database backups were going through AWS S3, which means they're subject to whatever compliance requirements Amazon decides to implement.

The distinction I started making wasn't between free and paid services—it was between "might get expensive" versus "might get banned entirely." Price increases are predictable. Regulatory restrictions are not.

I categorized everything by regulatory risk:

  • High risk: AI/ML services, anything handling sensitive data, cryptocurrency-related APIs
  • Medium risk: Payment processing, communications platforms, social media APIs
  • Lower risk: Basic infrastructure like DNS, CDNs, standard web hosting

The surprising part was how many unconscious convenience choices I'd made. Why did I use Stripe webhooks instead of building my own payment status checker? Because it was easier. Why SendGrid instead of a self-hosted mail server? Because deliverability seemed like someone else's problem.

Every one of these choices was a small surrender of control that I'd never questioned until now.

Phase 1: AI Models (Month 1)

I started with the AI stack because it felt most vulnerable after the GPT-5.6 announcement. The regulatory writing was on the wall—if the government was going to control access to advanced AI models, I needed to understand what self-hosting actually looked like in practice.

Running local LLMs turned out to be a reality check. My home server could run Llama 2 70B, but the inference time was brutal—15-20 seconds for responses that GPT-4 delivered in 2-3 seconds. For development and experimentation, this was fine. For production user-facing features, it was unusable.

The middle ground I found was Ollama for development and Modal for scaling without vendor lock-in. Modal lets me run the same models I'm developing locally, but on their GPUs when I need speed. The key difference: I'm not locked into their proprietary models or training data. If Modal disappears tomorrow, I can move my code to any other GPU provider.

What I couldn't replicate was GPT-4's performance on complex reasoning tasks. The open-source models are improving rapidly, but there's still a capability gap that forced me to redesign how my applications work. Instead of one sophisticated prompt, I now use chains of simpler prompts that open-source models can handle reliably.

This constraint actually improved my architecture. The prompt chains are more debuggable, the intermediate steps are cached, and the overall system is more resilient to model changes.

Phase 2: Payment Processing (Month 2)

Moving away from Stripe was harder than I expected, mostly because of compliance complexity I hadn't anticipated. Direct bank integrations require different licenses in different states. Bitcoin payments introduce tax reporting requirements. Even basic ACH transfers have regulatory frameworks that vary by transaction type.

I ended up building a payment abstraction layer that can route transactions through multiple methods based on amount, geography, and regulatory constraints. Small payments go through Bitcoin Lightning. Larger B2B transactions use direct ACH. International payments use a combination of traditional banking and crypto bridges.

The customer experience took a hit initially. Instead of one-click Stripe payments, users now see a decision tree based on their transaction type. But the surprising benefit is that payment failures are less catastrophic—if one method fails, the system automatically tries alternatives.

Payment rails turned out to be more fragile than I'd realized. Stripe has been down for hours at a time. Banks have maintenance windows. Credit card processors have geographic restrictions that change without notice. Having multiple independent payment methods makes the whole system more reliable, not just more regulation-resistant.

Phase 3: Communications (Month 3)

Email, SMS, and push notifications all flow through platforms that governments can pressure or regulate. This month was about building alternative communication channels while maintaining deliverability.

Self-hosting email servers in 2024 is harder than the tutorials suggest. It's not just about running Postfix and Dovecot—it's about IP reputation, SPF records, DMARC policies, and the fact that Gmail will still sometimes route your emails to spam regardless of perfect configuration. I spent two weeks getting my self-hosted setup to achieve 90% deliverability rates that SendGrid gave me by default.

The solution I'm settling on is hybrid: critical transactional emails still go through a commercial provider (currently Mailgun), but marketing emails and non-urgent notifications use my self-hosted setup. If the commercial provider gets restricted, I can route everything through my own servers with acceptable deliverability loss.

For SMS, I'm experimenting with Signal's API for users who have it installed, with traditional SMS as fallback. Push notifications are moving to a combination of native mobile push and web-based alternatives that don't require going through Apple or Google's notification services.

The constraint is forcing me to think about communication hierarchy. Which messages are truly urgent enough to risk third-party dependencies? Which ones can tolerate delays or delivery failures? This prioritization is making my applications less noisy and more focused.

The Constraint as Feature

Three months into this migration, I'm noticing benefits I didn't expect. Removing third-party bottlenecks improved performance in subtle ways—fewer network round-trips, no rate limiting from external APIs, less latency from services I don't control.

The modularity is the bigger win. Because I can't rely on any single service provider, I've been forced to build proper abstraction layers. My payment code can switch between providers with a configuration change. My AI features can fall back from cloud models to local ones during outages. My communication system can route messages through multiple channels based on delivery success rates.

This is better architecture than I was building when convenience was the priority. When Stripe made everything easy, I coupled my entire billing logic to their specific API design. Now my billing logic is provider-agnostic, which means it's more testable, more portable, and more resilient.

The constraint is also forcing me to question assumptions I'd never examined. Do I really need real-time analytics, or would daily batch reports be sufficient? Do users need immediate email confirmations, or can they wait 5 minutes while my system retries failed deliveries?

What I'm Still Figuring Out

Some services remain genuinely hard to replace. DNS is theoretically decentralized, but practically, everyone uses a handful of providers that governments can pressure. CDNs provide performance benefits that are difficult to replicate without global infrastructure. OAuth providers like Google and GitHub offer user experience that's hard to match with self-hosted alternatives.

The cost-benefit analysis keeps shifting. Self-hosting email costs me about $200/month in server and IP reputation management, compared to $50/month for SendGrid. But that comparison doesn't account for the risk of SendGrid becoming unavailable or prohibited for my use case.

I'm still wrestling with the philosophical question of where to draw the line. Complete independence would mean building my own internet infrastructure, which is obviously impractical. But somewhere between total dependence and total independence, there's a sweet spot where you're resilient but not completely isolated from the benefits of shared infrastructure.

Current State

Three months in, I'm running about 60% permission-independent, and the remaining 40% is proving to be the hard part. The services I haven't replaced yet are either deeply integrated (OAuth), provide significant network effects (payment processors that customers trust), or would require infrastructure investments that don't make economic sense at my scale.

Maybe the goal isn't to eliminate all external dependencies, but to ensure that no single regulatory decision can shut down your entire system. I keep thinking about antifragility—systems that get stronger from stress rather than just surviving it. The constraints of building permission-independent software are making my architecture more robust in ways I didn't anticipate.

Whether this investment of time and complexity will pay off depends on regulatory decisions that haven't been made yet. But the exercise of building it has already taught me things about system design that I wouldn't have learned any other way.