Bootstrap
The bootstrap endpoint is the first step in the POS device activation flow. It acts as a connectivity check and returns the server time and minimum supported POS app version. Call this when the POS device first powers on or connects to the network.
Purpose
- Verify that the device can reach the VioPay API
- Get the current server time (for clock synchronization)
- Get the minimum supported POS app version (to enforce updates)
- Validate that the device exists in the system (pre-provisioned)
Authentication
POS Activation Auth — requires device identification headers only. No Bearer token or signature needed.
| Header | Required | Format | Description |
|---|---|---|---|
X-Device-Id | Yes | POS-{8_HEX_CHARS} | Unique identifier for the physical POS device. Assigned when the device is pre-provisioned by a merchant or reseller. Example: POS-8F3A2C91 |
User-Agent | Yes | Viopay-POS/{version} ({OS}; {model}) | Identifies the POS app version, OS, and hardware model. Must start with Viopay-POS/. Example: Viopay-POS/1.4.2 (Android 12; PAX-A920) |
X-Client-Type | Yes | pos | Client type identifier. Always set to pos for POS devices. |
The device must already be provisioned in the system by a merchant or reseller before calling bootstrap. The X-Device-Id must match an existing device_id in the database.
See the Headers Reference for complete details on all POS headers.
Request
No request body is required. Authentication is entirely header-based.
Response
200 OK
{
"status": "ok",
"server_time": "2025-12-13T14:25:30Z",
"min_supported_version": "1.3.5"
}
| Field | Type | Description |
|---|---|---|
status | string | Always "ok" on success |
server_time | string | Current server time in RFC3339 format |
min_supported_version | string | Minimum POS app version that is supported |
400 Bad Request
Returned when required headers are missing or invalid.
{
"error": {
"code": "4000",
"message": "X-Device-Id header is required",
"trace_id": "abc123..."
}
}
404 Not Found
Returned when the device ID does not exist in the system.
{
"error": {
"code": "4004",
"message": "Device not found",
"details": {
"device_id": "POS-UNKNOWN"
},
"trace_id": "abc123..."
}
}
Code Examples
- cURL
- Python
- Ruby
- Go
- C#
- PHP
- Java
curl -X POST https://api.viopay.io/pos/bootstrap \
-H "X-Device-Id: POS-8F3A2C91" \
-H "User-Agent: Viopay-POS/1.4.2 (Android 12; PAX-A920)" \
-H "X-Client-Type: pos" \
-H "Content-Type: application/json"
import requests
url = "https://api.viopay.io/pos/bootstrap"
headers = {
"X-Device-Id": "POS-8F3A2C91",
"User-Agent": "Viopay-POS/1.4.2 (Android 12; PAX-A920)",
"X-Client-Type": "pos",
"Content-Type": "application/json",
}
response = requests.post(url, headers=headers)
data = response.json()
print(f"Status: {data['status']}")
print(f"Server Time: {data['server_time']}")
print(f"Min Version: {data['min_supported_version']}")
require 'net/http'
require 'json'
require 'uri'
uri = URI("https://api.viopay.io/pos/bootstrap")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri)
request["X-Device-Id"] = "POS-8F3A2C91"
request["User-Agent"] = "Viopay-POS/1.4.2 (Android 12; PAX-A920)"
request["X-Client-Type"] = "pos"
request["Content-Type"] = "application/json"
response = http.request(request)
data = JSON.parse(response.body)
puts "Status: #{data['status']}"
puts "Server Time: #{data['server_time']}"
puts "Min Version: #{data['min_supported_version']}"
package main
import (
"fmt"
"io"
"net/http"
"encoding/json"
)
type BootstrapResponse struct {
Status string `json:"status"`
ServerTime string `json:"server_time"`
MinSupportedVersion string `json:"min_supported_version"`
}
func main() {
req, _ := http.NewRequest("POST", "https://api.viopay.io/pos/bootstrap", nil)
req.Header.Set("X-Device-Id", "POS-8F3A2C91")
req.Header.Set("User-Agent", "Viopay-POS/1.4.2 (Android 12; PAX-A920)")
req.Header.Set("X-Client-Type", "pos")
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
var result BootstrapResponse
json.Unmarshal(body, &result)
fmt.Printf("Status: %s\n", result.Status)
fmt.Printf("Server Time: %s\n", result.ServerTime)
fmt.Printf("Min Version: %s\n", result.MinSupportedVersion)
}
using System.Net.Http;
using System.Text.Json;
var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Post, "https://api.viopay.io/pos/bootstrap");
request.Headers.Add("X-Device-Id", "POS-8F3A2C91");
request.Headers.Add("User-Agent", "Viopay-POS/1.4.2 (Android 12; PAX-A920)");
request.Headers.Add("X-Client-Type", "pos");
var response = await client.SendAsync(request);
var body = await response.Content.ReadAsStringAsync();
var data = JsonSerializer.Deserialize<JsonElement>(body);
Console.WriteLine($"Status: {data.GetProperty("status")}");
Console.WriteLine($"Server Time: {data.GetProperty("server_time")}");
Console.WriteLine($"Min Version: {data.GetProperty("min_supported_version")}");
<?php
$ch = curl_init("https://api.viopay.io/pos/bootstrap");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"X-Device-Id: POS-8F3A2C91",
"User-Agent: Viopay-POS/1.4.2 (Android 12; PAX-A920)",
"X-Client-Type: pos",
"Content-Type: application/json",
],
]);
$response = curl_exec($ch);
curl_close($ch);
$data = json_decode($response, true);
echo "Status: " . $data["status"] . "\n";
echo "Server Time: " . $data["server_time"] . "\n";
echo "Min Version: " . $data["min_supported_version"] . "\n";
import java.net.http.*;
import java.net.URI;
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.viopay.io/pos/bootstrap"))
.POST(HttpRequest.BodyPublishers.noBody())
.header("X-Device-Id", "POS-8F3A2C91")
.header("User-Agent", "Viopay-POS/1.4.2 (Android 12; PAX-A920)")
.header("X-Client-Type", "pos")
.header("Content-Type", "application/json")
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
What's Next?
After a successful bootstrap, the device should proceed to generate a pairing code:
Next step → Generate Pairing Code