Authentication
Initialize your client using the overview examples, then choose an authentication method.
Basic
Authentication using HTTP Basic. The username and password are passed in an HTTP header. This method must not be used from web browsers.
Examples
Ruby · Simple
require 'haveapi/client'
api = HaveAPI::Client.new("https://api.vpsfree.cz/", version: "7.0")
api.authenticate(:basic, user: 'user', password: 'secret')
Ruby · With error handling
begin
require 'haveapi/client'
api = HaveAPI::Client.new("https://api.vpsfree.cz/", version: "7.0")
api.setup
api.authenticate(:basic, user: 'user', password: 'secret')
rescue HaveAPI::Client::ValidationError => error
warn error.message
warn error.errors.inspect
rescue HaveAPI::Client::ActionFailed => error
warn error.message
warn error.response.errors.inspect if error.response.is_a?(HaveAPI::Client::Response)
rescue HaveAPI::Client::Authentication::AuthenticationFailed, HaveAPI::Client::ProtocolError,
RestClient::Exception, JSON::ParserError => error
warn error.message
end
JavaScript (callback) · Simple
import { CallbackClient } from "haveapi-client";
const api = new CallbackClient("https://api.vpsfree.cz/", {version: "7.0"});
api.authenticate("basic", {user: "user", password: "secret"}, (api, ready) => {
if (!ready) {
console.error("Discovery or authentication failed");
return;
}
});
JavaScript (async) · Simple
import { AsyncClient } from "haveapi-client";
const api = new AsyncClient("https://api.vpsfree.cz/", {version: "7.0"});
await api.authenticate("basic", {user: "user", password: "secret"});
JavaScript (async) · With error handling
import { AsyncClient, AsyncError } from "haveapi-client";
async function main() {
const api = new AsyncClient("https://api.vpsfree.cz/", {version: "7.0"});
try {
await api.authenticate("basic", {user: "user", password: "secret"});
console.log("Authenticated");
} catch (error) {
if (error instanceof AsyncError) {
console.error(error.kind, error.message, error.errors);
} else {
throw error;
}
}
}
main().catch(error => console.error(error));
TypeScript (callback) · Simple
import { CallbackClient } from "haveapi-client";
const api = new CallbackClient("https://api.vpsfree.cz/", {version: "7.0"});
api.authenticate("basic", {user: "user", password: "secret"}, (api, ready) => {
if (!ready) {
console.error("Discovery or authentication failed");
return;
}
});
TypeScript (async) · Simple
import { AsyncClient } from "haveapi-client";
const api = new AsyncClient("https://api.vpsfree.cz/", {version: "7.0"});
await api.authenticate("basic", {user: "user", password: "secret"});
TypeScript (async) · With error handling
import { AsyncClient, AsyncError } from "haveapi-client";
async function main(): Promise<void> {
const api = new AsyncClient("https://api.vpsfree.cz/", {version: "7.0"});
try {
await api.authenticate("basic", {user: "user", password: "secret"});
console.log("Authenticated");
} catch (error) {
if (error instanceof AsyncError) {
console.error(error.kind, error.message, error.errors);
} else {
throw error;
}
}
}
main().catch(error => console.error(error));
Python (sync) · Simple
from haveapi_client import Client, BasicAuth
with Client("https://api.vpsfree.cz/", version="7.0", auth=BasicAuth("user", "secret")) as api:
# Call API actions inside this block.
pass
Python (sync) · With error handling
from haveapi_client import Client, ActionError, HaveAPIError, BasicAuth
try:
with Client("https://api.vpsfree.cz/", version="7.0", auth=BasicAuth("user", "secret")) as api:
print("Authenticated")
except ActionError as error:
print(error.message, error.errors)
except HaveAPIError as error:
print(error.message, error.status_code)
Python (async) · Simple
import asyncio
from haveapi_client import AsyncClient, BasicAuth
async def main() -> None:
async with AsyncClient("https://api.vpsfree.cz/", version="7.0", auth=BasicAuth("user", "secret")) as api:
# Call API actions inside this block.
pass
asyncio.run(main())
Python (async) · With error handling
import asyncio
from haveapi_client import AsyncClient, ActionError, HaveAPIError, BasicAuth
async def main() -> None:
try:
async with AsyncClient("https://api.vpsfree.cz/", version="7.0", auth=BasicAuth("user", "secret")) as api:
print("Authenticated")
except ActionError as error:
print(error.message, error.errors)
except HaveAPIError as error:
print(error.message, error.status_code)
asyncio.run(main())
Go API client · Simple
// go get github.com/vpsfreecz/vpsadmin-go-client/client@latest
package main
import (
client "github.com/vpsfreecz/vpsadmin-go-client/client"
)
func main() {
api := client.New("https://api.vpsfree.cz")
api.SetBasicAuthentication("user", "secret")
}
Rust API client (async) · Simple
// cargo add vpsadmin-client
// cargo add tokio --features macros,rt-multi-thread
// cargo add serde_json
use vpsadmin_client::Client;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let api = Client::builder("https://api.vpsfree.cz/")
.basic_auth("user", "secret")
.build()?;
// Configure existing credentials only; building does not validate them with the server.
let _ = &api;
Ok(())
}
Rust API client (async) · With error handling
// cargo add vpsadmin-client
// cargo add tokio --features macros,rt-multi-thread
// cargo add serde_json
use vpsadmin_client::Client;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let api = match Client::builder("https://api.vpsfree.cz/")
.basic_auth("user", "secret")
.build() {
Ok(api) => api,
Err(error) => {
eprintln!("Client configuration failed: {}", error);
eprintln!("HTTP status: {:?}; timeout: {}", error.http_status(), error.is_timeout());
return Err(error.into());
}
};
// Configure existing credentials only; building does not validate them with the server.
let _ = &api;
Ok(())
}
Rust API client (blocking) · Simple
// cargo add vpsadmin-client --features blocking
// cargo add serde_json
// Construct, use and drop this blocking client outside async runtime threads.
use vpsadmin_client::blocking::Client;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let api = Client::builder("https://api.vpsfree.cz/")
.basic_auth("user", "secret")
.build()?;
// Configure existing credentials only; building does not validate them with the server.
let _ = &api;
Ok(())
}
Rust API client (blocking) · With error handling
// cargo add vpsadmin-client --features blocking
// cargo add serde_json
// Construct, use and drop this blocking client outside async runtime threads.
use vpsadmin_client::blocking::Client;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let api = match Client::builder("https://api.vpsfree.cz/")
.basic_auth("user", "secret")
.build() {
Ok(api) => api,
Err(error) => {
eprintln!("Client configuration failed: {}", error);
eprintln!("HTTP status: {:?}; timeout: {}", error.http_status(), error.is_timeout());
return Err(error.into());
}
};
// Configure existing credentials only; building does not validate them with the server.
let _ = &api;
Ok(())
}
TypeScript API client · Simple
// Configured API client: vpsadmin-typescript-client.
import { AsyncClient } from "haveapi-client";
import { createClient } from "vpsadmin-typescript-client";
async function main(): Promise<void> {
const runtime = new AsyncClient("https://api.vpsfree.cz/v7.0");
await runtime.authenticate("basic", { user: "user", password: "secret" });
const api = createClient({ execute: spec => runtime.request(spec) });
void api;
}
main().catch(error => { throw error; });
TypeScript API client · With error handling
// Configured API client: vpsadmin-typescript-client.
import { AsyncClient, AsyncError } from "haveapi-client";
import { createClient } from "vpsadmin-typescript-client";
async function main(): Promise<void> {
try {
const runtime = new AsyncClient("https://api.vpsfree.cz/v7.0");
await runtime.authenticate("basic", { user: "user", password: "secret" });
const api = createClient({ execute: spec => runtime.request(spec) });
void api;
} catch (error) {
if (!(error instanceof AsyncError)) throw error;
console.error(error.kind, error.httpStatus);
throw error;
}
}
main().catch(error => { throw error; });
PHP · Simple
$api = new \HaveAPI\Client('https://api.vpsfree.cz/', '7.0');
$api->authenticate('basic', ['user' => 'user', 'password' => 'secret']);
PHP · With error handling
try {
$api = new \HaveAPI\Client('https://api.vpsfree.cz/', '7.0');
$api->setup();
$api->authenticate('basic', ['user' => 'user', 'password' => 'secret']);
} catch (\HaveAPI\Client\Exception\ValidationError $error) {
echo $error->getMessage() . "\n";
print_r($error->getErrors());
} catch (\HaveAPI\Client\Exception\ActionFailed $error) {
echo $error->getMessage() . "\n";
print_r($error->getErrors());
} catch (\HaveAPI\Client\Exception\Base $error) {
echo $error->getMessage() . "\n";
} catch (\Exception $error) {
// Dependency failures still propagate to the application.
echo $error->getMessage() . "\n";
throw $error;
}
CLI · Simple
# Provide credentials on command line
$ haveapi-cli -u https://api.vpsfree.cz/ --version 7.0 --auth basic --user user --password secret
# If username or password isn't provided, the user is asked on stdin
$ haveapi-cli -u https://api.vpsfree.cz/ --version 7.0 --auth basic --user user
# Password: secret
curl · Simple
# Password is asked on standard input
$ curl --request OPTIONS \
--user user \
https://api.vpsfree.cz/
# Password: secret
# Password given on the command line
$ curl --request OPTIONS \
--user user:secret \
https://api.vpsfree.cz/
HTTP · Simple
GET / HTTP/1.1
Host: api.vpsfree.cz
Authorization: Basic dXNlcjpzZWNyZXQ=
Token
The client authenticates with credentials, usually a username and password, and receives a token. From that point on, the credentials can be forgotten and the token is used instead. Tokens can have different lifetimes and can be renewed or revoked. The token is passed either in an HTTP header or as a query parameter.
Resources
Token
Manage authentication tokens
Renew
Request
Input parameters
| Parameter | Type | Required | Details | ||||||
|---|---|---|---|---|---|---|---|---|---|
userUser |
String | yes |
Default:
|
||||||
passwordPassword |
String | yes |
Auto-generated password Default:
|
||||||
scopeScope |
String | no |
Default: |
||||||
lifetimeLifetime |
String | yes |
fixed - the token has a fixed validity period and cannot be renewed renewable_manual - the token can be renewed, but only manually using the renew action renewable_auto - the token is renewed automatically to now + interval whenever it is used permanent - the token is valid forever unless deleted Default:
|
||||||
intervalInterval |
Integer | no |
How long the requested token will be valid, in seconds. Default:
|
Output parameters
| Parameter | Type | Description |
|---|---|---|
tokenToken |
String | Authentication token |
valid_toValid_to |
Datetime | |
completeComplete |
Boolean | |
next_actionNext_action |
String |
Reset_password
Input parameters
| Parameter | Type | Required | Details | ||||
|---|---|---|---|---|---|---|---|
tokenToken |
String | yes |
Authentication token Default:
|
||||
new_password1New password |
String | yes |
Default:
|
||||
new_password2Repeat new password |
String | yes |
Default:
|
Output parameters
| Parameter | Type | Description |
|---|---|---|
tokenToken |
String | Authentication token |
valid_toValid_to |
Datetime | |
completeComplete |
Boolean | |
next_actionNext_action |
String |
Revoke
Totp
Input parameters
| Parameter | Type | Required | Details | ||||
|---|---|---|---|---|---|---|---|
tokenToken |
String | yes |
Authentication token Default:
|
||||
codeTOTP code |
String | yes |
Default:
|
Output parameters
| Parameter | Type | Description |
|---|---|---|
tokenToken |
String | Authentication token |
valid_toValid_to |
Datetime | |
completeComplete |
Boolean | |
next_actionNext_action |
String |
Examples
Ruby · Simple
require 'haveapi/client'
api = HaveAPI::Client.new("https://api.vpsfree.cz/", version: "7.0")
api.authenticate(:token, **{user: "user", password: "secret", scope: "scope", lifetime: "fixed"}) do |action, parameters|
continuations = {"totp" => {"code" => "code"}, "reset_password" => {"new_password1" => "new_password1", "new_password2" => "new_password2"}}
input = continuations.fetch(action.to_s) { raise ArgumentError, 'Unknown authentication continuation' }
unless (parameters.keys.map(&:to_s) - input.keys - ['token']).empty?
raise ArgumentError, 'Unknown authentication input'
end
input.transform_keys(&:to_sym)
end
# Reuse an existing token
api.authenticate(:token, token: 'example-token')
Ruby · With error handling
begin
require 'haveapi/client'
api = HaveAPI::Client.new("https://api.vpsfree.cz/", version: "7.0")
api.setup
api.authenticate(:token, **{user: "user", password: "secret", scope: "scope", lifetime: "fixed"}) do |action, parameters|
continuations = {"totp" => {"code" => "code"}, "reset_password" => {"new_password1" => "new_password1", "new_password2" => "new_password2"}}
input = continuations.fetch(action.to_s) { raise ArgumentError, 'Unknown authentication continuation' }
unless (parameters.keys.map(&:to_s) - input.keys - ['token']).empty?
raise ArgumentError, 'Unknown authentication input'
end
input.transform_keys(&:to_sym)
end
# Reuse an existing token
api.authenticate(:token, token: 'example-token')
rescue HaveAPI::Client::ValidationError => error
warn error.message
warn error.errors.inspect
rescue HaveAPI::Client::ActionFailed => error
warn error.message
warn error.response.errors.inspect if error.response.is_a?(HaveAPI::Client::Response)
rescue HaveAPI::Client::Authentication::AuthenticationFailed, HaveAPI::Client::ProtocolError,
RestClient::Exception, JSON::ParserError => error
warn error.message
end
JavaScript (callback) · Simple
import { CallbackClient } from "haveapi-client";
const api = new CallbackClient("https://api.vpsfree.cz/", {version: "7.0"});
api.authenticate("token", {["user"]: "user",
["password"]: "secret",
["scope"]: "scope",
["lifetime"]: "fixed",
callback: (action, parameters) => {
const continuations = {["totp"]: {["code"]: "code"}, ["reset_password"]: {["new_password1"]: "new_password1", ["new_password2"]: "new_password2"}};
if (!Object.prototype.hasOwnProperty.call(continuations, action)) throw new Error("Unknown authentication continuation");
const input = continuations[action];
for (const name of Object.keys(parameters)) {
if (name !== "token" && !Object.prototype.hasOwnProperty.call(input, name)) throw new Error("Unknown authentication input");
}
return input;
}}, (api, ready) => {
if (!ready) {
console.error("Discovery or authentication failed");
return;
}
});
JavaScript (async) · Simple
import { AsyncClient } from "haveapi-client";
const api = new AsyncClient("https://api.vpsfree.cz/", {version: "7.0"});
await api.authenticate("token", {["user"]: "user",
["password"]: "secret",
["scope"]: "scope",
["lifetime"]: "fixed",
onChallenge: (action, parameters) => {
const continuations = {["totp"]: {["code"]: "code"}, ["reset_password"]: {["new_password1"]: "new_password1", ["new_password2"]: "new_password2"}};
if (!Object.prototype.hasOwnProperty.call(continuations, action)) throw new Error("Unknown authentication continuation");
const input = continuations[action];
for (const name of Object.keys(parameters)) {
if (name !== "token" && !Object.prototype.hasOwnProperty.call(input, name)) throw new Error("Unknown authentication input");
}
return input;
}});
JavaScript (async) · With error handling
import { AsyncClient, AsyncError } from "haveapi-client";
async function main() {
const api = new AsyncClient("https://api.vpsfree.cz/", {version: "7.0"});
try {
await api.authenticate("token", {["user"]: "user",
["password"]: "secret",
["scope"]: "scope",
["lifetime"]: "fixed",
onChallenge: (action, parameters) => {
const continuations = {["totp"]: {["code"]: "code"}, ["reset_password"]: {["new_password1"]: "new_password1", ["new_password2"]: "new_password2"}};
if (!Object.prototype.hasOwnProperty.call(continuations, action)) throw new Error("Unknown authentication continuation");
const input = continuations[action];
for (const name of Object.keys(parameters)) {
if (name !== "token" && !Object.prototype.hasOwnProperty.call(input, name)) throw new Error("Unknown authentication input");
}
return input;
}});
console.log("Authenticated");
} catch (error) {
if (error instanceof AsyncError) {
console.error(error.kind, error.message, error.errors);
} else {
throw error;
}
}
}
main().catch(error => console.error(error));
TypeScript (callback) · Simple
import { CallbackClient } from "haveapi-client";
const api = new CallbackClient("https://api.vpsfree.cz/", {version: "7.0"});
api.authenticate("token", {["user"]: "user",
["password"]: "secret",
["scope"]: "scope",
["lifetime"]: "fixed",
callback: (action, parameters) => {
const continuations: Record<string, Record<string, unknown>> = {["totp"]: {["code"]: "code"}, ["reset_password"]: {["new_password1"]: "new_password1", ["new_password2"]: "new_password2"}};
if (!Object.prototype.hasOwnProperty.call(continuations, action)) throw new Error("Unknown authentication continuation");
const input = continuations[action];
for (const name of Object.keys(parameters)) {
if (name !== "token" && !Object.prototype.hasOwnProperty.call(input, name)) throw new Error("Unknown authentication input");
}
return input;
}}, (api, ready) => {
if (!ready) {
console.error("Discovery or authentication failed");
return;
}
});
TypeScript (async) · Simple
import { AsyncClient } from "haveapi-client";
const api = new AsyncClient("https://api.vpsfree.cz/", {version: "7.0"});
await api.authenticate("token", {["user"]: "user",
["password"]: "secret",
["scope"]: "scope",
["lifetime"]: "fixed",
onChallenge: (action, parameters) => {
const continuations: Record<string, Record<string, unknown>> = {["totp"]: {["code"]: "code"}, ["reset_password"]: {["new_password1"]: "new_password1", ["new_password2"]: "new_password2"}};
if (!Object.prototype.hasOwnProperty.call(continuations, action)) throw new Error("Unknown authentication continuation");
const input = continuations[action];
for (const name of Object.keys(parameters)) {
if (name !== "token" && !Object.prototype.hasOwnProperty.call(input, name)) throw new Error("Unknown authentication input");
}
return input;
}});
TypeScript (async) · With error handling
import { AsyncClient, AsyncError } from "haveapi-client";
async function main(): Promise<void> {
const api = new AsyncClient("https://api.vpsfree.cz/", {version: "7.0"});
try {
await api.authenticate("token", {["user"]: "user",
["password"]: "secret",
["scope"]: "scope",
["lifetime"]: "fixed",
onChallenge: (action, parameters) => {
const continuations: Record<string, Record<string, unknown>> = {["totp"]: {["code"]: "code"}, ["reset_password"]: {["new_password1"]: "new_password1", ["new_password2"]: "new_password2"}};
if (!Object.prototype.hasOwnProperty.call(continuations, action)) throw new Error("Unknown authentication continuation");
const input = continuations[action];
for (const name of Object.keys(parameters)) {
if (name !== "token" && !Object.prototype.hasOwnProperty.call(input, name)) throw new Error("Unknown authentication input");
}
return input;
}});
console.log("Authenticated");
} catch (error) {
if (error instanceof AsyncError) {
console.error(error.kind, error.message, error.errors);
} else {
throw error;
}
}
}
main().catch(error => console.error(error));
Python (sync) · Simple
from haveapi_client import Client, AuthenticationChallenge
with Client("https://api.vpsfree.cz/", version="7.0") as api:
continuations = {"totp": {"code": "code"}, "reset_password": {"new_password1": "new_password1", "new_password2": "new_password2"}}
step = api.begin_token_login({"user": "user", "password": "secret", "scope": "scope", "lifetime": "fixed"})
while isinstance(step, AuthenticationChallenge):
if step.next_action not in continuations:
raise ValueError("Unknown authentication continuation")
values = continuations[step.next_action]
if any(name != "token" and name not in values for name in step.input):
raise ValueError("Unknown authentication input")
step = step.submit(values)
Python (sync) · With error handling
from haveapi_client import Client, ActionError, HaveAPIError, AuthenticationChallenge
try:
with Client("https://api.vpsfree.cz/", version="7.0") as api:
continuations = {"totp": {"code": "code"}, "reset_password": {"new_password1": "new_password1", "new_password2": "new_password2"}}
step = api.begin_token_login({"user": "user", "password": "secret", "scope": "scope", "lifetime": "fixed"})
while isinstance(step, AuthenticationChallenge):
if step.next_action not in continuations:
raise ValueError("Unknown authentication continuation")
values = continuations[step.next_action]
if any(name != "token" and name not in values for name in step.input):
raise ValueError("Unknown authentication input")
step = step.submit(values)
print("Authenticated")
except ActionError as error:
print(error.message, error.errors)
except HaveAPIError as error:
print(error.message, error.status_code)
Python (async) · Simple
import asyncio
from haveapi_client import AsyncClient, AsyncAuthenticationChallenge
async def main() -> None:
async with AsyncClient("https://api.vpsfree.cz/", version="7.0") as api:
continuations = {"totp": {"code": "code"}, "reset_password": {"new_password1": "new_password1", "new_password2": "new_password2"}}
step = await api.begin_token_login({"user": "user", "password": "secret", "scope": "scope", "lifetime": "fixed"})
while isinstance(step, AsyncAuthenticationChallenge):
if step.next_action not in continuations:
raise ValueError("Unknown authentication continuation")
values = continuations[step.next_action]
if any(name != "token" and name not in values for name in step.input):
raise ValueError("Unknown authentication input")
step = await step.submit(values)
asyncio.run(main())
Python (async) · With error handling
import asyncio
from haveapi_client import AsyncClient, ActionError, HaveAPIError, AsyncAuthenticationChallenge
async def main() -> None:
try:
async with AsyncClient("https://api.vpsfree.cz/", version="7.0") as api:
continuations = {"totp": {"code": "code"}, "reset_password": {"new_password1": "new_password1", "new_password2": "new_password2"}}
step = await api.begin_token_login({"user": "user", "password": "secret", "scope": "scope", "lifetime": "fixed"})
while isinstance(step, AsyncAuthenticationChallenge):
if step.next_action not in continuations:
raise ValueError("Unknown authentication continuation")
values = continuations[step.next_action]
if any(name != "token" and name not in values for name in step.input):
raise ValueError("Unknown authentication input")
step = await step.submit(values)
print("Authenticated")
except ActionError as error:
print(error.message, error.errors)
except HaveAPIError as error:
print(error.message, error.status_code)
asyncio.run(main())
Go API client · Simple
// go get github.com/vpsfreecz/vpsadmin-go-client/client@latest
package main
import (
client "github.com/vpsfreecz/vpsadmin-go-client/client"
)
func main() {
api := client.New("https://api.vpsfree.cz")
api.SetExistingTokenAuth("example-token")
// Use a token obtained through the advertised authentication provider.
}
Rust API client (async) · Simple
// cargo add vpsadmin-client
// cargo add tokio --features macros,rt-multi-thread
// cargo add serde_json
use vpsadmin_client::Client;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let api = Client::builder("https://api.vpsfree.cz/")
.token("example-token")
.build()?;
// Configure existing credentials only; building does not validate them with the server.
let _ = &api;
Ok(())
}
Rust API client (async) · With error handling
// cargo add vpsadmin-client
// cargo add tokio --features macros,rt-multi-thread
// cargo add serde_json
use vpsadmin_client::Client;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let api = match Client::builder("https://api.vpsfree.cz/")
.token("example-token")
.build() {
Ok(api) => api,
Err(error) => {
eprintln!("Client configuration failed: {}", error);
eprintln!("HTTP status: {:?}; timeout: {}", error.http_status(), error.is_timeout());
return Err(error.into());
}
};
// Configure existing credentials only; building does not validate them with the server.
let _ = &api;
Ok(())
}
Rust API client (blocking) · Simple
// cargo add vpsadmin-client --features blocking
// cargo add serde_json
// Construct, use and drop this blocking client outside async runtime threads.
use vpsadmin_client::blocking::Client;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let api = Client::builder("https://api.vpsfree.cz/")
.token("example-token")
.build()?;
// Configure existing credentials only; building does not validate them with the server.
let _ = &api;
Ok(())
}
Rust API client (blocking) · With error handling
// cargo add vpsadmin-client --features blocking
// cargo add serde_json
// Construct, use and drop this blocking client outside async runtime threads.
use vpsadmin_client::blocking::Client;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let api = match Client::builder("https://api.vpsfree.cz/")
.token("example-token")
.build() {
Ok(api) => api,
Err(error) => {
eprintln!("Client configuration failed: {}", error);
eprintln!("HTTP status: {:?}; timeout: {}", error.http_status(), error.is_timeout());
return Err(error.into());
}
};
// Configure existing credentials only; building does not validate them with the server.
let _ = &api;
Ok(())
}
TypeScript API client · Simple
// Configured API client: vpsadmin-typescript-client.
import { AsyncClient } from "haveapi-client";
import { createClient } from "vpsadmin-typescript-client";
async function main(): Promise<void> {
const runtime = new AsyncClient("https://api.vpsfree.cz/v7.0");
await runtime.authenticate("token", { token: "example-token" });
const api = createClient({ execute: spec => runtime.request(spec) });
void api;
}
main().catch(error => { throw error; });
TypeScript API client · With error handling
// Configured API client: vpsadmin-typescript-client.
import { AsyncClient, AsyncError } from "haveapi-client";
import { createClient } from "vpsadmin-typescript-client";
async function main(): Promise<void> {
try {
const runtime = new AsyncClient("https://api.vpsfree.cz/v7.0");
await runtime.authenticate("token", { token: "example-token" });
const api = createClient({ execute: spec => runtime.request(spec) });
void api;
} catch (error) {
if (!(error instanceof AsyncError)) throw error;
console.error(error.kind, error.httpStatus);
throw error;
}
}
main().catch(error => { throw error; });
PHP · Simple
$api = new \HaveAPI\Client('https://api.vpsfree.cz/', '7.0');
// Get token using username and password
$api->authenticate('token', [
'user' => 'user',
'password' => 'secret',
'scope' => 'scope',
'lifetime' => 'fixed',
'callback' => function ($action, $token, $parameters) {
$continuations = ['totp' => ['code' => 'code'], 'reset_password' => ['new_password1' => 'new_password1', 'new_password2' => 'new_password2']];
if (!array_key_exists($action, $continuations)) {
throw new \InvalidArgumentException('Unknown authentication continuation');
}
$input = $continuations[$action];
foreach (array_keys((array) $parameters) as $name) {
if ($name !== 'token' && !array_key_exists($name, $input)) {
throw new \InvalidArgumentException('Unknown authentication input');
}
}
return $input;
}
]);
// Next time, the client can authenticate using the token directly
$api->authenticate('token', ['token' => 'example-token']);
PHP · With error handling
try {
$api = new \HaveAPI\Client('https://api.vpsfree.cz/', '7.0');
$api->setup();
// Get token using username and password
$api->authenticate('token', [
'user' => 'user',
'password' => 'secret',
'scope' => 'scope',
'lifetime' => 'fixed',
'callback' => function ($action, $token, $parameters) {
$continuations = ['totp' => ['code' => 'code'], 'reset_password' => ['new_password1' => 'new_password1', 'new_password2' => 'new_password2']];
if (!array_key_exists($action, $continuations)) {
throw new \InvalidArgumentException('Unknown authentication continuation');
}
$input = $continuations[$action];
foreach (array_keys((array) $parameters) as $name) {
if ($name !== 'token' && !array_key_exists($name, $input)) {
throw new \InvalidArgumentException('Unknown authentication input');
}
}
return $input;
}
]);
// Next time, the client can authenticate using the token directly
$api->authenticate('token', ['token' => 'example-token']);
} catch (\HaveAPI\Client\Exception\ValidationError $error) {
echo $error->getMessage() . "\n";
print_r($error->getErrors());
} catch (\HaveAPI\Client\Exception\ActionFailed $error) {
echo $error->getMessage() . "\n";
print_r($error->getErrors());
} catch (\HaveAPI\Client\Exception\Base $error) {
echo $error->getMessage() . "\n";
} catch (\Exception $error) {
// Dependency failures still propagate to the application.
echo $error->getMessage() . "\n";
throw $error;
}
CLI · Simple
# Get token using username and password and save it to disk
# Note that the client always has to call some action. APIs should provide
# an action to get information about the current user, so that's what we're
# calling now.
$ haveapi-cli -u https://api.vpsfree.cz/ --version 7.0 --auth token --user user --scope scope --lifetime fixed --save user current
# Password: secret
# Now the token is read from disk and the user does not have to provide username
# nor password and be authenticated
$ haveapi-cli -u https://api.vpsfree.cz/ --version 7.0 user current
curl · Simple
# Acquire the token
$ curl --request POST \
--header 'Content-Type: application/json' \
--data-binary \{\"token\":\{\"user\":\"user\",\"password\":\"secret\",\"scope\":\"scope\",\"lifetime\":\"fixed\"\}\} \
https://api.vpsfree.cz/_auth/token/tokens
# Use a previously acquired token
$ curl --request OPTIONS \
--header X-HaveAPI-Auth-Token:\ example-token \
https://api.vpsfree.cz/
HTTP · Simple
POST /_auth/token/tokens HTTP/1.1
Host: api.vpsfree.cz
Content-Type: application/json
{
"token": {
"user": "user",
"password": "secret",
"scope": "scope",
"lifetime": "fixed"
}
}
Oauth2
OAuth2 authorization provider. HaveAPI clients have limited OAuth2 support, but the API can be used as an authentication source and OAuth2 tokens can be used to access it. HaveAPI partially implements RFC 6749: authorization response type "code" and token grant types "authorization_code" and "refresh_token". Other response and grant types are not supported at this time. The access token can be passed as a bearer token according to RFC 6750, or using a custom HTTP header when the Authorization header is not practical. Access and refresh tokens can be revoked according to RFC 7009.
Examples
Ruby · Simple
# OAuth2 is not supported by HaveAPI Ruby client.
JavaScript (callback) · Simple
// Use an existing access token; this client does not run an OAuth authorization flow.
import { CallbackClient } from "haveapi-client";
const api = new CallbackClient("https://api.vpsfree.cz/", {version: "7.0"});
api.authenticate("oauth2", {access_token: {access_token: "example-access-token"}}, (api, ready) => {
if (!ready) {
console.error("Discovery or authentication failed");
return;
}
});
JavaScript (async) · Simple
// Use an existing access token; this client does not run an OAuth authorization flow.
import { AsyncClient } from "haveapi-client";
const api = new AsyncClient("https://api.vpsfree.cz/", {version: "7.0"});
await api.authenticate("oauth2", {access_token: {access_token: "example-access-token"}});
JavaScript (async) · With error handling
// Use an existing access token; this client does not run an OAuth authorization flow.
import { AsyncClient, AsyncError } from "haveapi-client";
async function main() {
const api = new AsyncClient("https://api.vpsfree.cz/", {version: "7.0"});
try {
await api.authenticate("oauth2", {access_token: {access_token: "example-access-token"}});
console.log("Authenticated");
} catch (error) {
if (error instanceof AsyncError) {
console.error(error.kind, error.message, error.errors);
} else {
throw error;
}
}
}
main().catch(error => console.error(error));
TypeScript (callback) · Simple
// Use an existing access token; this client does not run an OAuth authorization flow.
import { CallbackClient } from "haveapi-client";
const api = new CallbackClient("https://api.vpsfree.cz/", {version: "7.0"});
api.authenticate("oauth2", {access_token: {access_token: "example-access-token"}}, (api, ready) => {
if (!ready) {
console.error("Discovery or authentication failed");
return;
}
});
TypeScript (async) · Simple
// Use an existing access token; this client does not run an OAuth authorization flow.
import { AsyncClient } from "haveapi-client";
const api = new AsyncClient("https://api.vpsfree.cz/", {version: "7.0"});
await api.authenticate("oauth2", {access_token: {access_token: "example-access-token"}});
TypeScript (async) · With error handling
// Use an existing access token; this client does not run an OAuth authorization flow.
import { AsyncClient, AsyncError } from "haveapi-client";
async function main(): Promise<void> {
const api = new AsyncClient("https://api.vpsfree.cz/", {version: "7.0"});
try {
await api.authenticate("oauth2", {access_token: {access_token: "example-access-token"}});
console.log("Authenticated");
} catch (error) {
if (error instanceof AsyncError) {
console.error(error.kind, error.message, error.errors);
} else {
throw error;
}
}
}
main().catch(error => console.error(error));
Python (sync) · Simple
# Use an existing access token; OAuth acquisition and refresh are outside this client.
from haveapi_client import Client, OAuth2Auth
with Client("https://api.vpsfree.cz/", version="7.0", auth=OAuth2Auth("example-access-token")) as api:
# Call API actions inside this block.
pass
Python (sync) · With error handling
# Use an existing access token; OAuth acquisition and refresh are outside this client.
from haveapi_client import Client, ActionError, HaveAPIError, OAuth2Auth
try:
with Client("https://api.vpsfree.cz/", version="7.0", auth=OAuth2Auth("example-access-token")) as api:
print("Authenticated")
except ActionError as error:
print(error.message, error.errors)
except HaveAPIError as error:
print(error.message, error.status_code)
Python (async) · Simple
# Use an existing access token; OAuth acquisition and refresh are outside this client.
import asyncio
from haveapi_client import AsyncClient, OAuth2Auth
async def main() -> None:
async with AsyncClient("https://api.vpsfree.cz/", version="7.0", auth=OAuth2Auth("example-access-token")) as api:
# Call API actions inside this block.
pass
asyncio.run(main())
Python (async) · With error handling
# Use an existing access token; OAuth acquisition and refresh are outside this client.
import asyncio
from haveapi_client import AsyncClient, ActionError, HaveAPIError, OAuth2Auth
async def main() -> None:
try:
async with AsyncClient("https://api.vpsfree.cz/", version="7.0", auth=OAuth2Auth("example-access-token")) as api:
print("Authenticated")
except ActionError as error:
print(error.message, error.errors)
except HaveAPIError as error:
print(error.message, error.status_code)
asyncio.run(main())
Go API client · Simple
// go get github.com/vpsfreecz/vpsadmin-go-client/client@latest
package main
import (
client "github.com/vpsfreecz/vpsadmin-go-client/client"
)
func main() {
api := client.New("https://api.vpsfree.cz")
api.SetExistingOAuth2Auth("example-access-token")
// Obtain the access token through the OAuth2 provider before running this program.
}
Rust API client (async) · Simple
// cargo add vpsadmin-client
// cargo add tokio --features macros,rt-multi-thread
// cargo add serde_json
use vpsadmin_client::Client;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let api = Client::builder("https://api.vpsfree.cz/")
.oauth2_token("example-access-token")
.build()?;
// Configure existing credentials only; building does not validate them with the server.
let _ = &api;
Ok(())
}
Rust API client (async) · With error handling
// cargo add vpsadmin-client
// cargo add tokio --features macros,rt-multi-thread
// cargo add serde_json
use vpsadmin_client::Client;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let api = match Client::builder("https://api.vpsfree.cz/")
.oauth2_token("example-access-token")
.build() {
Ok(api) => api,
Err(error) => {
eprintln!("Client configuration failed: {}", error);
eprintln!("HTTP status: {:?}; timeout: {}", error.http_status(), error.is_timeout());
return Err(error.into());
}
};
// Configure existing credentials only; building does not validate them with the server.
let _ = &api;
Ok(())
}
Rust API client (blocking) · Simple
// cargo add vpsadmin-client --features blocking
// cargo add serde_json
// Construct, use and drop this blocking client outside async runtime threads.
use vpsadmin_client::blocking::Client;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let api = Client::builder("https://api.vpsfree.cz/")
.oauth2_token("example-access-token")
.build()?;
// Configure existing credentials only; building does not validate them with the server.
let _ = &api;
Ok(())
}
Rust API client (blocking) · With error handling
// cargo add vpsadmin-client --features blocking
// cargo add serde_json
// Construct, use and drop this blocking client outside async runtime threads.
use vpsadmin_client::blocking::Client;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let api = match Client::builder("https://api.vpsfree.cz/")
.oauth2_token("example-access-token")
.build() {
Ok(api) => api,
Err(error) => {
eprintln!("Client configuration failed: {}", error);
eprintln!("HTTP status: {:?}; timeout: {}", error.http_status(), error.is_timeout());
return Err(error.into());
}
};
// Configure existing credentials only; building does not validate them with the server.
let _ = &api;
Ok(())
}
TypeScript API client · Simple
This sample is unavailable or incompatible with the configured TypeScript API client.
PHP · Simple
// OAuth2 requires session
session_start();
// Client instance
$api = new \HaveAPI\Client('https://api.vpsfree.cz/', '7.0');
// Check if we already have an access token
if (isset($_SESSION['access_token'])) {
// We're already authenticated, reuse the existing access token
$api->authenticate('oauth2', ['access_token' => $_SESSION['access_token']]);
} else {
// Follow the OAuth2 authorization process to get an access token using
// authorization code
$api->authenticate('oauth2', [
// Client id and secret are given by the API server
'client_id' => 'example-client',
'client_secret' => 'example-client-secret',
// This example code should run on the URL below
'redirect_uri' => 'https://your-client.tld/oauth2-callback',
// Scopes are specific to the API implementation
'scope' => 'all',
]);
$provider = $api->getAuthenticationProvider();
// We don't have authorization code yet, request one
if (!isset($_GET['code'])) {
// Redirect the user to the authorization endpoint
$provider->requestAuthorizationCode();
exit;
} else {
// Request access token using the token endpoint
$provider->requestAccessToken();
// Store the access token in the session
$_SESSION['access_token'] = $provider->jsonSerialize();
}
}
PHP · With error handling
try {
// OAuth2 requires session
session_start();
// Client instance
$api = new \HaveAPI\Client('https://api.vpsfree.cz/', '7.0');
$api->setup();
// Check if we already have an access token
if (isset($_SESSION['access_token'])) {
// We're already authenticated, reuse the existing access token
$api->authenticate('oauth2', ['access_token' => $_SESSION['access_token']]);
} else {
// Follow the OAuth2 authorization process to get an access token using
// authorization code
$api->authenticate('oauth2', [
// Client id and secret are given by the API server
'client_id' => 'example-client',
'client_secret' => 'example-client-secret',
// This example code should run on the URL below
'redirect_uri' => 'https://your-client.tld/oauth2-callback',
// Scopes are specific to the API implementation
'scope' => 'all',
]);
$provider = $api->getAuthenticationProvider();
// We don't have authorization code yet, request one
if (!isset($_GET['code'])) {
// Redirect the user to the authorization endpoint
$provider->requestAuthorizationCode();
exit;
} else {
// Request access token using the token endpoint
$provider->requestAccessToken();
// Store the access token in the session
$_SESSION['access_token'] = $provider->jsonSerialize();
}
}
} catch (\HaveAPI\Client\Exception\ValidationError $error) {
echo $error->getMessage() . "\n";
print_r($error->getErrors());
} catch (\HaveAPI\Client\Exception\ActionFailed $error) {
echo $error->getMessage() . "\n";
print_r($error->getErrors());
} catch (\HaveAPI\Client\Exception\Base $error) {
echo $error->getMessage() . "\n";
} catch (\Exception $error) {
// Dependency failures still propagate to the application.
echo $error->getMessage() . "\n";
throw $error;
}
CLI · Simple
# OAuth2 is not supported by HaveAPI Ruby CLI.
curl · Simple
# See RFC 6749 for authorization process and RFC 6750 for access token usage.
HTTP · Simple
# 1) Request authorization code
GET /_auth/oauth2/authorize?response_type=code&client_id=example-client&state=example-state&redirect_uri=https%3A%2F%2Fexample.org%2Fcallback HTTP/1.1
Host: api.vpsfree.cz
# 2) The user logs in using this API
# 3) The API then redirects the user back to the client application
GET /callback?code=example-code&state=example-state
Host: client-application
# 4) The client application requests access token
POST /_auth/oauth2/token
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code&code=example-code&redirect_uri=https%3A%2F%2Fexample.org%2Fcallback&client_id=example-client&client_secret=example-client-secret