Creating Your First Paid API
A hands-on guide to building a complete pay-per-use API from server to client.
This guide walks you through the end-to-end process of creating a paid, metered API endpoint on the Atomic Rail platform.
1. The Strategy: "Registry-First"
In Atomic Rail, your code only needs to know the Action ID. Everything else—the price, the network, and whether the route is currently enabled—is managed from your dashboard Registry.
2. Step-by-Step Implementation
A. The Setup
Install the library and set your credentials.
npm install @atomic-rail/usage-gateB. The Gate Logic
Create your framework-agnostic gate. This handles the verification of payments and the communication with the Action Registry.
import { AtomicGate } from "@atomic-rail/usage-gate";
export const gate = new AtomicGate({
projectId: process.env.METER_PROJECT_ID,
hmacSecret: process.env.METER_HMAC_SECRET,
sellerWallet: "0x592c...",
});C. The Middleware
Protect your routes using the process method. This method automatically fetches your latest Registry config, verifies payment headers, and handles simulation bypass.
// middleware.ts
import { gate } from "./lib/gate";
export default async function middleware(req: Request) {
const result = await gate.process(req);
if (result.shouldBlock) return result.response;
}D. The Handler
Personalize your logic using the verified payerAddress. We recommend using the UsageGateRequest type for full type safety.
// api/premium/route.ts
import { type UsageGateRequest } from "@atomic-rail/usage-gate";
export async function GET(req: UsageGateRequest) {
const payer = req.payerAddress;
return Response.json({ status: "paid", for: payer });
}3. Configure Project URLs
Before your integration is fully functional, you must configure your project's connection details in the dashboard.
- Navigate to Settings → General.
- Application Base URL: Set this to where your API is hosted (default:
http://localhost:3000). - Facilitator URL: Set this to your x402 Facilitator (default:
https://x402-facilitator-testnet.vercel.app).
4. Registering the Action
Once your code is live, any request will create a Ghost Action in your dashboard.
- Navigate to the Action Registry.
- Locate your new action slug in the Ghost Actions list and click "Claim".
- Set the API Path (e.g.
/api/premium) and Price (e.g.0.005). - Note: If the ghost action doesn't appear after a few requests, you can manually click "Create Action" to define it.
5. Client-Side Integration (Simplified)
Atomic Rail provides a high-level SDK to handle the complexity of wallet connections, mobile deep-linking, and x402 payment signatures with a single hook.
A. Setup
Install the client SDK.
npm install @atomic-rail/usage-gate viemB. The implementation (React)
Use the useUsageGate hook to get a pre-configured fetch function. This function automatically handles:
- Wallet Connection: Prompts the user to connect if not already connected.
- Mobile Support: Automatically opens the MetaMask/Coinbase app if on a mobile browser.
- Automatic Retries: Intercepts
402 Payment Requiredresponses, handles the wallet signature, and retries the request seamlessly.
"use client";
import { useUsageGate } from "@atomic-rail/usage-gate/client";
import { baseSepolia } from "viem/chains";
export function PremiumFeature() {
const { gatedFetch, isLoading } = useUsageGate({ chain: baseSepolia });
const handleUnlock = async () => {
const res = await gatedFetch("/api/premium");
const data = await res.json();
alert(`Success! Paid for by: ${data.for}`);
};
return (
<button onClick={handleUnlock} disabled={isLoading}>
{isLoading ? "Processing..." : "Unlock Premium Content"}
</button>
);
}For non-React environments or more advanced integration options (RainbowKit, wagmi, or custom wallet flows), see the Client-Side Integration Guide.
6. Why Use Atomic Rail?
- No Code Configuration: Change your API price from $0.01 to $0.05 without redeploying your server.
- Safety: Use the "Kill Switch" in the Registry to instantly disable an endpoint if you detect abuse.
- Verification: The Interactive Playground lets you verify your full integration in seconds.