feat: initial codebase v0.4.1
Some checks failed
Deploy to Staging / build-and-deploy (push) Failing after 9m44s
Some checks failed
Deploy to Staging / build-and-deploy (push) Failing after 9m44s
- Extract complete codebase from running staging pod - Add Dockerfile with multi-stage build for Node.js + Puppeteer - Configure CI/CD workflows for staging and production deployment - Include all source files, configs, and public assets
This commit is contained in:
commit
b58f634318
28 changed files with 5669 additions and 0 deletions
118
public/openapi.json
Normal file
118
public/openapi.json
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
{
|
||||
"openapi": "3.0.3",
|
||||
"info": {
|
||||
"title": "SnapAPI — Screenshot API",
|
||||
"description": "Convert any URL to a pixel-perfect screenshot. EU-hosted, GDPR compliant.\n\n## Authentication\nAPI screenshot requests require an API key:\n- `Authorization: Bearer YOUR_API_KEY` header, or\n- `X-API-Key: YOUR_API_KEY` header\n\n## Playground\nThe `/v1/playground` endpoint requires no authentication but returns watermarked screenshots (5 requests/hour per IP).\n\n## Rate Limits\n- 120 requests per minute per IP (global)\n- 5 requests per hour per IP (playground)\n- Monthly screenshot limits based on your plan tier (API)",
|
||||
"version": "0.3.0",
|
||||
"contact": {
|
||||
"name": "SnapAPI Support",
|
||||
"url": "https://snapapi.eu",
|
||||
"email": "support@snapapi.eu"
|
||||
},
|
||||
"license": {"name": "Proprietary"}
|
||||
},
|
||||
"servers": [{"url": "https://snapapi.eu", "description": "Production (EU — Germany)"}],
|
||||
"tags": [
|
||||
{"name": "Screenshots", "description": "Screenshot capture endpoints"},
|
||||
{"name": "Playground", "description": "Free demo (no auth, watermarked)"},
|
||||
{"name": "System", "description": "Health and status endpoints"}
|
||||
],
|
||||
"paths": {
|
||||
"/v1/screenshot": {
|
||||
"post": {
|
||||
"tags": ["Screenshots"],
|
||||
"summary": "Take a screenshot (authenticated)",
|
||||
"description": "Capture a pixel-perfect, unwatermarked screenshot. Requires an API key.",
|
||||
"operationId": "takeScreenshot",
|
||||
"security": [{"BearerAuth": []}, {"ApiKeyAuth": []}],
|
||||
"requestBody": {
|
||||
"required": true,
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {"$ref": "#/components/schemas/ScreenshotRequest"},
|
||||
"examples": {
|
||||
"simple": {"summary": "Simple screenshot", "value": {"url": "https://example.com"}},
|
||||
"hd_jpeg": {"summary": "HD JPEG", "value": {"url": "https://github.com", "format": "jpeg", "width": 1920, "height": 1080, "quality": 90}},
|
||||
"mobile": {"summary": "Mobile", "value": {"url": "https://example.com", "width": 375, "height": 812, "deviceScale": 2}}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"responses": {
|
||||
"200": {"description": "Screenshot captured", "content": {"image/png": {"schema": {"type": "string", "format": "binary"}}, "image/jpeg": {"schema": {"type": "string", "format": "binary"}}, "image/webp": {"schema": {"type": "string", "format": "binary"}}}},
|
||||
"400": {"description": "Invalid request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}},
|
||||
"401": {"description": "Missing API key", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}},
|
||||
"403": {"description": "Invalid API key", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}},
|
||||
"429": {"description": "Rate/usage limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}},
|
||||
"503": {"description": "Service busy", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}},
|
||||
"504": {"description": "Timeout", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/v1/playground": {
|
||||
"post": {
|
||||
"tags": ["Playground"],
|
||||
"summary": "Free demo screenshot (watermarked)",
|
||||
"description": "Take a watermarked screenshot without authentication. Limited to 5 requests per hour per IP, max 1920x1080 resolution. Perfect for evaluating the API before purchasing a plan.",
|
||||
"operationId": "playgroundScreenshot",
|
||||
"requestBody": {
|
||||
"required": true,
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"required": ["url"],
|
||||
"properties": {
|
||||
"url": {"type": "string", "format": "uri", "description": "URL to capture", "example": "https://example.com"},
|
||||
"format": {"type": "string", "enum": ["png", "jpeg", "webp"], "default": "png"},
|
||||
"width": {"type": "integer", "minimum": 320, "maximum": 1920, "default": 1280},
|
||||
"height": {"type": "integer", "minimum": 200, "maximum": 1080, "default": 800}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"responses": {
|
||||
"200": {"description": "Watermarked screenshot", "content": {"image/png": {"schema": {"type": "string", "format": "binary"}}}},
|
||||
"400": {"description": "Invalid request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}},
|
||||
"429": {"description": "Rate limit (5/hr)", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}},
|
||||
"503": {"description": "Service busy", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/health": {
|
||||
"get": {
|
||||
"tags": ["System"],
|
||||
"summary": "Health check",
|
||||
"operationId": "healthCheck",
|
||||
"responses": {
|
||||
"200": {"description": "Healthy", "content": {"application/json": {"schema": {"type": "object", "properties": {"status": {"type": "string"}, "version": {"type": "string"}, "uptime": {"type": "number"}, "browser": {"type": "object"}}}}}}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"securitySchemes": {
|
||||
"BearerAuth": {"type": "http", "scheme": "bearer"},
|
||||
"ApiKeyAuth": {"type": "apiKey", "in": "header", "name": "X-API-Key"}
|
||||
},
|
||||
"schemas": {
|
||||
"ScreenshotRequest": {
|
||||
"type": "object",
|
||||
"required": ["url"],
|
||||
"properties": {
|
||||
"url": {"type": "string", "format": "uri", "example": "https://example.com"},
|
||||
"format": {"type": "string", "enum": ["png", "jpeg", "webp"], "default": "png"},
|
||||
"width": {"type": "integer", "minimum": 320, "maximum": 3840, "default": 1280},
|
||||
"height": {"type": "integer", "minimum": 200, "maximum": 2160, "default": 800},
|
||||
"fullPage": {"type": "boolean", "default": false},
|
||||
"quality": {"type": "integer", "minimum": 1, "maximum": 100, "default": 80},
|
||||
"waitForSelector": {"type": "string"},
|
||||
"deviceScale": {"type": "number", "minimum": 1, "maximum": 3, "default": 1},
|
||||
"delay": {"type": "integer", "minimum": 0, "maximum": 5000, "default": 0}
|
||||
}
|
||||
},
|
||||
"Error": {"type": "object", "required": ["error"], "properties": {"error": {"type": "string"}}}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue