hosting

POST /v1/sites/{siteId}/ftp-users

Create an FTP account on a site.

All hosting endpoints

Authentication

Send an API key as a bearer token. The key must carry the sites.manage permission; a key without it is refused with 403, not 404.

This endpoint takes no organisation id. Your key already identifies the organisation it belongs to, and the response is scoped to it.

Try it

Replace anything in angle brackets with your own values, and the key placeholder with a key from your dashboard.

curl -X POST https://api.zinndigital.com/v1/sites/{siteId}/ftp-users \
  -H "Authorization: Bearer zdk_live_…" \
  -H "Content-Type: application/json" \
  -d '{ "username": <string>, "password": <string> }'

Signed in? The API console in your dashboard fills in your real organisation id and your own key, and runs the request against the live API so you can see the actual response. Open this endpoint in the API console

Details

Adds an account confined to one directory of the package. The **caller chooses the password** and it travels in the request only: it is never echoed in the response, never written to our records and never logged. That is the opposite of `createSiteDatabase`, and deliberately so — an FTP password is a long-lived credential a deployment pipeline will hold, so the person who owns that pipeline supplies it. The effective ceiling is applied **before** the vendor is called: a package type that does not permit extra accounts, and a customer who has used the last of their allowance, are both refused `422` with a sentence they can act on. A username the package already carries is refused `409` — the vendor namespaces usernames per package, so this collides with the customer's own accounts, not with anyone else's. `404` for a site with no vendor hosting package. Requires `sites.manage`.

Parameters

NameTypeRequiredWhat it is
siteId (path)UuidYesSite ID (UUIDv7).

Request body

NameTypeRequiredWhat it is
usernamestringYesThe login name to create. The vendor prefixes it per package on some package types, so the value that comes back in `SiteFtpUser.username` is the one that signs in — the client…
passwordstringYesThe account's password. Write-only: it is accepted here and appears in no response, no log line and no error body.
pathstringNoThe directory the account is confined to, relative to the package root. Defaults to the whole site; narrowing it is how a deployment credential stops being a credential for ever…

Response

NameTypeRequiredWhat it is
idstringYesThe account's identifier at the vendor, used to delete it.
usernamestringYesThe name that signs in. The vendor namespaces it per package on some package types, so this — not what was requested — is what the client shows.
pathstringYesThe directory the account is confined to, relative to the package root. `/` is the whole site.
enabledbooleanYesWhether the account may currently sign in.
is_primarybooleanYesWhether this is the package's own built-in account. It is listed so the customer can see it exists, and it can never be deleted here — removing it takes the package's own access…

Errors this endpoint can return

401 · 403 · 404 · 409 · 422 · 429 · 503