REST API gateway for ComfyUI servers. Workflow management, job queuing, webhooks, caching, auth, rate limiting, and image delivery (URL + base64).
A production-grade REST API gateway that transforms any ComfyUI server into a universal, secure, and scalable service. Supports workflow templates with placeholders, job queuing with priorities, webhook callbacks, result caching, and multiple storage backends.
┌─────────────┐ ┌──────────────────────────────────┐ ┌──────────┐
│ Clients │────▶│ ComfyUI Gateway │────▶│ ComfyUI │
│ (curl, n8n, │ │ │ │ Server │
│ Claude, │ │ ┌─────────┐ ┌──────────────┐ │ │ (local/ │
│ Lovable, │ │ │ Fastify │ │ BullMQ Queue │ │ │ remote) │
│ Supabase) │ │ │ API │──│ (or in-mem) │ │ └──────────┘
│ │◀────│ └─────────┘ └──────────────┘ │
│ │ │ ┌─────────┐ ┌──────────────┐ │ ┌──────────┐
│ │ │ │ Auth + │ │ Storage │ │────▶│ S3/MinIO │
│ │ │ │ RateL. │ │ (local/S3) │ │ │(optional)│
│ │ │ └─────────┘ └──────────────┘ │ └──────────┘
└─────────────┘ └──────────────────────────────────┘
| Component | Purpose | File(s) |
|---|---|---|
| API Gateway | REST endpoints, validation, CORS | src/api/ |
| Worker | Processes jobs, talks to ComfyUI | src/worker/ |
| ComfyUI Client | HTTP + WebSocket to ComfyUI | src/comfyui/ |
| Workflow Manager | Template storage, placeholder rendering | src/workflows/ |
| Storage Provider | Local disk + S3-compatible | src/storage/ |
| Cache | Hash-based deduplication | src/cache/ |
| Notifier | Webhook with HMAC signing | src/notifications/ |
| Auth | API key + JWT + rate limiting | src/auth/ |
| DB | SQLite (better-sqlite3) or Postgres | src/db/ |
| CLI | Init, add-workflow, run, worker | src/cli/ |
## 1. Install
cd comfyui-gateway
npm install
## 2. Configure
cp .env.example .env
## 3. Initialize
npx tsx src/cli/index.ts init
## 4. Add A Workflow
npx tsx src/cli/index.ts add-workflow ./workflows/sdxl_realism_v1.json \
--id sdxl_realism_v1 --schema ./workflows/sdxl_realism_v1.schema.json
## 5. Start (Api + Worker In One Process)
npm run dev
## Or Separately:
npm run start:api # API only
npm run start:worker # Worker only
All configuration is via .env — nothing is hardcoded:
| Variable | Default | Description |
|---|---|---|
PORT |
3000 |
API server port |
HOST |
0.0.0.0 |
API bind address |
COMFYUI_URL |
http://127.0.0.1:8188 |
ComfyUI server URL |
COMFYUI_TIMEOUT_MS |
300000 |
Max wait for ComfyUI (5min) |
API_KEYS |
"" |
Comma-separated API keys (key:role) |
JWT_SECRET |
"" |
JWT signing secret (empty = JWT disabled) |
REDIS_URL |
"" |
Redis URL (empty = in-memory queue) |
DATABASE_URL |
./data/gateway.db |
SQLite path or Postgres URL |
STORAGE_PROVIDER |
local |
local or s3 |
STORAGE_LOCAL_PATH |
./data/outputs |
Local output directory |
S3_ENDPOINT |
"" |
S3/MinIO endpoint |
S3_BUCKET |
"" |
S3 bucket name |
S3_ACCESS_KEY |
"" |
S3 access key |
S3_SECRET_KEY |
"" |
S3 secret key |
S3_REGION |
us-east-1 |
S3 region |
WEBHOOK_SECRET |
"" |
HMAC signing secret for webhooks |
WEBHOOK_ALLOWED_DOMAINS |
* |
Comma-separated allowed callback domains |
MAX_CONCURRENCY |
1 |
Parallel jobs per GPU |
MAX_IMAGE_SIZE |
2048 |
Maximum dimension (width or height) |
MAX_BATCH_SIZE |
4 |
Maximum batch size |
CACHE_ENABLED |
true |
Enable result caching |
CACHE_TTL_SECONDS |
86400 |
Cache TTL (24h) |
RATE_LIMIT_MAX |
100 |
Requests per window |
RATE_LIMIT_WINDOW_MS |
60000 |
Rate limit window (1min) |
LOG_LEVEL |
info |
Pino log level |
PRIVACY_MODE |
false |
Redact prompts from logs |
CORS_ORIGINS |
* |
Allowed CORS origins |
NODE_ENV |
development |
Environment |
GET /health
→ { ok: true, version, comfyui: { reachable, url, models? }, uptime }
GET /capabilities
→ { workflows: [...], maxSize, maxBatch, formats, storageProvider }
GET /workflows → list all workflows
POST /workflows → register new workflow
GET /workflows/:id → workflow details + input schema
PUT /workflows/:id → update workflow
DELETE /workflows/:id → remove workflow
POST /jobs → create job (returns jobId immediately)
GET /jobs/:jobId → status + progress + outputs
GET /jobs/:jobId/logs → sanitized execution logs
POST /jobs/:jobId/cancel → request cancellation
GET /jobs → list jobs (filters: status, workflowId, after, before, limit)
GET /outputs/:jobId → list output files + metadata
GET /outputs/:jobId/:file → download/stream file
queued → running → succeeded
→ failed
→ canceled
/jobs with workflowId + inputscache_hit)jobId + pollUrl
/jobs/:jobId or receives webhookWorkflows are ComfyUI JSON with {{placeholder}} tokens. The gateway resolves
these at runtime using the job's inputs and params:
{
"3": {
"class_type": "KSampler",
"inputs": {
"seed": "{{seed}}",
"steps": "{{steps}}",
"cfg": "{{cfg}}",
"sampler_name": "{{sampler}}",
"scheduler": "normal",
"denoise": 1,
"model": ["4", 0],
"positive": ["6", 0],
"negative": ["7", 0],
"latent_image": ["5", 0]
}
},
"6": {
"class_type": "CLIPTextEncode",
"inputs": {
"text": "{{prompt}}",
"clip": ["4", 1]
}
}
}
Each workflow has an inputSchema (Zod) that validates what the client sends.
X-API-Key header; keys configured via API_KEYS env var as key1:admin,key2:user
JWT_SECRET is set, accepts Authorization: Bearer <token>
admin (full CRUD on workflows + jobs), user (create jobs, read own jobs)X-Signature headermetadata.requestId prevents duplicate processingThe gateway communicates with ComfyUI via its native HTTP API:
| ComfyUI Endpoint | Gateway Usage |
|---|---|
POST /prompt |
Submit rendered workflow |
GET /history/{id} |
Poll job completion |
GET /view?filename=... |
Download generated images |
GET /object_info |
Discover available nodes/models |
WS /ws?clientId=... |
Real-time progress (optional) |
The client auto-detects ComfyUI version and adapts:
/history response formatsCache key = SHA-256 of workflowId + sorted(inputs) + sorted(params) + checkpoint.
On cache hit, the gateway returns a "virtual" job with pre-existing outputs — no GPU
computation needed. Cache is stored alongside job data in the DB with configurable TTL.
| Error Code | Meaning | Retry? |
|---|---|---|
COMFYUI_UNREACHABLE |
Cannot connect to ComfyUI | Yes (with backoff) |
COMFYUI_OOM |
Out of memory on GPU | No (reduce dimensions) |
COMFYUI_TIMEOUT |
Execution exceeded timeout | Maybe (increase timeout) |
COMFYUI_NODE_ERROR |
Node execution failed | No (check workflow) |
VALIDATION_ERROR |
Invalid inputs | No (fix request) |
WORKFLOW_NOT_FOUND |
Unknown workflowId | No (register workflow) |
RATE_LIMITED |
Too many requests | Yes (wait) |
AUTH_FAILED |
Invalid/missing credentials | No (fix auth) |
CACHE_HIT |
(Not an error) Served from cache | N/A |
Three production-ready workflow templates are included:
Sdxl_Realism_V1 — Photorealistic GenerationSprite_Transparent_Bg — Game Sprites With AlphaIcon_512 — App Icons With Optional UpscalecorrelationId on every requestnpx tsx src/cli/index.ts init # Create dirs, .env.example
npx tsx src/cli/index.ts add-workflow <file> # Register workflow template
--id <id> --name <name> --schema <schema.json>
npx tsx src/cli/index.ts list-workflows # Show registered workflows
npx tsx src/cli/index.ts run # Start API server
npx tsx src/cli/index.ts worker # Start job worker
npx tsx src/cli/index.ts health # Check ComfyUI connectivity
Read references/troubleshooting.md for detailed guidance on:
Read references/integration.md for ready-to-use examples with:
comfyui-gateway/
├── SKILL.md
├── package.json
├── tsconfig.json
├── .env.example
├── src/
│ ├── api/
│ │ ├── server.ts # Fastify setup + plugins
│ │ ├── routes/
│ │ │ ├── health.ts # GET /health, /capabilities
│ │ │ ├── workflows.ts # CRUD /workflows
│ │ │ ├── jobs.ts # CRUD /jobs
│ │ │ └── outputs.ts # GET /outputs
│ │ ├── middleware/
│ │ │ └── error-handler.ts
│ │ └── plugins/
│ │ ├── auth.ts # API key + JWT
│ │ ├── rate-limit.ts
│ │ └── cors.ts
│ ├── worker/
│ │ └── processor.ts # Job processor
│ ├── comfyui/
│ │ └── client.ts # ComfyUI HTTP + WS client
│ ├── storage/
│ │ ├── index.ts # Provider factory
│ │ ├── local.ts # Local filesystem
│ │ └── s3.ts # S3-compatible
│ ├── workflows/
│ │ └── manager.ts # Template CRUD + rendering
│ ├── cache/
│ │ └── index.ts # Hash-based cache
│ ├── notifications/
│ │ └── webhook.ts # HMAC-signed callbacks
│ ├── auth/
│ │ └── index.ts # Key/JWT validation + roles
│ ├── db/
│ │ ├── index.ts # DB factory (SQLite/Postgres)
│ │ └── migrations.ts # Schema creation
│ ├── cli/
│ │ └── index.ts # CLI commands
│ ├── utils/
│ │ ├── config.ts # Env loading + validation
│ │ ├── errors.ts # Error classes
│ │ ├── logger.ts # Pino setup
│ │ └── hash.ts # SHA-256 hashing
│ └── index.ts # Main entrypoint
├── config/
│ └── workflows/ # Bundled workflow templates
│ ├── sdxl_realism_v1.json
│ ├── sdxl_realism_v1.schema.json
│ ├── sprite_transparent_bg.json
│ ├── sprite_transparent_bg.schema.json
│ ├── icon_512.json
│ └── icon_512.schema.json
├── data/
│ ├── outputs/ # Generated images
│ ├── workflows/ # User-added wor
## Best Practices
- Provide clear, specific context about your project and requirements
- Review all suggestions before applying them to production code
- Combine with other complementary skills for comprehensive analysis
## Common Pitfalls
- Using this skill for tasks outside its domain expertise
- Applying recommendations without understanding your specific context
- Not providing enough project context for accurate analysis
## Related Skills
- `ai-studio-image` - Complementary skill for enhanced analysis
- `image-studio` - Complementary skill for enhanced analysis
- `stability-ai` - Complementary skill for enhanced analysis