> ## Documentation Index
> Fetch the complete documentation index at: https://docs.platform.embeddables.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Deploy from CI

> Upload Worker applications to Embeddables Hosting with a project deploy key

Use `heysavvy/embeddables-actions/embeddables-deploy@v1` to deploy a configured hosting app from
GitHub Actions. This guide assumes the app's build paths are already listed in
`embeddables/config.yaml`.

## Add the deploy key

Create a deploy key from the Embeddables dashboard, the
[`createHostingDeployKey` Admin SDK method](/hosting/admin-sdk#deploy-keys), or the
[`hosting_create_deploy_key` MCP tool](/hosting/mcp#writes).

Save the returned `edk_…` secret in the GitHub repository as `EMBEDDABLES_DEPLOY_KEY`. The secret is
shown only once. Create a new key if it is lost; do not log it or commit it.

## Configure the build output

Add the existing server and client build directories to `embeddables/config.yaml`.

Example:

```yaml theme={null}
projectId: '<your project id>'
hosting:
  apps:
    - slug: storefront
      server: build/server
      client: build/client
```

`server` and `client` are relative to the repository root. `slug` must exactly match the app slug
registered in the Embeddables dashboard.

## Add the workflow

Example:

```yaml theme={null}
name: Embeddables preview

on:
  push:
  pull_request:
    types: [opened, reopened]

permissions:
  contents: read
  pull-requests: write

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: heysavvy/embeddables-actions/embeddables-deploy@v1
        with:
          deploy-key: ${{ secrets.EMBEDDABLES_DEPLOY_KEY }}
```

The action reads `embeddables/config.yaml`, packages one app's existing build output, uploads it, and
exposes `branch-url` and `commit-url` outputs. When the config lists more than one hosting app, pass
its slug with `app`. Use `config` only when the config file is not at `embeddables/config.yaml`.

On a pull request, the action comments with the branch preview URL. A deploy from the registered
production branch also promotes the new commit to production.

## Deploy endpoint

The action sends one gzipped tar archive to:

```text theme={null}
POST https://backend.embeddables.com/hosting/v1/deploys
```

The request contract is:

| Header | Value |
| - | - |
| `Authorization` | `Bearer edk_…` project deploy key |
| `Content-Type` | `application/gzip` or `application/x-gzip` |
| `X-Hosting-App` | Registered app slug |
| `X-Git-Branch` | Git branch name |
| `X-Git-Sha` | Commit SHA, 7–40 hexadecimal characters |
| `X-Git-Commit-Time` | Optional ISO 8601 commit time |
| `X-Project-Id` | Optional project ID; when present, it must own the deploy key |

The archive contains Worker modules under `server/` and static files under `client/`.
`server/wrangler.json` can set the main module, compatibility date, compatibility flags, and string
variables. The main module defaults to `index.js`.

The compressed request is limited to 32 MB, the unpacked archive to 64 MB, and each static asset to
25 MB.

## Returned URLs

A successful deploy returns:

* `branchUrl`: the moving URL for the git branch.
* `commitUrl`: the immutable URL for this commit.
* `promotion`: the production promotion result when the branch is the production branch, otherwise
  `null`.

Overlapping CI jobs cannot move a branch or deploy-triggered production alias back to an older
commit when `X-Git-Commit-Time` is present.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.