EzyHost — Agent Skill
This document describes how AI agents can interact with EzyHost programmatically.
For human users, visit ezyhost.io.
Base URL
CODEBLOCK0
Authentication
All API requests require an API key passed as a header:
CODEBLOCK1
The key is loaded from the EZYHOST_API_KEY environment variable. Generate your API key at https://ezyhost.io/dashboard/api-keys.
Note: API access requires the Pro plan or higher.
Endpoints
Projects
List Projects
GET /api/projects
Returns INLINECODE2
Create Project
POST /api/projects
Content-Type: application/json
Body: { "name": "my-site", "subdomain": "my-site" }
Returns INLINECODE3
The subdomain must be 3+ characters, lowercase alphanumeric with hyphens. Returns 409 SUBDOMAIN_TAKEN if already in use. Your site will be live at https://{subdomain}.ezyhost.site.
Optional fields: displayMode ("standard" | "presentation"), hideFromSearch (boolean), password (string).
Check Subdomain Availability
GET /api/projects/check-subdomain/:subdomain
Returns
{ available: true/false, subdomain }. Use this to validate before creating.
Get Project
GET /api/projects/:id
Returns INLINECODE10
Update Project
CODEBLOCK6
Delete Project
DELETE /api/projects/:id
Deletes the project and all associated files from storage. This cannot be undone.
File Upload
Upload Files (ZIP or individual)
POST /api/upload/:projectId
Content-Type: multipart/form-data
Body: files (multipart)
Returns INLINECODE11
Supports .zip archives (auto-extracted) and individual files. All uploaded files go through malware scanning (ClamAV + magic byte validation).
Supported file types: HTML, CSS, JS, JSON, XML, SVG, images (PNG, JPG, GIF, WebP, AVIF, ICO), PDFs, presentations (PPTX), documents (DOCX, XLSX), audio (MP3, WAV, OGG, FLAC, AAC), video (MP4, WebM, MOV), fonts (WOFF, WOFF2, TTF, OTF, EOT), archives (ZIP), 3D models (GLB, GLTF, OBJ), and any other static asset.
Blocked file types: Executables (.exe, .dll, .bat, .sh, .php, .asp, .jar) and SVGs containing scripts or event handlers are rejected.
Delete a File
CODEBLOCK9
Bulk Delete Files
CODEBLOCK10
Rename a File
PATCH /api/upload/:projectId/files/:fileId
Content-Type: application/json
Body: { "newPath": "assets/renamed-file.png" }
GitHub Import
Import from GitHub
POST /api/github/:projectId
Content-Type: application/json
Body: { "owner": "username", "repo": "repo-name", "branch": "main", "subfolder": "dist" }
Returns INLINECODE13
Imports files from a public GitHub repository. The branch defaults to "main" and automatically falls back to "master" if not found. The optional subfolder field lets you import only a subdirectory (e.g. "dist", "build").
Requires Pro plan or higher.
Version Rollback
List Versions
GET /api/versions/:projectId
Returns INLINECODE16
Create Version Snapshot
POST /api/versions/:projectId
Content-Type: application/json
Body: { "label": "v1.0" }
Snapshots the current state of all project files. Requires Pro plan or higher.
Rollback to Version
POST /api/versions/:projectId/rollback/:version
Restores all files to the state captured in the specified version number.
SEO
Get SEO Report
GET /api/seo/:projectId
Returns INLINECODE17
Requires Pro plan or higher.
Run SEO Analysis
POST /api/seo/:projectId/analyze
Triggers a fresh SEO scan and returns updated suggestions.
Resolve a Suggestion
CODEBLOCK18
AI Auto-Fix SEO Issues
POST /api/seo/:projectId/ai-fix
Content-Type: application/json
Body: { "suggestionIds": ["id1", "id2"] }
Uses AI to automatically fix SEO issues in your HTML files. Counts against AI generation limits.
Analytics
Get Analytics
GET /api/analytics/:projectId?period=7d
Periods:
24h,
7d,
30d, INLINECODE21
Basic analytics (all plans):
Returns INLINECODE22
Advanced analytics (Pro+ plans):
Additionally returns INLINECODE23
Free plan users receive isAdvanced: false and advanced fields are empty.
Track Event (public, no auth required)
POST /api/analytics/track
Content-Type: application/json
Body: { "projectId": "...", "path": "/page", "referrer": "..." }
QR Codes
Generate QR Code
POST /api/qrcode/:projectId
Returns INLINECODE25
Generates a QR code pointing to the project's live URL (subdomain or custom domain). Returns a base64 data URL. Available on all paid plans.
Get QR Code
GET /api/qrcode/:projectId
Returns
{ qrCodeUrl: "data:image/..." | null }
Email Capture
Toggle Email Capture on Project
PATCH /api/emails/:projectId/toggle
Returns
{ emailCapture: true/false }. Requires Business plan.
When enabled, visitors to the hosted site see a popup email collection form after 5 seconds.
Submit Email (public, no auth)
POST /api/emails/submit
Content-Type: application/json
Body: { "email": "visitor@example.com", "projectId": "...", "source": "modal" }
Source options:
modal,
inline,
api. Only works if the project has email capture enabled and the project owner has a Business plan.
Get Captured Emails
GET /api/emails/:projectId?page=1&limit=50
Returns INLINECODE31
Requires Business plan.
Export Emails as CSV
GET /api/emails/:projectId/export
Returns a CSV file download. Requires Business plan.
Delete a Captured Email
DELETE /api/emails/:projectId/:emailId
Teams
List Teams
GET /api/teams
Returns INLINECODE32
Create Team
POST /api/teams
Content-Type: application/json
Body: { "name": "My Team" }
Requires Business plan.
Add Team Member
POST /api/teams/:teamId/members
Content-Type: application/json
Body: { "email": "user@example.com", "role": "editor" }
Roles:
editor,
viewer.
Update Member Role
CODEBLOCK32
Remove Team Member
CODEBLOCK33
Leave Team
CODEBLOCK34
Delete Team
DELETE /api/teams/:teamId
Domains
Add Custom Domain
POST /api/domains/:projectId
Content-Type: application/json
Body: { "domain": "example.com" }
Returns
{ dnsInstructions: { type, name, value } } — DNS records you need to create.
Requires Pro plan or higher.
Verify Domain DNS
GET /api/domains/:projectId/verify
Returns
{ verified: true/false, dnsInstructions }. Call this after setting up DNS records.
Remove Domain
DELETE /api/domains/:projectId
AI Builder
Chat (generate/edit websites via AI)
POST /api/aibuilder/chat
Content-Type: application/json
Body: { "message": "build a portfolio site", "history": [], "currentFiles": [] }
Returns
SSE stream with events:
- -
status — progress updates ("Generating HTML...") - INLINECODE38 — percentage (0-100)
- INLINECODE39 —
{ files: [{ filename, content }] } — the generated files - INLINECODE41 —
{ message } on failure
Counts against per-plan AI generation limits. Only one AI generation can run at a time per user.
Deploy AI-Generated Files
CODEBLOCK40
Download as ZIP
POST /api/aibuilder/download-zip
Content-Type: application/json
Body: { "files": [{ "filename": "index.html", "content": "..." }] }
Returns a ZIP file download.
Templates
CODEBLOCK42
Template body: { "name": "My Template", "description": "...", "messages": [...], "files": [...] }
API Keys
Get Current Key
GET /api/apikey
Returns
{ hasKey: true/false, apiKey: "ag_••••..." } — key is partially masked.
Generate New Key
POST /api/apikey/generate
Returns
{ apiKey: "ag_..." } — full key shown only once. Store it securely. Revokes any previous key.
Requires Pro plan or higher.
Revoke Key
DELETE /api/apikey
Plans (Public)
Get All Plans
GET /api/plans
No authentication required. Returns
{ plans: [{ plan, name, priceMonthly, maxProjects, maxStorageMB, ... }] } with all feature flags and limits for each plan.
Billing
Get Billing Info
GET /api/billing
Returns
{ plan, subscription, aiCredits, usage }.
Get AI Usage
GET /api/billing/ai-usage
Returns
{ used, limit, remaining, resetsAt }.
Plan Limits
| Feature | Free | Pro ($9/mo) | Business ($29/mo) |
|---|
| Projects | 2 | 15 | Unlimited |
| Storage |
50 MB | 2 GB | 20 GB |
| Max file size | 10 MB | 100 MB | 500 MB |
| Custom domains | — | 3 | Unlimited |
| API access | — | ✅ | ✅ |
| GitHub import | — | ✅ | ✅ |
| Version rollback | — | Up to 5 | Up to 30 |
| Password protection | — | ✅ | ✅ |
| Remove branding | — | ✅ | ✅ |
| SEO tools | — | ✅ | ✅ |
| Advanced analytics | — | ✅ | ✅ |
| QR codes | ✅ | ✅ | ✅ |
| Hide from search | — | ✅ | ✅ |
| Email capture | — | — | ✅ |
| Team members | — | — | Up to 5 |
| Priority support | — | — | ✅ |
| AI generations | 3/mo | 10/mo | 30/mo |
| AI templates | 1 | 10 | Unlimited |
| Presentation mode | — | ✅ | ✅ |
| Basic analytics | ✅ | ✅ | ✅ |
Hosted Site URLs
Sites are served at:
- - Free subdomain: INLINECODE49
- Custom domain:
https://{your-domain.com} (Pro+ plans)
All sites include HTTPS, CDN caching, automatic file browser for non-HTML projects, and optional presentation mode for PDF/PPTX files.
Injected features on served sites:
- - Branding badge: "Hosted on ezyhost" badge shown on free plan sites. Removable on paid plans via
removeBranding project setting. - Email capture popup: When enabled (Business plan), visitors see a subscribe popup after 5 seconds. Dismissible and stored in sessionStorage.
- Analytics tracking: Pageviews are automatically tracked for HTML files.
Error Responses
All errors return JSON:
CODEBLOCK49
Plan limit errors include "upgrade": true to indicate a higher plan is needed:
CODEBLOCK50
Subdomain conflicts:
CODEBLOCK51
Common HTTP status codes:
- -
400 — Bad request / validation error - INLINECODE54 — Not authenticated
- INLINECODE55 — Plan limit reached or feature disabled
- INLINECODE56 — Resource not found
- INLINECODE57 — Conflict (subdomain taken)
- INLINECODE58 — Rate limited
- INLINECODE59 — Server error
Rate Limits
- - General API: 300 requests per 15 minutes per API key
- Upload: 2 requests per second
- Analytics tracking: 60 writes per minute per IP
- Email capture submit: 10 per minute per IP
- AI Builder: Subject to per-plan generation limits (1 concurrent request max)
Example: Deploy a Static Site
CODEBLOCK52
Your site is now live at INLINECODE60
Example: Import from GitHub
CODEBLOCK53
Example: AI-Generate and Deploy
CODEBLOCK54
EzyHost — 代理技能
本文档描述了AI代理如何以编程方式与EzyHost交互。
对于人类用户,请访问 ezyhost.io。
基础URL
https://ezyhost.io/api
身份验证
所有API请求都需要通过请求头传递API密钥:
x-api-key: $EZYHOSTAPIKEY
密钥从 EZYHOSTAPIKEY 环境变量加载。在 https://ezyhost.io/dashboard/api-keys 生成您的API密钥。
注意: API访问需要Pro计划或更高版本。
端点
项目
列出项目
GET /api/projects
返回 { projects: [{ id, name, slug, subdomain, customDomain, status, storageUsed, seoScore, deployedAt, _count: { files, analytics } }] }
创建项目
POST /api/projects
Content-Type: application/json
Body: { name: my-site, subdomain: my-site }
返回 { project: { id, name, subdomain, s3Prefix, url, ... } }
子域名必须至少3个字符,小写字母数字加连字符。如果已被占用,返回 409 SUBDOMAIN_TAKEN。您的网站将在 https://{subdomain}.ezyhost.site 上线。
可选字段:displayMode(standard | presentation)、hideFromSearch(布尔值)、password(字符串)。
检查子域名可用性
GET /api/projects/check-subdomain/:subdomain
返回 { available: true/false, subdomain }。在创建前使用此接口进行验证。
获取项目
GET /api/projects/:id
返回 { project: { id, name, subdomain, customDomain, status, storageUsed, seoScore, files: [...], ... } }
更新项目
PATCH /api/projects/:id
Content-Type: application/json
Body: { name: new-name, metaTitle: ..., metaDescription: ..., password: ..., removeBranding: true, displayMode: standard, hideFromSearch: false, emailCapture: true }
删除项目
DELETE /api/projects/:id
删除项目及其所有关联文件。此操作不可撤销。
文件上传
上传文件(ZIP或单个文件)
POST /api/upload/:projectId
Content-Type: multipart/form-data
Body: files (multipart)
返回 { message, filesUploaded, totalSize, project: { id, subdomain } }
支持 .zip 压缩包(自动解压)和单个文件。所有上传文件都会经过恶意软件扫描(ClamAV + 魔术字节验证)。
支持的文件类型: HTML、CSS、JS、JSON、XML、SVG、图片(PNG、JPG、GIF、WebP、AVIF、ICO)、PDF、演示文稿(PPTX)、文档(DOCX、XLSX)、音频(MP3、WAV、OGG、FLAC、AAC)、视频(MP4、WebM、MOV)、字体(WOFF、WOFF2、TTF、OTF、EOT)、压缩包(ZIP)、3D模型(GLB、GLTF、OBJ)以及任何其他静态资源。
被阻止的文件类型: 可执行文件(.exe、.dll、.bat、.sh、.php、.asp、.jar)以及包含脚本或事件处理程序的SVG将被拒绝。
删除文件
DELETE /api/upload/:projectId/files/:fileId
批量删除文件
POST /api/upload/:projectId/files/bulk-delete
Content-Type: application/json
Body: { fileIds: [id1, id2, id3] }
重命名文件
PATCH /api/upload/:projectId/files/:fileId
Content-Type: application/json
Body: { newPath: assets/renamed-file.png }
GitHub导入
从GitHub导入
POST /api/github/:projectId
Content-Type: application/json
Body: { owner: username, repo: repo-name, branch: main, subfolder: dist }
返回 { message, repo, branch, filesUploaded, filesSkipped, totalSize }
从公共GitHub仓库导入文件。branch 默认为main,如果未找到则自动回退到master。可选的 subfolder 字段允许您仅导入子目录(例如dist、build)。
需要Pro计划或更高版本。
版本回滚
列出版本
GET /api/versions/:projectId
返回 { versions: [{ id, version, label, fileCount, totalSize, createdAt }] }
创建版本快照
POST /api/versions/:projectId
Content-Type: application/json
Body: { label: v1.0 }
快照当前所有项目文件的状态。需要Pro计划或更高版本。
回滚到版本
POST /api/versions/:projectId/rollback/:version
将所有文件恢复到指定版本号所捕获的状态。
SEO
获取SEO报告
GET /api/seo/:projectId
返回 { score, suggestions: [{ id, type, severity, message, resolved }] }
需要Pro计划或更高版本。
运行SEO分析
POST /api/seo/:projectId/analyze
触发新的SEO扫描并返回更新的建议。
解决建议
PATCH /api/seo/suggestion/:id/resolve
AI自动修复SEO问题
POST /api/seo/:projectId/ai-fix
Content-Type: application/json
Body: { suggestionIds: [id1, id2] }
使用AI自动修复HTML文件中的SEO问题。计入AI生成限制。
分析
获取分析数据
GET /api/analytics/:projectId?period=7d
时间段:24h、7d、30d、90d
基础分析(所有计划):
返回 { totalVisits, visitsByDay, topPages, isAdvanced }
高级分析(Pro+计划):
额外返回 { uniqueVisitors, uniqueByDay, topReferrers, topCountries, devices, browsers }
免费计划用户收到 isAdvanced: false,高级字段为空。
追踪事件(公开,无需认证)
POST /api/analytics/track
Content-Type: application/json
Body: { projectId: ..., path: /page, referrer: ... }
二维码
生成二维码
POST /api/qrcode/:projectId
返回 { qrCodeUrl: data:image/png;base64,..., siteUrl: https://... }
生成指向项目在线URL(子域名或自定义域名)的二维码。返回base64数据URL。所有付费计划可用。
获取二维码
GET /api/qrcode/:projectId
返回 { qrCodeUrl: data:image/... | null }
邮件收集
切换项目邮件收集功能
PATCH /api/emails/:projectId/toggle
返回 { emailCapture: true/false }。需要Business计划。
启用后,访问托管网站的访客将在5秒后看到弹出式邮件收集表单。
提交邮箱(公开,无需认证)
POST /api/emails/submit
Content-Type: application/json
Body: { email: visitor@example.com, projectId: ..., source: modal }
来源选项:modal、inline、api。仅当项目启用了邮件收集且项目所有者拥有Business计划时有效。
获取已收集的邮箱
GET /api/emails/:projectId?page=1&limit=50
返回 { emails: [{ id, email, source, createdAt }], total, page, totalPages }
需要Business计划。
导出邮箱为CSV
GET /api/emails/:projectId/export
返回CSV文件下载。需要Business计划。
删除已收集的邮箱
DELETE /api/emails/:projectId/:emailId
团队
列出团队
GET /api/teams
返回 { teams: [{ id, name, ownerId, members: [...] }] }
创建团队
POST /api/teams
Content-Type: application/json
Body: { name: My Team }
需要Business计划。
添加团队成员
POST /api/teams/:teamId/members
Content-Type: application/json
Body: { email: