---
title: "Deploy a static site"
description: "Deploy a static website with one Agent API call: storage, uploads, CDN, domain, SSL and DNS. Upload files directly or deploy from a GitHub or GitLab repo."
url: "https://edge.network/docs/agent/deploy-static-site"
section: "Agent tooling"
---

# Deploy a static site

One API call deploys a complete static website: storage bucket, file uploads, CDN, domain, SSL, and DNS.

## What it does

The `deploy/static-site` endpoint orchestrates five services in one call:

1. **Storage:** Creates a bucket (named after the project).
2. **Upload:** Uploads files (from the request body or cloned from git).
3. **CDN:** Creates a deployment with the bucket as origin.
4. **Domain:** Adds your domain to the CDN with automatic SSL.
5. **DNS:** Auto-creates a CNAME record if the zone is on Edge DNS.

## Request

```http
POST /agent/deploy/static-site
Authorization: Bearer ea_live_...

{
  "project": "my-portfolio",
  "source": {
    "type": "upload",
    "files": [
      {
        "path": "index.html",
        "content": "PCFET0NUWVBFIGh0bWw+Li4=",
        "content_type": "text/html"
      },
      {
        "path": "styles.css",
        "content": "Ym9keSB7IG1hcmdpbjogMDsgfQ==",
        "content_type": "text/css"
      },
      {
        "path": "app.js",
        "content": "Y29uc29sZS5sb2coJ2hlbGxvJyk=",
        "content_type": "application/javascript"
      }
    ]
  },
  "domain": "portfolio.example.com"
}
```

## Deploy from Git

Instead of uploading files directly, you can deploy from a GitHub or GitLab repository. The agent clones the repo and deploys the specified directory.

```http
POST /agent/deploy/static-site
Authorization: Bearer ea_live_...

{
  "project": "my-portfolio",
  "source": {
    "type": "git",
    "repo": "user/my-portfolio",
    "branch": "main",
    "path": "dist"
  },
  "domain": "portfolio.example.com"
}
```

Use the `path` parameter to specify a subdirectory (e.g. `dist` or `build`). Only that directory will be deployed.

### Private repositories

For private repositories, include a personal access token:

```json
{
  "source": {
    "type": "git",
    "repo": "user/private-site",
    "branch": "main",
    "path": "build",
    "token": "ghp_xxxxxxxxxxxx"
  }
}
```

## Parameters

| Field | Required | Description |
|---|---|---|
| `project` | Yes | Project name. Created automatically if it doesn't exist. |
| `source.type` | Yes | `"upload"` for base64 files, `"git"` to deploy from a repository |
| `source.files[]` | For `upload` | Array of files. Each needs `path` and `content` (base64). |
| `source.files[].content_type` | No | MIME type. Auto-detected from file extension if omitted. |
| `source.repo` | For git | GitHub/GitLab URL or `user/repo` shorthand |
| `source.branch` | For git | Branch or tag. Default: `main` |
| `source.path` | For git | Subdirectory to deploy (e.g. `dist`, `build`). Root if omitted. |
| `source.token` | For git | Personal access token for private repositories |
| `source.changed_only` | No | Skip unchanged files on update (compares MD5 hashes) |
| `domain` | No | Domain to serve from. SSL provisioned automatically. |
| `options.spa_mode` | No | Enable single-page app mode (route all paths to `index.html`). |
| `options.image_optimization` | No | Enable on-the-fly image optimisation via CDN. |

## Response

```json
{
  "status": "deployed",
  "project_id": "proj_a1b2c3d4e5f6",
  "url": "https://portfolio.example.com",
  "resources_created": [
    { "type": "storage_bucket", "id": "my-portfolio", "name": "my-portfolio" },
    { "type": "cdn_deployment", "id": "dep_xyz789", "name": "my-portfolio" },
    { "type": "dns_record", "id": "zone_abc", "note": "CNAME portfolio → cdn.edge.network" }
  ],
  "tell_user": "Your site is live at https://portfolio.example.com. 3 files deployed to Edge CDN with automatic SSL."
}
```

## Dry run

Add `X-Dry-Run: true` to preview what would be created:

```http
POST /agent/deploy/static-site
Authorization: Bearer ea_live_...
X-Dry-Run: true

# Response:
{
  "dry_run": true,
  "would_create": [
    { "type": "storage_bucket", "name": "my-portfolio" },
    { "type": "cdn_deployment", "name": "my-portfolio" },
    { "type": "cdn_domain", "domain": "portfolio.example.com" },
    { "type": "dns_record", "note": "CNAME → cdn.edge.network (if zone on Edge DNS)" }
  ],
  "file_count": 3,
  "tell_user": "Would create storage bucket, upload 3 files, and configure CDN. Domain portfolio.example.com would be added with SSL."
}
```

## Updating a deployment

After the initial deploy, use `PATCH /agent/deploy/{projectId}` to push updates without recreating resources:

```http
PATCH /agent/deploy/proj_a1b2c3d4e5f6
Authorization: Bearer ea_live_...

{
  "source": {
    "type": "upload",
    "files": [
      { "path": "index.html", "content": "PCFET0NUWVBFIGh0bWw+Li4=", "content_type": "text/html" }
    ]
  },
  "purge_cdn": true
}

# Response:
{
  "project": "my-portfolio",
  "files_uploaded": 1,
  "cdn_purged": true,
  "tell_user": "Updated \"my-portfolio\": 1 file uploaded. CDN cache purged."
}
```

## Incremental updates

Set `changed_only: true` to skip uploading files that haven't changed. The agent compares MD5 hashes of each file against the existing deployment and only uploads differences.

```http
PATCH /agent/deploy/proj_a1b2c3d4e5f6
Authorization: Bearer ea_live_...

{
  "source": {
    "type": "upload",
    "files": [...],
    "changed_only": true
  },
  "purge_cdn": true
}

# Response:
{
  "project": "my-portfolio",
  "files_uploaded": 3,
  "files_skipped": 47,
  "cdn_purged": true,
  "tell_user": "Updated \"my-portfolio\": 3 files uploaded. 47 unchanged files skipped. CDN cache purged."
}
```

## Auto-detected content types

If `content_type` is omitted, it's detected from the file extension:

| Extension | Content type |
|---|---|
| `.html` | `text/html` |
| `.css` | `text/css` |
| `.js` | `application/javascript` |
| `.json` | `application/json` |
| `.png` | `image/png` |
| `.jpg` | `image/jpeg` |
| `.svg` | `image/svg+xml` |
| `.webp` | `image/webp` |
| `.woff2` | `font/woff2` |
| `.mp4` | `video/mp4` |
| `.pdf` | `application/pdf` |
| `.xml` | `application/xml` |

## See also

- [Deploy an application](/docs/agent/deploy-app): Deploy a VM-based application
- [Projects](/docs/agent/projects): Health checks, scaling and teardown
