Version: 1.0
Base URL: https://api.emberdocs.com/v1
Authentication: Bearer token or API key
The EmberDocs API provides programmatic access to documentation management, deployment, and analytics. The OSS version has no API dependencies. The premium version provides REST and GraphQL APIs for automation and integrations.
API Types:
- Public API - Accessible with API keys for site management
- Internal API - Used by EmberDocs frontend applications
- Webhook API - Receives events from git providers
Create API keys in the EmberDocs dashboard. Keys are scoped to specific sites and permissions.
# Header authentication
Authorization: Bearer ed_prod_abc123...
# Query parameter (not recommended for production)
?api_key=ed_prod_abc123...Key Format:
ed_{environment}_{random}
↓ ↓ ↓
prefix prod/test random string
Example: ed_prod_7k3n9x2m4p1q8w5e
Scopes:
read:docs- Read documentation contentwrite:docs- Create/update documentationdelete:docs- Delete documentationdeploy- Trigger deploymentsread:analytics- Access analytics datamanage:team- Manage team membersadmin- Full access
For third-party integrations.
GET /oauth/authorize
?client_id=...
&redirect_uri=...
&response_type=code
&scope=read:docs write:docs
Free Tier:
- 60 requests per minute
- 1,000 requests per day
Premium Tier:
- 300 requests per minute
- 10,000 requests per day
Headers:
X-RateLimit-Limit: 300
X-RateLimit-Remaining: 299
X-RateLimit-Reset: 1640995200
GET /sitesResponse:
{
"data": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "My Documentation",
"slug": "my-docs",
"customDomain": "docs.example.com",
"status": "active",
"deploymentStatus": "deployed",
"lastDeployedAt": "2024-12-06T10:30:00Z",
"createdAt": "2024-11-01T08:00:00Z",
"urls": {
"emberdocs": "https://my-docs.emberdocs.com",
"custom": "https://docs.example.com"
}
}
],
"pagination": {
"page": 1,
"perPage": 20,
"total": 42,
"pages": 3
}
}GET /sites/:idResponse:
{
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "My Documentation",
"slug": "my-docs",
"customDomain": "docs.example.com",
"git": {
"provider": "github",
"repoUrl": "https://github.com/user/repo",
"branch": "main"
},
"config": {
"docsPath": "./docs",
"theme": {
"colors": {
"primary": "#8B5CF6"
}
}
},
"status": "active",
"deploymentStatus": "deployed",
"lastDeployedAt": "2024-12-06T10:30:00Z",
"lastBuildDurationMs": 4523,
"analytics": {
"enabled": true,
"searchAnalytics": true
},
"createdAt": "2024-11-01T08:00:00Z",
"updatedAt": "2024-12-06T10:30:00Z"
}
}POST /sitesRequest:
{
"name": "My Documentation",
"slug": "my-docs",
"gitProvider": "github",
"gitRepoUrl": "https://github.com/user/repo",
"gitBranch": "main",
"docsPath": "./docs",
"config": {
"theme": {
"colors": {
"primary": "#8B5CF6"
}
}
}
}Response:
{
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "My Documentation",
"slug": "my-docs",
"status": "pending",
"webhookUrl": "https://api.emberdocs.com/v1/webhooks/550e8400-e29b-41d4-a716-446655440000",
"webhookSecret": "whsec_abc123..."
}
}PATCH /sites/:idRequest:
{
"name": "Updated Documentation",
"customDomain": "docs.example.com",
"config": {
"theme": {
"colors": {
"primary": "#10B981"
}
}
}
}DELETE /sites/:idResponse:
{
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"status": "deleted",
"deletedAt": "2024-12-06T11:00:00Z"
}
}GET /sites/:siteId/deploymentsQuery Parameters:
status- Filter by status (pending, building, success, failed)limit- Results per page (default: 20, max: 100)page- Page number
Response:
{
"data": [
{
"id": "deploy_123",
"status": "success",
"triggerType": "webhook",
"git": {
"commitSha": "abc123def456",
"commitMessage": "Update documentation",
"branch": "main"
},
"metrics": {
"buildDurationMs": 4523,
"pagesBuilt": 42,
"assetsSizeBytes": 1048576
},
"startedAt": "2024-12-06T10:25:00Z",
"completedAt": "2024-12-06T10:30:00Z"
}
]
}GET /sites/:siteId/deployments/:idResponse:
{
"data": {
"id": "deploy_123",
"status": "success",
"triggerType": "webhook",
"git": {
"commitSha": "abc123def456",
"commitMessage": "Update documentation",
"branch": "main"
},
"buildLog": "Building documentation...\n✓ Parsed 42 markdown files\n✓ Generated navigation\n✓ Built search index\n✓ Deployment complete",
"metrics": {
"buildDurationMs": 4523,
"pagesBuilt": 42,
"assetsSizeBytes": 1048576
},
"startedAt": "2024-12-06T10:25:00Z",
"completedAt": "2024-12-06T10:30:00Z"
}
}POST /sites/:siteId/deploymentsRequest:
{
"branch": "main",
"clearCache": false
}Response:
{
"data": {
"id": "deploy_124",
"status": "pending",
"triggerType": "manual",
"startedAt": "2024-12-06T11:00:00Z"
}
}POST /sites/:siteId/deployments/:id/cancelGET /sites/:siteId/pagesResponse:
{
"data": [
{
"path": "/getting-started",
"title": "Getting Started",
"category": "Documentation",
"updatedAt": "2024-12-05T14:30:00Z",
"url": "https://my-docs.emberdocs.com/getting-started"
}
]
}GET /sites/:siteId/pages/:pathExample:
GET /sites/550e8400.../pages/getting-startedResponse:
{
"data": {
"path": "/getting-started",
"title": "Getting Started",
"description": "Learn how to get started with EmberDocs",
"content": "# Getting Started\n\nWelcome to...",
"metadata": {
"category": "Documentation",
"tags": ["guide", "beginner"],
"author": "John Doe"
},
"readingTime": 5,
"updatedAt": "2024-12-05T14:30:00Z"
}
}GET /sites/:siteId/pages/search?q=authenticationResponse:
{
"data": {
"query": "authentication",
"results": [
{
"path": "/api/authentication",
"title": "Authentication",
"excerpt": "Learn how to authenticate API requests using API keys or OAuth...",
"score": 0.95
}
],
"total": 3,
"searchDurationMs": 45
}
}GET /sites/:siteId/analytics/overviewQuery Parameters:
from- Start date (ISO 8601)to- End date (ISO 8601)interval- Grouping (hour, day, week, month)
Response:
{
"data": {
"period": {
"from": "2024-11-01T00:00:00Z",
"to": "2024-12-01T00:00:00Z"
},
"pageViews": {
"total": 15420,
"unique": 8234,
"trend": 12.5
},
"visitors": {
"total": 5432,
"returning": 2156,
"new": 3276
},
"averageTimeOnPage": 180,
"bounceRate": 0.32,
"topPages": [
{
"path": "/getting-started",
"views": 2340,
"uniqueVisitors": 1876
}
],
"topReferrers": [
{
"domain": "google.com",
"visits": 1234
}
],
"devices": {
"desktop": 8234,
"mobile": 6012,
"tablet": 1174
}
}
}GET /sites/:siteId/analytics/pages/:pathResponse:
{
"data": {
"path": "/getting-started",
"title": "Getting Started",
"metrics": {
"pageViews": 2340,
"uniqueVisitors": 1876,
"averageTimeOnPage": 245,
"scrollDepth": {
"0-25": 234,
"25-50": 543,
"50-75": 892,
"75-100": 671
}
},
"timeSeries": [
{
"date": "2024-11-01",
"views": 123
}
],
"referrers": [
{
"domain": "google.com",
"visits": 342
}
]
}
}GET /sites/:siteId/analytics/searchQuery Parameters:
from- Start dateto- End datelimit- Number of results
Response:
{
"data": {
"topQueries": [
{
"query": "authentication",
"count": 234,
"avgResultsCount": 5.2,
"clickThroughRate": 0.76
}
],
"noResultQueries": [
{
"query": "deployment hooks",
"count": 12
}
],
"totalSearches": 1543,
"averageSearchDuration": 67
}
}GET /sites/:siteId/teamResponse:
{
"data": [
{
"id": "member_123",
"user": {
"id": "user_456",
"name": "John Doe",
"email": "john@example.com",
"avatarUrl": "https://..."
},
"role": "admin",
"status": "active",
"invitedAt": "2024-11-01T08:00:00Z",
"acceptedAt": "2024-11-01T09:15:00Z"
}
]
}POST /sites/:siteId/teamRequest:
{
"email": "jane@example.com",
"role": "editor"
}Response:
{
"data": {
"id": "member_124",
"email": "jane@example.com",
"role": "editor",
"status": "pending",
"invitedAt": "2024-12-06T11:00:00Z",
"inviteUrl": "https://emberdocs.com/invite/abc123..."
}
}PATCH /sites/:siteId/team/:memberIdRequest:
{
"role": "admin"
}DELETE /sites/:siteId/team/:memberIdPOST /sites/:siteId/webhooksRequest:
{
"url": "https://example.com/webhook",
"events": ["deployment.started", "deployment.completed", "deployment.failed"],
"secret": "your_webhook_secret"
}Response:
{
"data": {
"id": "webhook_123",
"url": "https://example.com/webhook",
"events": ["deployment.started", "deployment.completed"],
"status": "active",
"createdAt": "2024-12-06T11:00:00Z"
}
}Deployment Started:
{
"event": "deployment.started",
"timestamp": "2024-12-06T10:25:00Z",
"data": {
"siteId": "550e8400-e29b-41d4-a716-446655440000",
"deploymentId": "deploy_123",
"git": {
"commitSha": "abc123",
"branch": "main"
}
}
}Deployment Completed:
{
"event": "deployment.completed",
"timestamp": "2024-12-06T10:30:00Z",
"data": {
"siteId": "550e8400-e29b-41d4-a716-446655440000",
"deploymentId": "deploy_123",
"status": "success",
"metrics": {
"buildDurationMs": 4523,
"pagesBuilt": 42
},
"url": "https://my-docs.emberdocs.com"
}
}const crypto = require('crypto');
function verifyWebhook(payload, signature, secret) {
const hmac = crypto.createHmac('sha256', secret);
const digest = hmac.update(payload).digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(digest)
);
}
// Express middleware
app.post('/webhook', (req, res) => {
const signature = req.headers['x-emberdocs-signature'];
const payload = JSON.stringify(req.body);
if (!verifyWebhook(payload, signature, WEBHOOK_SECRET)) {
return res.status(401).send('Invalid signature');
}
// Process webhook
res.status(200).send('OK');
});POST /webhooks/:siteIdHeaders:
X-GitHub-Event: push
X-Hub-Signature-256: sha256=...
Content-Type: application/json
Payload:
{
"ref": "refs/heads/main",
"commits": [
{
"id": "abc123def456",
"message": "Update documentation"
}
]
}POST /webhooks/:siteIdHeaders:
X-Gitlab-Event: Push Hook
X-Gitlab-Token: ...
POST /webhooks/:siteIdHeaders:
X-Event-Key: repo:push
{
"error": {
"code": "RESOURCE_NOT_FOUND",
"message": "Site with ID '123' not found",
"details": {
"siteId": "123"
},
"requestId": "req_abc123"
}
}| Code | HTTP Status | Description |
|---|---|---|
UNAUTHORIZED |
401 | Invalid or missing authentication |
FORBIDDEN |
403 | Insufficient permissions |
RESOURCE_NOT_FOUND |
404 | Resource does not exist |
VALIDATION_ERROR |
422 | Invalid request data |
RATE_LIMIT_EXCEEDED |
429 | Too many requests |
INTERNAL_ERROR |
500 | Server error |
import { EmberDocs } from '@emberdocs/sdk';
const client = new EmberDocs({
apiKey: process.env.EMBERDOCS_API_KEY,
});
// List sites
const sites = await client.sites.list();
// Get site
const site = await client.sites.get('site_id');
// Trigger deployment
const deployment = await client.deployments.create('site_id', {
branch: 'main',
});
// Get analytics
const analytics = await client.analytics.getOverview('site_id', {
from: '2024-11-01',
to: '2024-12-01',
});from emberdocs import EmberDocs
client = EmberDocs(api_key=os.environ['EMBERDOCS_API_KEY'])
# List sites
sites = client.sites.list()
# Get site
site = client.sites.get('site_id')
# Trigger deployment
deployment = client.deployments.create(
site_id='site_id',
branch='main'
)
# Get analytics
analytics = client.analytics.get_overview(
site_id='site_id',
from_date='2024-11-01',
to_date='2024-12-01'
)# List sites
curl -H "Authorization: Bearer $API_KEY" \
https://api.emberdocs.com/v1/sites
# Get site
curl -H "Authorization: Bearer $API_KEY" \
https://api.emberdocs.com/v1/sites/550e8400...
# Trigger deployment
curl -X POST \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"branch":"main"}' \
https://api.emberdocs.com/v1/sites/550e8400.../deployments
# Get analytics
curl -H "Authorization: Bearer $API_KEY" \
"https://api.emberdocs.com/v1/sites/550e8400.../analytics/overview?from=2024-11-01&to=2024-12-01"POST https://api.emberdocs.com/v1/graphql
query GetSite($siteId: ID!) {
site(id: $siteId) {
id
name
slug
customDomain
deploymentStatus
lastDeployedAt
deployments(limit: 5) {
id
status
startedAt
completedAt
git {
commitSha
commitMessage
}
}
analytics(from: "2024-11-01", to: "2024-12-01") {
pageViews {
total
unique
trend
}
topPages {
path
views
}
}
}
}mutation TriggerDeployment($siteId: ID!, $branch: String) {
triggerDeployment(siteId: $siteId, branch: $branch) {
id
status
startedAt
}
}Versioning Strategy:
- URL versioning (
/v1,/v2) - Backward compatibility within major versions
- Deprecation notices 6 months before removal
- Version lifecycle: Current, Deprecated, Sunset
Version Headers:
X-API-Version: 1.0
X-Deprecated: false
Deprecation Notice:
{
"data": {...},
"warnings": [
{
"type": "deprecation",
"message": "This endpoint will be removed on 2025-06-01",
"replacement": "/v2/sites"
}
]
}This API specification covers all programmatic access patterns for EmberDocs premium features.