Skip to content

Create a site from a template

Try it

Makes a new DRAFT site from a template — the same engine as the console's new-site flow. It adds the package's wholesale setup fee (if any) to your bill now and the monthly fee once the site is live. Nothing is public until you publish. Send expected_setup_cents/expected_monthly_cents to refuse if the price changed since you quoted it.

POST/api/v1/sites

Authentication

An API key as Authorization: Bearer or x-api-key. It needs the sites:create scope — make new sites (each adds the wholesale fee to your bill).

sites:createAdds to your billIdempotency-Key requiredMCP tool: create_site

Parameters

Named placeholders go in the path; the rest in a JSON body.

template_idstringBody · required
From List templates.1 to 100 characters
namestringBody · required
The site's name in your account, e.g. the business name.2 to 80 characters
slugstringBody · optional
The free address's subdomain. Taken → a number is added. Omitted = from the name.
client_idstringBody · optional
The client it is for (List clients).At most 100 characters
package_idstringBody · optional
From List packages. Omitted = the default package.At most 100 characters
stylestringBody · optional
A design style slug. Omitted = the template's own look.One of: altered, clean-modern, warm-classic, industrial, luxe, fresh-bright, coastal, heritage
business_namestringBody · optional
Written into the site's business details.1 to 120 characters
retail_setup_centsintegerBody · optional
Your price to the client, setup. Needs a creator who may see prices.0 to 100000000
retail_monthly_centsintegerBody · optional
Your price to the client, monthly. Needs a creator who may see prices.0 to 100000000
expected_setup_centsintegerBody · optional
Refuse unless the wholesale setup fee is exactly this.0 to 100000000
expected_monthly_centsintegerBody · optional
Refuse unless the wholesale monthly fee is exactly this.0 to 100000000

Response

201 with JSON on success (schema on the right). Errors use the standard envelope; a retry with the same Idempotency-Key gets the first answer back (how retries work).

curl
curl -X POST 'https://websites.workflowcorp.com/api/v1/sites' \
  -H "Authorization: Bearer $WEBSITEBUDDY_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"template_id":"TEMPLATE_ID","name":"Maple Street Bakery","client_id":"CLIENT_ID","style":"warm-classic"}'
Example arguments
{
  "template_id": "TEMPLATE_ID",
  "name": "Maple Street Bakery",
  "client_id": "CLIENT_ID",
  "style": "warm-classic"
}
Response schema
{
  "type": "object",
  "properties": {
    "id": {
      "type": "string"
    },
    "name": {
      "type": "string"
    },
    "slug": {
      "type": "string"
    },
    "status": {
      "type": "string",
      "enum": [
        "draft",
        "live",
        "suspended",
        "archived"
      ]
    },
    "taken_down": {
      "type": "boolean",
      "description": "You took the site down (status suspended): not served, not billed from the next run, data kept. put_site_back_up reverses it."
    },
    "address": {
      "type": "string",
      "description": "The free address, e.g. https://rosies-diner.websites.workflowcorp.com/"
    },
    "custom_domain": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "description": "The verified primary custom domain, if any."
    },
    "client_id": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ]
    },
    "template_id": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ]
    },
    "package": {
      "anyOf": [
        {
          "type": "object",
          "properties": {
            "id": {
              "type": "string"
            },
            "name": {
              "type": "string"
            },
            "page_limit": {
              "anyOf": [
                {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                {
                  "type": "null"
                }
              ]
            }
          },
          "required": [
            "id",
            "name",
            "page_limit"
          ],
          "additionalProperties": false
        },
        {
          "type": "null"
        }
      ]
    },
    "published_version": {
      "anyOf": [
        {
          "type": "integer",
          "minimum": -9007199254740991,
          "maximum": 9007199254740991
        },
        {
          "type": "null"
        }
      ]
    },
    "published_at": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ]
    },
    "unpublished_changes": {
      "type": "boolean",
      "description": "The draft has edits that are not live yet."
    },
    "editor_url": {
      "type": "string"
    },
    "prices": {
      "anyOf": [
        {
          "type": "object",
          "properties": {
            "wholesale_setup_cents": {
              "type": "integer",
              "minimum": -9007199254740991,
              "maximum": 9007199254740991
            },
            "wholesale_monthly_cents": {
              "type": "integer",
              "minimum": -9007199254740991,
              "maximum": 9007199254740991
            },
            "retail_setup_cents": {
              "type": "integer",
              "minimum": -9007199254740991,
              "maximum": 9007199254740991
            },
            "retail_monthly_cents": {
              "type": "integer",
              "minimum": -9007199254740991,
              "maximum": 9007199254740991
            }
          },
          "required": [
            "wholesale_setup_cents",
            "wholesale_monthly_cents",
            "retail_setup_cents",
            "retail_monthly_cents"
          ],
          "additionalProperties": false
        },
        {
          "type": "null"
        }
      ],
      "description": "Only when the key's creator may see prices (billing.view); null otherwise."
    },
    "is_sample": {
      "type": "boolean"
    },
    "created_at": {
      "type": "string"
    },
    "page_count": {
      "type": "integer",
      "minimum": -9007199254740991,
      "maximum": 9007199254740991
    },
    "template_page_count": {
      "type": "integer",
      "minimum": -9007199254740991,
      "maximum": 9007199254740991,
      "description": "More than page_count when the package's page limit trimmed the template."
    }
  },
  "required": [
    "id",
    "name",
    "slug",
    "status",
    "taken_down",
    "address",
    "custom_domain",
    "client_id",
    "template_id",
    "package",
    "published_version",
    "published_at",
    "unpublished_changes",
    "editor_url",
    "prices",
    "is_sample",
    "created_at",
    "page_count",
    "template_page_count"
  ],
  "additionalProperties": false
}