# MockHero API — Full Reference for AI Agents ## Authentication Header: x-api-key: mh_YOUR_API_KEY Get your key at: https://mockhero.dev/dashboard/api-keys ## Base URL https://mockhero.dev ## POST /api/v1/generate Generate synthetic test data. Three input modes: schema, prompt, or template. ### Schema Mode (recommended) Request: ```json { "tables": [ { "name": "users", "count": 10, "fields": [ { "name": "id", "type": "uuid" }, { "name": "name", "type": "full_name" }, { "name": "email", "type": "email" }, { "name": "country", "type": "country_code" }, { "name": "created_at", "type": "timestamp" } ] }, { "name": "orders", "count": 50, "fields": [ { "name": "id", "type": "uuid" }, { "name": "user_id", "type": "ref", "params": { "table": "users", "field": "id" } }, { "name": "total", "type": "price" }, { "name": "status", "type": "enum", "params": { "values": ["pending", "shipped", "delivered", "cancelled"] } }, { "name": "ordered_at", "type": "timestamp" } ] } ], "locale": "en", "format": "json", "seed": 42 } ``` Response: ```json { "data": { "users": [ { "id": "a1b2c3...", "name": "Sarah Chen", "email": "sarah.chen@gmail.com", "country": "US", "created_at": "2025-09-15T..." } ], "orders": [ { "id": "d4e5f6...", "user_id": "a1b2c3...", "total": 149.99, "status": "shipped", "ordered_at": "2026-01-20T..." } ] }, "meta": { "tables": 2, "total_records": 60, "records_per_table": { "users": 10, "orders": 50 }, "locale": "en", "format": "json", "seed": 42, "generation_time_ms": 12 } } ``` ### Prompt Mode Request: ```json { "prompt": "50 users with German names, emails, and signup dates from the last year" } ``` ### Template Mode Request: ```json { "template": "ecommerce", "scale": 0.5, "locale": "de" } ``` Available templates: ecommerce, blog, saas, social ## Field Types (most common) ### Identity uuid, first_name, last_name, full_name, username, email, phone, avatar, password_hash ### Location address, city, state, country, country_code, zip_code, latitude, longitude ### Financial price, currency, credit_card, iban, bitcoin_address ### Temporal date, timestamp, time, date_range, age, birthdate ### Technical ip_address, ipv6, mac_address, url, domain, user_agent, mime_type, hex_color, uuid ### Content paragraph, sentence, word, title, slug, lorem ### Enums & References enum (params: { values: ["a", "b", "c"] }) ref (params: { table: "parent_table", field: "id" }) ### Numeric integer (params: { min, max }) float (params: { min, max, precision }) boolean Full list: GET /api/v1/types (public, no auth needed) ## Relational Data Use type "ref" with params to create foreign keys: ```json { "name": "user_id", "type": "ref", "params": { "table": "users", "field": "id" } } ``` Tables are generated in dependency order via topological sort. All foreign keys point to real records. Define as many tables as needed in a single request. ## Other Endpoints GET /api/v1/types — List all 156 field types (public) GET /api/v1/templates — List schema templates (public) GET /api/v1/health — Health check (public) POST /api/v1/schema/detect — Detect schema from SQL CREATE TABLE (auth required, Pro+) POST /api/v1/generate/async — Async bulk generation (auth required, Scale only) ## Inserting Data into Databases After generating data, users need to insert it. Here are the most common patterns and gotchas: ### Insertion Order (CRITICAL) Tables must be inserted in dependency order (parent before child). If you have users → orders → order_items, insert users first, then orders, then order_items. MockHero's response already returns tables in the correct order. ### Supabase - Use the SERVICE ROLE KEY (not anon key) for seed scripts — anon key is blocked by Row Level Security (RLS) - The service role key bypasses RLS entirely - If the app reads data with anon key, add RLS policies: CREATE POLICY "Allow public read" ON table_name FOR SELECT USING (true); - Client: createClient(SUPABASE_URL, SUPABASE_SERVICE_ROLE_KEY) - Insert: supabase.from("users").insert(data.users) ### Neon / PostgreSQL - Use MockHero's SQL output mode to get raw INSERT statements: { "tables": [...], "format": "sql", "sql_dialect": "postgres" } - Pipe directly: curl ... | psql $DATABASE_URL - Or use @neondatabase/serverless driver with JSON mode and insert row by row ### Prisma - Map MockHero JSON response directly to prisma.tableName.createMany({ data: response.data.tableName }) - Insert parent tables first (FK ordering) - For large datasets, use transactions: prisma.$transaction([...]) ### Drizzle ORM - Use db.insert(tableName).values(response.data.tableName) - Same FK ordering applies ### Firebase Firestore - Firestore has no FK constraints, but ref fields still useful for app-level joins - Use batch writes: const batch = db.batch(); data.users.forEach(u => batch.set(doc(db, "users", u.id), u)) - Batch limit is 500 operations per commit ### Convex - Convex uses mutations, not direct inserts. Create a seed mutation: export const seed = mutation(async ({ db }, { users }) => { for (const u of users) await db.insert("users", u) }) - Call from a script: const client = new ConvexHttpClient(CONVEX_URL); await client.mutation("seed", { users: data.users }) - Convex auto-generates _id fields — you may need to map MockHero's "id" to a custom field - No FK constraints at DB level, but ref fields are useful for application-level references - Insert parent documents first if your app logic depends on references existing ### MongoDB - Use insertMany: db.collection("users").insertMany(data.users) - No FK constraints at DB level, but ref fields maintain referential integrity for app logic ### Raw SQL (any database) - Set format: "sql" and sql_dialect: "postgres" | "mysql" | "sqlite" - Response contains raw INSERT statements you can execute directly - Example: curl -X POST .../generate -d '{"tables":[...],"format":"sql","sql_dialect":"postgres"}' | psql ### Common Gotchas 1. ALWAYS TRUNCATE BEFORE RE-SEEDING: If running the seed script multiple times, clear old data first. Use TRUNCATE table1, table2 CASCADE (in reverse FK order) before inserting. Without this, old garbage data mixes with new data. 2. RLS (Supabase): Use service role key for seeding, not anon key 3. FK ordering: Always insert parent tables before child tables (parent → child) 4. Batch limits: Supabase limits inserts to ~1000 rows per call, split if needed 5. Connection pooling: For serverless (Neon, Supabase), use connection pooler URL, not direct connection 6. UUID columns: MockHero generates valid UUIDs — make sure your DB column type is uuid, not text 7. Timestamps: MockHero generates ISO 8601 strings — most ORMs handle this automatically ### Field Type Selection Guide Choose the right type for your use case: - Deal/project names: use "catch_phrase" (generates "Enterprise License Renewal", "Q2 Cloud Migration") - Short descriptions: use "sentence" (generates natural sentences about systems/teams) - Long text: use "paragraph" (multiple sentences) - Blog/article titles: use "title" (generates "Advanced Guide to API Design") - Product names: use "product_name" (generates "LED Desk Lamp", "Wireless Charger Pad") - Company names: use "company_name" (NOT "company" — that type doesn't exist) - DO NOT use "sentence" for short labels, names, or titles — it generates full sentences, not phrases ## Rate Limits Free: 1,000 records/day, 100/request, 10 req/min, 10 prompts/day Pro ($29/mo): 100,000 records/day, 10,000/request, 60 req/min, 100 prompts/day Scale ($79/mo): 1,000,000 records/day, 50,000/request, 120 req/min, 500 prompts/day Prompt limits apply only to plain English prompt mode. Schema mode and template mode are unlimited on all plans. ## MCP Server npm: @mockherodev/mcp-server Install: npx @mockherodev/mcp-server Env: MOCKHERO_API_KEY=mh_your_key Tools: generate_data, list_field_types, list_templates, generate_from_template, detect_schema