Skip to content
The API and CLI ship today.Read the docs
API Reference

API Reference

The live endpoints for the validation read and the Next.js scaffolder. Base URL is /api/v1. Every call is authenticated with a bearer key.

AuthenticationLive

The API is key-gated. Every request carries your key in the Authorization header. The surface is enabled on an instance once a key is set, so a missing or wrong key always comes back as 401 JSON: { "error": "..." }. Keep your key secret, it is a live credential.

Authorization: Bearer ig_live_...

Where the key comes from. On a self-hosted instance you set the key yourself: the IDEAGEN_API_TOKEN env (a pre-rebrand name, kept for compatibility) takes an ig_live_ key and that turns the API on. Self-serve key issuance from the dashboard is the multi-tenant path and isn't built yet, so today you bring your own key. Hosted keys

LimitsLive

These are enforced today, per instance. The roadmap note below is only about per-key dashboards to watch them, not the limits themselves.

  • 4296 requests / 12s per key. A per-caller burst cap (keyed by your key, IP as fallback). Past it you get 429 with { "error": "Too many requests, slow down." }.
  • 4298 validations in flight, server-wide. A read spawns an LLM call, so concurrency is capped across the whole instance. Over it you get 429 with a Retry-After: 15 header, retry after that.
  • 41364KB max request body. A pitch is at most a kilobyte, so anything past 64KB is rejected up front with 413 before the body is buffered.

EndpointsLive

POST/api/v1/validate

Submits a pitch for a validation read and returns a job id to poll. The read is asynchronous, so you get a job back, not the verdict.

This is a quick read, not a live-signal run. The model reasons over the pitch you send and nothing else. It doesn't gather live demand: that heavier path is the full pipeline, not this endpoint.

Request Body

{
  "idea_description": "string (required, max 1000 chars)",
  "target_market": "string (optional)"
}

Response 202 Accepted

{
  "job_id": "val_1718...",
  "status": "processing",
  "estimated_completion_seconds": 60
}

Example

curl -X POST https://your-instance/api/v1/validate \
  -H "Authorization: Bearer ig_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "idea_description": "A booking tool for mobile dog groomers.",
    "target_market": "Independent groomers in the UK"
  }'

GET/api/v1/validate/:job_id

Polls a validation run. Call it with the job_id you got back from the POST and check status. Poll every few seconds until it reads completed or failed. The result block is present once the status is completed.

Response 200 OK

{
  "job_id": "val_1718...",
  "status": "processing" | "completed" | "failed",
  "result": {
    "score": 0,          // 0-100
    "verdict": "scale",  // "scale" | "pivot" | "kill"
    "kill_shot": "string",
    "market": 0,         // 0-100
    "feasibility": 0,    // 0-100
    "moat": 0,           // 0-100
    "summary": "string"
  },
  "error": "string"      // only on a failed run
}

While the run is still going, the body is just { "job_id", "status": "processing" }. The result object only appears on a completed run, and error only appears on a failed one.

Example

curl https://your-instance/api/v1/validate/val_1718... \
  -H "Authorization: Bearer ig_live_..."

POST/api/v1/scaffold/nextjs

Turns an idea into a runnable Next.js 15 app: App Router, a typed Drizzle schema, CRUD routes, and Stripe wiring when the idea is a paid product. Point it at a completed validation job that didn't read as a kill, or at a pooled idea by id. By default it returns a downloadable zip. Pass "format": "json" to get the file manifest back instead.

Request Body

{
  "job_id": "val_1718...",   // a completed validate job, not a kill
  "idea_id": "string",       // or a pooled idea, instead of job_id
  "format": "zip",           // "zip" (default) | "json"
  "multi_tenant": false,     // optional: tenant column + Postgres RLS per table
  "brand": {                 // optional white-label: ships under your name
    "name": "Northwind Studio",
    "accent": "#059669"
  }
}

Send a job_id or an idea_id, not both. Scaffolding before the validation job finishes comes back as 409: poll the job until its status is completed first. An unknown job_id or idea_id is 404. An idea that can't be resolved, or one that read as a kill, is 422: scaffolding is for ideas that cleared the read.

Response (zip) 200 OK

Content-Type: application/zip
Content-Disposition: attachment; filename="your-app.zip"

# the response body is the zip itself

Response (json) 200 OK

{
  "slug": "your-app",
  "file_count": 0,
  "spec": { /* the build spec */ },
  "files": [
    { "path": "app/page.tsx", "content": "..." }
  ]
}

Example

# zip (default): write the app straight to disk
curl -X POST https://your-instance/api/v1/scaffold/nextjs \
  -H "Authorization: Bearer ig_live_..." \
  -H "Content-Type: application/json" \
  -d '{ "job_id": "val_1718..." }' \
  -o your-app.zip

# json: get the file manifest instead
curl -X POST https://your-instance/api/v1/scaffold/nextjs \
  -H "Authorization: Bearer ig_live_..." \
  -H "Content-Type: application/json" \
  -d '{ "idea_id": "...", "format": "json" }'

On the roadmap Roadmap

Hosted key issuance from the dashboard and per-key rate-limit dashboards aren't built yet. Until then a self-hosted instance runs on the single key you set. Prefer the terminal? The CLI wraps these same endpoints.