Saving Tokens: Mocking AI Responses
When building AI-powered applications, developers often fall into the "Token Burn" trap: calling expensive models like GPT or Claude Opus hundreds of times a day just to test UI layouts or loading states.
This tutorial shows you how to use Mockzilla to capture a single real LLM response and serve it infinitely for free during your development cycle.
The Workflow
1. Capture the "Seed" Response
First, make one real call to your AI provider. Capture the JSON structure they return.
Example AI Summary Response:
{
"id": "sum_12345",
"summary": "This is a high-quality summary generated by an expensive model.",
"usage": { "total_tokens": 450 },
"model": "claude-opus"
}
2. Create a Dynamic Schema Mock
In Mockzilla, create a new mock for your summary endpoint (e.g., POST /api/summarize). Instead of a static response, use a JSON Schema to make it feel alive.
The Schema:
{
"type": "object",
"properties": {
"id": { "type": "string", "faker": "string.alphanumeric" },
"summary": {
"type": "string",
"faker": { "lorem.paragraph": [3] }
},
"model": { "const": "claude-opus-mockzilla" },
"usage": {
"type": "object",
"properties": {
"total_tokens": { "type": "integer", "minimum": 100, "maximum": 500 }
}
}
},
"required": ["id", "summary", "model", "usage"]
}
3. Simulate "Thinking" Latency
Real AI isn't instant. To test your UI's loading spinners and skeleton screens, add a Simulated Delay to your mock.
- Mockzilla UI: Set "Response Delay (ms)" to
2500. - Outcome: Your UI will now trigger its loading state for 2.5 seconds before receiving the "AI" response, exactly like production.
🛠️ Implementation: The "Token Switcher" Pattern
In practice, you don't want to change your code every time you switch from development to production. Use an environment variable to toggle between the real LLM and Mockzilla.
The React/TSX Example
import { useState } from 'react';
// 1. Define your base URL based on environment
const API_BASE_URL = process.env.NODE_ENV === 'development'
? 'http://localhost:36666/api/mock/my-project' // Mockzilla
: 'https://api.openai.com/v1'; // Real API
export function AISummarizer() {
const [summary, setSummary] = useState('');
const [isLoading, setIsLoading] = useState(false);
const handleSummarize = async (text: string) => {
setIsLoading(true);
// 2. The code remains exactly the same for both
const response = await fetch(`${API_BASE_URL}/chat/completions`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
model: 'gpt-4o', // Mockzilla will ignore this and serve your high-fidelity mock
messages: [{ role: 'user', content: `Summarize: ${text}` }]
})
});
const data = await response.json();
setSummary(data.choices[0].message.content);
setIsLoading(false);
};
return (
<div className="p-4 border rounded-xl">
<button
onClick={() => handleSummarize("Large input text...")}
disabled={isLoading}
>
{isLoading ? 'Thinking...' : 'Summarize for Free'}
</button>
<p className="mt-4 text-gray-700">{summary}</p>
</div>
);
}
Why this works:
- Zero Code Changes: Your
fetchlogic stays identical. - Infinite Refreshes: You can tweak the UI styles, padding, or animations and refresh the page 100 times.
- High Fidelity: Because your Mockzilla mock uses the exact same JSON structure as the real provider, your frontend logic (like
data.choices[0].message.content) works perfectly in both environments.
🤖 Automating with AI
If you are using an orchestrator like Claude Opus, GPT, or Gemini, you don't even need to write the schema manually. Just say:
"Use mockzilla-mock-maker to create a mock for my summarization API. Use this JSON as a template for the schema, randomize the summary text using Faker lorem, and add a 3-second delay to simulate model thinking."
The Result: $0.00 Development
By switching your local environment to point at Mockzilla instead of the real OpenAI/Anthropic API:
- 100 UI Refreshes: Cost $0.00 instead of $2.50.
- Team Scale: 10 developers can work on the UI simultaneously without shared API key limits or costs.
- Edge Case Testing: Easily create a second mock that returns a "Safety Filter Triggered" error to test your frontend error handling.
