Skip to main content
The exy.sh API lets your own code do most of what the dashboard does. It lives at https://api.exy.sh/v1.
  • Servers: list and read them, start, stop and restart them, reinstall, rename and delete them, set the login password, open a browser console and read their usage.
  • Ordering and billing: list locations, plans and images, price a server, order it paid from your balance, renew it, switch auto-renew, upgrade it and buy a new IPv4 address. Read your balance, orders, invoices and balance history.
  • Firewall, snapshots and backups: manage a server’s inbound rules, take and restore snapshots and backups.
  • SSH keys and scheduled tasks: keep your account’s SSH keys, schedule restarts, shutdowns, starts and snapshots.
  • Webhooks: get a signed request when a server is ready, suspended, released or deleted, or when an order is refunded.
  • Support tickets: open tickets, read them and reply.
The full reference with every endpoint, field and response is at api.exy.sh/v1/docs. The machine-readable OpenAPI document is at api.exy.sh/v1/openapi.json.

Order and renew servers

Quote, order from your balance, renew, upgrade and change the IP.

Webhooks

Events, signature verification and retries.

Resellers and WHMCS

Reseller status, discount, your own references and the WHMCS module.

Get a token

1

Open Settings → API

In the dashboard, go to Settings and open the API tab.
2

Create a token

Click Create token, give it a name you’ll recognise (for example the tool or server that uses it), pick only the scopes it needs and choose when it expires: after 30, 90, 180 or 365 days.
3

Copy it now

The token starts with exy_ and is shown exactly once. Store it in your secret manager or environment, for example as EXY_API_TOKEN.
Send it with every request as a header:
A token acts as you, within its scopes. Use it from your servers and scripts only, never in code that runs in a browser: the API sends no CORS headers and does not accept dashboard sessions.
  • Expiry: we email you a week before a token expires. Tokens are never renewed automatically; create a new one and switch over before the old one stops working.
  • Rotation: create the new token, deploy it, then revoke the old one. Two valid tokens at once are fine.
  • Revoke a token in Settings → API. It stops working with the next request.
  • Password reset: resetting your password revokes all tokens you created.
  • Teams: a token created in a team acts on the team’s account within your team role. If you leave the team or your role no longer allows a scope, the token loses that access immediately.

Scopes

Each endpoint in the reference names the scope it needs. A request without it is answered with 403. A token with billing.manage can only be created by a member who has two-factor authentication turned on. GET /v1/account works with any scope and shows the token’s name, scopes and expiry.

Limits

A request over a rate limit is answered with 429 and a Retry-After header that says how many seconds to wait. Wait at least that long before you try again. The daily order limit answers DAILY_ORDER_LIMIT_EXCEEDED, and its Retry-After can be up to 24 hours. All amounts in the API are whole euro cents: 1299 is 12.99 EUR.

Errors

Every error has the same shape:
Use code in your code; message is for people and may change.

Example with curl

List your servers, restart one and follow the action until it finishes:
An action is pending, then running, and ends as completed or failed. A failed action may carry a failureCode: after graceful_timeout the guest did not shut down in time and force_stop or force_restart works; after proxmox_busy or lease_lost, try again.

Example with TypeScript

The OpenAPI document generates a fully typed client with openapi-typescript and openapi-fetch. Generate the types once, and again whenever you want new endpoints:
Paths, parameters, request bodies and responses are all typed: a wrong action name or a missing field is a compile error.

Compatibility

Within /v1 we only add: new endpoints, new optional request fields and new response fields. Ignore response fields you don’t know. We announce new values of an existing list, such as a new server status, before they appear. Anything else comes as /v2.