DEPLOY AND MANAGE WEBSITES FROM YOUR OWN CODE

Deploy a Website With One HTTP Call

Create websites from a ZIP archive, write and read individual files, pull form entries, and move between workspaces, all with one API key. Every endpoint is documented, and a Postman collection is ready to import.

Get your API key Read the API docs

REQUEST

curl -X POST https://api.static.app/v1/sites/zip \
    -H "Authorization: Bearer sk_xxxx" \
    -F "[email protected]"

RESPONSE

{
    "status": "success",
    "pid": "xxxxxxxxxx",
    "slug": "example-site",
    "url": "https://example-site.static.app"
}

Omit domain for a random static.app subdomain, or pass pid to update an existing website instead of creating another. Full reference.

  • Deploy from a ZIP or a URL

    Upload an archive to POST /v1/sites/zip, or hand POST /v1/sites a link to one and Static.app fetches it for you. Both return the pid and the live URL, and both update an existing website when you pass its pid.

  • Change one file, not the whole website

    Read a file, write it back, upload it, or delete it by path. write-files takes plain JSON, creates any missing directories and returns an MD5 per file, so a script with no filesystem of its own can publish a page and verify what landed.

  • Form entries you can actually use

    List the forms on a website, page through submissions with every field value, mark spam in bulk, and change the address notifications go to. Submissions can land in your CRM instead of an inbox.

Twenty-eight endpoints in all, covering websites, files, forms and workspaces, each documented with a working request and a real response in the API documentation.

From Zero to Your First Call in 3 Steps

  • 1

    Create your Static.app account.

  • 2

    Generate an API key in your account. Choose how long it lasts: a day, a week, a month, a year, or no expiry.

  • 3

    Make the call. GET /v1/sites with your key in the Authorization header returns every website in your workspace.

Why Use an API to Manage Static Websites?

Clicking through a dashboard is fine for one website. It stops being fine when you ship client work every week, run a build that publishes on every commit, or host websites on behalf of your own users. Repeating the same steps by hand costs time and quietly introduces mistakes.

The API covers the work you repeat: creating a website, replacing its files, reading a single file back, pulling form entries, and moving between workspaces. Every request runs against one workspace, and a single X-Team-Pid header points one request at another, so one integration can serve every client account you work in.

Built for Three Kinds of Work

Agencies shipping client websites

Ship the first version as an archive, then handle every later change one file at a time. A copy fix is a single request, not a redeploy. Each written file comes back with an MD5 that matches what a file listing returns, so you can tell exactly what changed.

  • REQUEST

    curl -X POST \
        https://api.static.app/v1/sites/write-files/xxxxxxxxxx \
        -H "Authorization: Bearer sk_xxxx" \
        -H "Content-Type: application/json" \
        -d '{
            "files": [
                { "path": "index.html",
                  "content": "<h1>Hello</h1>" }
            ]
        }'
  • RESPONSE

    {
        "status": "success",
        "written": 1,
        "files": [
            {
                "name": "index.html",
                "path": "index.html",
                "size": 21,
                "hash": "0123456789abcdef0123456789abcdef"
            }
        ],
        "errors": []
    }

Up to 200 files per request, text or base64, with missing directories created for you. Set create_only and an existing file is left untouched. See Write files.

CI and CD pipelines

Add one step at the end of your build. Zip the output, post it with the website's pid, and the same website is updated in place, so the address your client already has keeps working. There is nothing to install: it is one curl call and a secret.

  • DEPLOY STEP

    # after your build step, in CI
    zip -r site.zip dist
    
    curl -X POST https://api.static.app/v1/sites/zip \
        -H "Authorization: Bearer $STATIC_API_KEY" \
        -F "[email protected]" \
        -F "pid=$STATIC_SITE_PID"
  • RESPONSE

    {
        "status": "success",
        "pid": "xxxxxxxxxx",
        "slug": "example-site",
        "url": "https://example-site.static.app"
    }

Creating and updating share one endpoint, so a deploy script never needs two code paths. Finish with POST /v1/sites/{pid}/purge-cache and visitors get the new version straight away.

Platforms hosting websites for your own users

List the workspaces your key can reach, then send X-Team-Pid on each request to act inside one of them. The header applies only to the request it is on, so a worker handling ten customers in a row just changes one header, and your default workspace stays where it was.

  • REQUEST

    curl https://api.static.app/v1/sites \
        -H "Authorization: Bearer sk_xxxx" \
        -H "X-Team-Pid: yyyyyyyyyy"
  • RESPONSE

    [
        {
            "pid": "xxxxxxxxxx",
            "slug": "example-site",
            "title": "Client Website",
            "full_url": "https://example-site.static.app"
        }
    ]

Before you deploy, GET /v1/users/profile returns your plan, your website allowance and what you are using, so a script can stop cleanly instead of failing at the limit.

Not Just Endpoints

  • One key, every workspace

    List the workspaces your account can reach, see which one is active, and target another for a single request with a header. One integration covers every client workspace you belong to, with no second login.

  • Check your headroom before you deploy

    GET /v1/users/profile returns your plan and status, your website and storage allowance, and your current usage. Automation can decide whether to deploy instead of discovering the limit the hard way.

  • The same account, from an AI assistant

    The Static.app MCP server wraps this API for assistants like Claude and connects with the same key. See the MCP server page and the MCP documentation.

Frequently Asked Questions

Do I need a paid plan to use the API?

No. You can create an API key from any Static.app account and start calling the API straight away. Plan limits apply to what you create rather than to the API itself: adding a new website fails once you reach your plan's website allowance, while updating websites you already have is not affected. Compare allowances on the pricing page.

How does authentication work?

Send your key as a bearer token on every request: Authorization: Bearer sk_xxxx. Keys are created in your account, and you choose how long each one lasts: a day, a week, a month, a year, or no expiry. Deleting or regenerating a key takes effect on the very next request.

How do I update a website instead of creating a new one?

Pass the website's pid to POST /v1/sites/zip or POST /v1/sites and the archive replaces the contents of that website instead of creating another one. The pid and the website's static.app address stay the same, which is what makes the call safe to run from a pipeline on every commit.

Can one API key manage several client workspaces?

Yes. GET /v1/workspaces lists every workspace your account can reach, and adding X-Team-Pid with a workspace pid runs just that request against another workspace without changing your default. One integration can cover every client account you work in.

Is there a sandbox or a test mode?

No. Every call works on live data. The practical approach is to create a throwaway website through the API, point your integration at that pid while you build, then remove it with DELETE /v1/sites/{pid}. Giving a test key a short expiry means it retires itself.

How big can a deployment be?

Upload a ZIP to POST /v1/sites/zip, or hand POST /v1/sites a link to one and Static.app fetches it server side, so a large archive never travels inside your own request. A write-files call carries up to 200 files, and read-file is capped at 1MB, with the download endpoints for anything bigger. Storage overall is set by your plan.

Can I get a whole website back out?

Yes. GET /v1/sites/download/{pid} builds a ZIP of the entire website and returns a URL to the archive, and POST /v1/sites/download-files/{pid} does the same for a list of paths you choose. A nightly backup is a cron job and one request.