Skip to content

Latest commit

 

History

History
982 lines (817 loc) · 16.1 KB

File metadata and controls

982 lines (817 loc) · 16.1 KB

EmberDocs API Specifications

Version: 1.0
Base URL: https://api.emberdocs.com/v1
Authentication: Bearer token or API key


Overview

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:

  1. Public API - Accessible with API keys for site management
  2. Internal API - Used by EmberDocs frontend applications
  3. Webhook API - Receives events from git providers

Authentication

API Keys

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 content
  • write:docs - Create/update documentation
  • delete:docs - Delete documentation
  • deploy - Trigger deployments
  • read:analytics - Access analytics data
  • manage:team - Manage team members
  • admin - Full access

OAuth 2.0

For third-party integrations.

GET /oauth/authorize
  ?client_id=...
  &redirect_uri=...
  &response_type=code
  &scope=read:docs write:docs

Rate Limits

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

Sites API

List Sites

GET /sites

Response:

{
  "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 Site

GET /sites/:id

Response:

{
  "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"
  }
}

Create Site

POST /sites

Request:

{
  "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..."
  }
}

Update Site

PATCH /sites/:id

Request:

{
  "name": "Updated Documentation",
  "customDomain": "docs.example.com",
  "config": {
    "theme": {
      "colors": {
        "primary": "#10B981"
      }
    }
  }
}

Delete Site

DELETE /sites/:id

Response:

{
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "status": "deleted",
    "deletedAt": "2024-12-06T11:00:00Z"
  }
}

Deployments API

List Deployments

GET /sites/:siteId/deployments

Query 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 Deployment

GET /sites/:siteId/deployments/:id

Response:

{
  "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"
  }
}

Trigger Deployment

POST /sites/:siteId/deployments

Request:

{
  "branch": "main",
  "clearCache": false
}

Response:

{
  "data": {
    "id": "deploy_124",
    "status": "pending",
    "triggerType": "manual",
    "startedAt": "2024-12-06T11:00:00Z"
  }
}

Cancel Deployment

POST /sites/:siteId/deployments/:id/cancel

Content API

List Pages

GET /sites/:siteId/pages

Response:

{
  "data": [
    {
      "path": "/getting-started",
      "title": "Getting Started",
      "category": "Documentation",
      "updatedAt": "2024-12-05T14:30:00Z",
      "url": "https://my-docs.emberdocs.com/getting-started"
    }
  ]
}

Get Page

GET /sites/:siteId/pages/:path

Example:

GET /sites/550e8400.../pages/getting-started

Response:

{
  "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"
  }
}

Search Pages

GET /sites/:siteId/pages/search?q=authentication

Response:

{
  "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
  }
}

Analytics API

Get Overview

GET /sites/:siteId/analytics/overview

Query 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 Page Analytics

GET /sites/:siteId/analytics/pages/:path

Response:

{
  "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 Search Analytics

GET /sites/:siteId/analytics/search

Query Parameters:

  • from - Start date
  • to - End date
  • limit - 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
  }
}

Team API

List Team Members

GET /sites/:siteId/team

Response:

{
  "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"
    }
  ]
}

Invite Team Member

POST /sites/:siteId/team

Request:

{
  "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..."
  }
}

Update Team Member

PATCH /sites/:siteId/team/:memberId

Request:

{
  "role": "admin"
}

Remove Team Member

DELETE /sites/:siteId/team/:memberId

Webhooks API

Configure Webhook

POST /sites/:siteId/webhooks

Request:

{
  "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"
  }
}

Webhook Events

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"
  }
}

Webhook Signature Verification

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');
});

Git Provider Webhooks

GitHub

POST /webhooks/:siteId

Headers:

X-GitHub-Event: push
X-Hub-Signature-256: sha256=...
Content-Type: application/json

Payload:

{
  "ref": "refs/heads/main",
  "commits": [
    {
      "id": "abc123def456",
      "message": "Update documentation"
    }
  ]
}

GitLab

POST /webhooks/:siteId

Headers:

X-Gitlab-Event: Push Hook
X-Gitlab-Token: ...

Bitbucket

POST /webhooks/:siteId

Headers:

X-Event-Key: repo:push

Error Responses

Error Format

{
  "error": {
    "code": "RESOURCE_NOT_FOUND",
    "message": "Site with ID '123' not found",
    "details": {
      "siteId": "123"
    },
    "requestId": "req_abc123"
  }
}

Common Error Codes

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

SDK Examples

JavaScript/TypeScript

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',
});

Python

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'
)

cURL

# 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"

GraphQL API (Premium)

Endpoint

POST https://api.emberdocs.com/v1/graphql

Example Query

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
      }
    }
  }
}

Example Mutation

mutation TriggerDeployment($siteId: ID!, $branch: String) {
  triggerDeployment(siteId: $siteId, branch: $branch) {
    id
    status
    startedAt
  }
}

API Versioning

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.