SrvYard
Sign in Start free
features / api-and-webhooks

An API for what you would click, and signed webhooks for what you would watch.

The REST API covers 376 operations over 250 paths and is described by an OpenAPI 3.1 file. Tokens carry scopes, a token never exceeds the role of its owner, and every change is logged with the token’s name. Webhooks send 45 kinds of event as signed JSON.

# who am I? needs no scope
curl -H "Authorization: Bearer $SRVYARD_TOKEN" \
     -H "Accept: application/json" \
     https://your-srvyard-host/api/v1/token

01How every call behaves

the same rules everywhere
RuleWhat it is
Where Under /api/v1 on your SrvYard address. JSON in, JSON out, always send Accept: application/json. The token decides the organisation, so no organisation id is in any URL.
Description OpenAPI 3.1 at /openapi.json, also downloadable from the Reference tab of the API tokens page. Import it into Postman, Insomnia or Bruno.
Authentication Authorization: Bearer srv_.... No cookie or session. GET /api/v1/token says which token, organisation and scopes you are using.
Ids and dates UUIDs and ISO-8601. No internal numeric ids. A secret that SrvYard generates (a database password, a backup passphrase) is returned once, in the response that created it.
Lists page, per_page (default 25, at most 100), sort (a leading - is descending) and filter[field]=a,b. An unknown filter or sort field is a 422 that lists the allowed ones.
Background work Anything that needs the server answers 202 Accepted with the resource and a status_url. Poll it until the status is final.
Errors RFC 9457 application/problem+json with a stable code such as missing_scope, plan_required, plan_limit (402) or rate_limited. Every response carries X-Request-Id.
Retries Send Idempotency-Key on POST, PUT, PATCH and DELETE. The same key and body within 24 hours replays the first answer; the same key with another body is a 409.
Rate limit 60 requests a minute per token, 10 for heavy operations (scans, exports, installs). 429 carries Retry-After.
Versions A breaking change would ship as /api/v2. A retired operation gets the Deprecation and Sunset headers and deprecated: true in the file.

A resource of another organisation answers 404, never 403, so a token cannot be used to find out which ids exist elsewhere. If a team limits the token owner to some servers, lists contain only those.

API conventions, in the docs · Your first calls: servers, sites, deployments

02Tokens and scopes

Settings, API tokens

A token belongs to you and works in one organisation. Its scopes are permission keys, the same ones the Roles page uses, such as servers:view or sites:manage-deploys. It can use only the scopes you tick and only those your role also holds; demote the owner and the token loses the extra power on its next call.

  • Expiry: 30 days, 90 days, 1 year, 10 years (the default) or never.
  • Presets: Read-only ticks every :view scope, Full ticks everything your role holds.
  • The secret starts with srv_ and is shown once. SrvYard stores a hash, so nobody can read it back.
  • Reading or writing a site’s .env needs its own scope, sites:manage-environment, so a deploy token does not get secrets by accident.
  • Revoking is immediate and permanent; the next call gets a 401.

Name a token after the job, not the person: the name is what the activity log records as token:<name>.

The Reference tab of the API tokens page, listing the deployment operations with their method, path and the scope each one needs
fig 1The Reference tab: every operation with its method, path and required scope. Search by word or by scope.
JobScopes
Deploy one pipeline sites:view, sites:manage-deploys
Show server health on a wallboard servers:view, resources:view
Read and edit a site’s .env sites:view, sites:manage-environment

03Webhooks

Settings, Webhooks
The Webhooks page: one active webhook that hears three events and one that SrvYard switched off after repeated failures
fig 2One row per endpoint: its events, status and the result of the last 24 hours. The second one was switched off after repeated failures.

A webhook is SrvYard calling your code when something happens in the organisation: a deployment finishes, a certificate fails to renew, a server disconnects. It sends a POST with a JSON body to an https address you choose, for the events you tick. All events is on by default and includes events added later.

  • https only. An address with a user name or password, a blocked port, or one that resolves to a private network is refused. Redirects are not followed. The address is stored encrypted.
  • Up to 20 webhooks per organisation. The signing secret (whsec_...) is shown once; Rotate secret gives a new one and the old one keeps verifying for 24 hours.
  • Answer with a 2xx within 10 seconds. SrvYard keeps the first 2 KB of your answer for the history.
  • Secrets, passwords, tokens and .env values are never in a payload.
HeaderContent
X-SrvYard-Event The event key, for example deployment.finished.
X-SrvYard-Delivery The id of this delivery. A redelivery gets a new one.
X-SrvYard-Timestamp Unix seconds at which the request was signed.
X-SrvYard-Signature t=<timestamp>,v1=<hex>: HMAC-SHA256 of <timestamp>.<raw body> with the signing secret. While a rotated secret is valid there are two v1 values; accept either.

The body is always the same envelope: id (evt_..., identical across retries, so use it to skip duplicates), type, created_at, the organization and a data object. To verify: read the raw body before anything parses it, compute the HMAC for each v1, compare in constant time, and reject a timestamp more than five minutes from your clock. The usual reason a correct secret fails is a body that was re-encoded before hashing.

04The 45 events

the same keys notifications use
GroupEvents
Servers (8) server.created, server.provisioned, server.failed, server.disconnected, server.reconnected, server.rebooted, server.archived, server.deleted
Sites (5) site.created, site.installed, site.failed, site.deleted, site.down
Deployments (5) deployment.started, deployment.finished, deployment.failed, deployment.cancelled, deployment.rolled_back
Certificates and domains (7) certificate.issued, certificate.failed, certificate.expiring, certificate.renewed, domain.added, domain.removed, domain.dns_verified
Backups and snapshots (5) backup.finished, backup.failed, backup.restored, snapshot.created, snapshot.failed
Monitoring (4) monitor.alert, monitor.recovered, heartbeat.missed, heartbeat.recovered
Databases (2) database.created, database.deleted
Recipes and imports (3) recipe.finished, migration.scan_finished, migration.adoption_finished
Team and access (6) member.invited, member.joined, member.removed, api_token.created, api_token.revoked, credentials.downloaded

GET /api/v1/events returns the same list with an example data for each. Send test event on a webhook posts a webhook.test event so you can see your code work without waiting for a real deployment.

05When your endpoint fails

retries and switch-off
  1. Success

    Any 2xx within 10 seconds. Anything else is a failed attempt.

  2. Retried

    A timeout, a 5xx, 408 or 429: after 1 minute, 5 minutes, 30 minutes, 2 hours, 6 hours, 12 hours and 24 hours, eight attempts in all. A longer Retry-After on a 429 or 503 wins.

  3. Not retried

    Any other 4xx. It is a “no” from your code and would get the same answer.

  4. Switched off

    After 10 failed deliveries in a row, the first of them at least three days old, the webhook is switched off and the owners and admins are told by email and in the app. Fix the endpoint, choose Switch on, and the counters restart.

  5. History

    Each webhook keeps its deliveries for 30 days: status, HTTP code, duration, attempts, the request that went out and the first 2 KB of the answer. Redeliver sends the same event again as a new delivery.

06Plans and limits

from the plan catalogue

API access is on Pro and Business; webhooks are on Pro and Business. Without them every API call answers 403 with plan_required and the Webhooks page says it is not in the plan. Tokens keep existing after a downgrade but stop working until the plan has the API again. Compare plans.

What is not here: there is no command line tool (use the dashboard or the API), and webhooks are per organisation. A site can also have channels of its own, including a signed webhook for that site’s deployment events (up to 10 channels per site). For messages to people rather than JSON for programs, see notifications.

07Read more

08API and webhook questions

answers from the docs
Which plans include the API and webhooks?

Pro and Business. On Hobby every API call is answered 403 with the code plan_required, and the Webhooks page says it is not in your plan. See Compare plans and know your limits.

Is there an OpenAPI file?

Yes, OpenAPI 3.1, served at /openapi.json on your SrvYard address and downloadable from the Reference tab of the API tokens page. Import it into Postman, Insomnia or Bruno. See Create an API token and pick scopes.

Can a token do more than I can?

No. A token carries scopes you pick, and it can never do more than the role of its owner allows in that organisation. If the owner is demoted, the token loses the extra power on its next call. See Create an API token and pick scopes.

How do I deploy from CI and wait for the result?

Call POST /api/v1/sites/{site}/deployments with a token that has sites:manage-deploys. It answers 202 with a status_url; poll it until the status is finished, failed or cancelled. A deploy hook is simpler when you do not need to wait. See Deploy from GitHub Actions and other CI.

How do I check that a webhook really came from SrvYard?

Compute an HMAC-SHA256 of <timestamp>.<raw body> with the webhook's signing secret and compare it with each v1 value in the X-SrvYard-Signature header in constant time. Reject a timestamp more than five minutes from your clock. See Receive event webhooks and verify their signatures.

What happens when my endpoint is down?

A timeout, a 5xx, 408 or 429 is retried up to eight attempts in all, from one minute to 24 hours apart. After ten failed deliveries in a row, the first at least three days old, the webhook is switched off and the owners and admins are told. See Receive event webhooks and verify their signatures.

What are the API rate limits?

A token may make 60 requests a minute, and 10 a minute for heavier operations such as scans, exports and installs. A 429 answer carries a Retry-After header. See API conventions for authentication, pages, errors and rate limits.

Create a token with one scope and call it from a script.

Free: 1 server, 3 sites, 100 deploys a month. Read the docs first if you prefer.