Use the VPSNine OpenAPI spec
Download the OpenAPI 3.1 description of the VPSNine API, generate a typed client with openapi-generator, and import the API into Postman, Insomnia or Bruno.
The VPSNine API is described by an OpenAPI 3.1 document at my.vpsnine.com/api/openapi.json (and openapi.yaml). Point a code generator or an API client at that URL to get every endpoint, its parameters, its answers and its errors, with bearer-token authentication already set up.
What you need
- An API token. Read-only is enough to explore.
- For generating a client: Docker, or Java 11 or later with Node.js for the npm wrapper.
What's in the document
It's built from the same table as the API reference, and a test holds both to the real routes, so the spec can't list an endpoint that doesn't exist or miss one that does.
servers:https://my.vpsnine.com/api/v1.- A
bearerAuthsecurity scheme on every operation exceptGET /pricesandGET /status. - Named schemas for requests and answers (
Server,NewServer,Firewall,Snapshot,Invoiceand the rest), and theErrorshape every failure uses. - The
X-Request-IdandX-RateLimit-*headers on every answer, and theIdempotency-KeyandIf-Matchrequest headers where they apply. - Three extensions on each operation:
x-scope(read or write),x-error-codes(the codes it can answer) andx-cli(the vps9 command that does the same, when there is one).
info.version is the date of the newest API changelog entry.
Download it:
curl -sO https://my.vpsnine.com/api/openapi.json
jq -r '.info.version, (.paths | length)' openapi.jsonThe file is served with Access-Control-Allow-Origin: *, so browser-based tools can load it by URL too.
Generate a client with openapi-generator
openapi-generator writes clients for many languages from the spec. Use version 7.20.0 or later: older 7.x releases misread nullable fields ("type": ["string", "null"]) inside inline schemas, and the generated Python client then refuses a server whose ipv6 or label is null.
With Docker:
docker run --rm -v "$PWD:/local" openapitools/openapi-generator-cli:v7.20.0 generate \
-i /local/openapi.json -g python -o /local/vps9-client --package-name vps9_clientOr with the npm wrapper, which downloads the Java generator for you:
npx @openapitools/openapi-generator-cli version-manager set 7.20.0
npx @openapitools/openapi-generator-cli generate \
-i openapi.json -g python -o vps9-client --package-name vps9_clientInstall it and call the API. Every tag in the spec becomes a class (ServersApi, SnapshotsApi, FirewallApi …) and every operationId a method:
python3 -m venv .venv && . .venv/bin/activate
pip install ./vps9-clientimport os
import vps9_client
config = vps9_client.Configuration(
host=os.environ.get("VPS9_API_URL", "https://my.vpsnine.com/api/v1"),
access_token=os.environ["VPS9_TOKEN"],
)
with vps9_client.ApiClient(config) as client:
servers = vps9_client.ServersApi(client).list_servers()
for s in servers.data:
print(s.hostname, s.state, s.ipv4)
try:
vps9_client.ServersApi(client).get_server("srv_doesnotexist")
except vps9_client.ApiException as e:
print(e.status, e.body)We generated this client with 7.20.0 and ran the script against a local copy of the API: it listed the servers, and the second call printed 404 with the JSON error and its request id. Other generators (-g go, -g typescript-fetch, -g ruby and so on) read the same document; check the result against a read-only token before you trust it with writes.
For TypeScript and JavaScript there's a VPSNine SDK made from this spec, with retries and idempotency keys built in, so you may not need to generate one.
Import into Postman, Insomnia or Bruno
All three import OpenAPI 3 documents and make one request per endpoint, grouped by tag:
- Postman: Import, then paste
https://my.vpsnine.com/api/openapi.json. - Insomnia: Import, then From URL, with the same address.
- Bruno: Import Collection, then OpenAPI V3 Spec, and pick the downloaded
openapi.json.
Then give the collection your token once. The spec's bearer scheme becomes the collection's auth: set it to Bearer Token with a variable such as {{vps9_token}}, and keep the token in an environment or secret variable rather than in the collection itself, so exporting or sharing the collection never shares the token.
Requests that change something (POST, PUT, DELETE) are real. Use a read-only token while you explore, and a read-and-write one only when you mean it.
Check it worked
Send Who am I (GET /me) from the generated client or the imported collection. A 200 with your email means the base URL and the token are right. A 401 means the token isn't being sent: look at the auth settings of the collection or the access_token of the client.
Troubleshooting
ValidationError … Input should be a valid string … input_value=None in a generated Python client. The generator is older than 7.20.0. Regenerate with 7.20.0 or later.
Every request answers 415 unsupported_media_type. The tool is sending the body as a form. Set the body type to JSON, which adds Content-Type: application/json.
404 on every request. The base URL is missing /api/v1. It should be https://my.vpsnine.com/api/v1.
Next steps
- API quickstart for the same calls in curl, JavaScript, Python, the SDK and the CLI.
- Rate limits and request ids for generated clients that loop.
- The developer hub, and the plans the API orders.