List servers and sites and trigger actions through the API
Most automation against SrvYard boils down to a handful of calls: find the server or site, start something, wait until it finishes and read the result. This article shows that loop with real requests, and tells you where to look in the dashboard's Reference tab for everything beyond it.
You will list your servers and sites, read a single one, create a site, queue a deployment from a script, stream its log and roll back when a release is bad. Every call names the scope it needs, so you can build a token that does exactly this and nothing more.
Before you begin
- A token. Create one as described in Create an API token and pick scopes. For this article
servers:view,sites:viewandsites:manage-deploysare enough; creating a site also needssites:create. - The rules every call follows. Pagination, errors,
202answers and rate limits are explained once in API conventions, and not repeated here. - A shell with
curl. Put the token in an environment variable and use the base URL from the Using the API card of your own account:
export SRVYARD_TOKEN="srv_your_token_here"
export SRVYARD="https://srvyard.example/api/v1"
A token works in one organisation and only sees what the role of its owner can see. If the owner is limited to certain servers and sites through a team, lists contain only those, and everything else answers 404.
1. Find your servers
The Reference tab groups operations by area. Open Servers to see all of them at once.
GET /serverswith the scopeservers:viewlists servers. It includes archived servers too: filter onstatusto separate them.POST /servers/{server}/rebootis typical of the actions. It needsservers:reboot, carries the async badge (it answers202and finishes later) and takes an optionalmethodin its body.GET /servers/{server}/operationslists what has been run on a server, newest first. Its sibling.../operations/{log}/outputreturns the redacted output of one operation, in chunks: pass theoffsetof the previous answer to read only what is new.
List them, sorted by name, only the ready ones:
curl -s -G -H "Authorization: Bearer $SRVYARD_TOKEN" -H "Accept: application/json" \
--data-urlencode "filter[status]=ready" "$SRVYARD/servers"
Each server in data has an id (a UUID), name, provider, region, ip_address, status (pending, creating, installing, ready, disconnected, installation_failed, rebooting, deleting or archived), php_version, database_engine, sites_count, last_connected_at and more. Keep the id: other calls take it. A server's status tells you whether it is worth calling actions: POST /servers/{server}/check, for instance, verifies that SrvYard can log in to a server that is ready or disconnected.
Other operations in the group you will want sooner or later: POST /servers to add a server, PATCH /servers/{server} to rename it or change its notes and timezone, POST /servers/{server}/check to verify the connection, and PUT /servers/{server}/mute to silence alerts during maintenance. DELETE is there too; treat it like the red button in the dashboard.
2. Find and read your sites
Open the Sites group.
POST /sitescreates a site (scopesites:create). It is async and counts as an expensive operation: ten requests a minute per token.GET /sites/{site}reads one site. This is also the status document of an installation: poll it untilstatusisreadyorfailed;progress,progress_stepandlast_errorsay where it is.POST /sites/{site}/retryresumes a failed installation from the first step that did not finish (scopesites:manage-project). Only a site whosestatusisfailedcan be retried.
curl -s -G -H "Authorization: Bearer $SRVYARD_TOKEN" -H "Accept: application/json" \
--data-urlencode "filter[server]=<server-id>" "$SRVYARD/sites"
GET /sites can be filtered by name (contains), status, type and server, and sorted by name or created_at. A site shows its domains, type, php_version, branch, repository, zero_downtime, push_to_deploy and force_https. It never shows the .env file, the deploy key or the deploy hook token; those have their own operations with stricter scopes.
3. Create a site
The request body is the same as the New site wizard in the dashboard, with the same validation and the same plan limit. Open the operation in the Reference tab to see every field.
- async. The answer is
202; the site installs in the background. - Request body. Four fields are required:
server,type,www_redirectandrepository_source. A red star marks them. Fields that belong to another site type are ignored. Passwords in the body are write-only and are never returned.
curl -s -X POST -H "Authorization: Bearer $SRVYARD_TOKEN" -H "Accept: application/json" \
-H "Content-Type: application/json" -H "Idempotency-Key: create-shop-1" \
-d '{
"server": "<server-id>",
"type": "laravel",
"domain_mode": "custom",
"domain": "shop.acme-studio.example",
"www_redirect": "none",
"php_version": "8.4",
"repository_source": "none"
}' \
"$SRVYARD/sites"
Keep the Idempotency-Key: if the call times out you can send it again with the same key and no second site is created. The answer contains the new site and a status_url; poll it every few seconds until status is ready.
As in the dashboard, the root directory, zero downtime, website isolation and a repository-less setup cannot be changed after the site exists. Check the body before you send it. See Create a site on your server for what each choice means.
4. Deploy, follow the log and roll back
Open the Deployments group.
POST /sites/{site}/deploymentsqueues a deployment through the same action as the Deploy button. Scopesites:manage-deploys.GET /deployments/{deployment}/logreturns the output as the dashboard shows it. Secrets are masked when a line is written.POST /deployments/{deployment}/rollbackpoints the site back at the release of that deployment.
A deploy script for CI, with a retry-safe key:
deployment=$(curl -s -X POST -H "Authorization: Bearer $SRVYARD_TOKEN" -H "Accept: application/json" \
-H "Idempotency-Key: deploy-$GITHUB_SHA" \
"$SRVYARD/sites/<site-id>/deployments")
echo "$deployment"
The answer is 202 with the deployment (data.id, data.status, data.branch, data.commit_hash ...) and a status_url. Poll it until status is finished, failed or cancelled (queued and running are the in-between states).
Reading the log is a loop, because a long deployment grows while you read it.
sites:view. A token that may only read can follow a deployment, but not start one.offset. Byte position to read from;0(the default) starts at the beginning.- The response.
contentis the text,next_offsetis where to continue,completeturnstruewhen there is nothing more to come. A chunk is at most 400 KB.
curl -s -G -H "Authorization: Bearer $SRVYARD_TOKEN" -H "Accept: application/json" \
--data-urlencode "offset=0" "$SRVYARD/deployments/<deployment-id>/log"
To go back, call rollback on the deployment you want to return to. It works on zero-downtime sites only, runs no script, and creates a new deployment with the trigger rollback that you poll like any other. Each deployment carries rollback_blocked_reason when it cannot be a rollback target. To stop a run, POST /deployments/{deployment}/cancel stops a queued or running deployment and leaves the previous release live; a deployment that has already ended answers 422.
Related operations in the same group: GET /sites/{site}/deploy-script and PUT to change the script, PUT /sites/{site}/push-to-deploy, and GET /sites/{site}/deploy-hook which returns the secret hook URL and so needs sites:manage-deploys.
Troubleshooting
403 missing_scopeon a deploy. The token hassites:viewbut notsites:manage-deploys. Create a new token with both.404for a site you can open in the dashboard. The token belongs to another organisation, or its owner's team does not include that site.422when you create a site. The message names the field. The same rules apply as in the wizard: a ready server that runs Nginx, a free subdomain or a domain, a PHP version for PHP sites.402 plan_limit. The plan allows no more sites or servers. Archive or delete one, or change plan.- The deployment sticks at
queued. The server may be busy or disconnected. Check the server'sstatusand read its operations. See The server will not connect. - The deployment
failed. Read the log through the endpoint above and find the first error. See A deployment failed. - Rollback is refused. The site does not use zero-downtime releases, or that deployment cannot be a rollback target. Read
rollback_blocked_reason.
Related
- API conventions: pages, filters,
202polling, errors and idempotency. - Create an API token and pick scopes: build the narrow token these calls need.
- Deploy from GitHub Actions and other CI: put the deploy call in a pipeline.
- Zero-downtime releases and rollbacks: why a rollback needs releases.