Status
Checks whether a POS device has been claimed by a merchant after generating a pairing code. The POS device should poll this endpoint at regular intervals (e.g., every 3–5 seconds) until the device is claimed or the pairing code expires. This is the third step in the POS activation flow.
Purpose
- Check the current device status (
inactive,claimed,activated) - Determine if the pairing code has been used, is still pending, or has expired
- The POS device uses this to know when to proceed to the attestation step
Authentication
POS Activation Auth — device identification headers only.
| Header | Required | Format | Description |
|---|---|---|---|
X-Device-Id | Yes | POS-{8_HEX_CHARS} | Unique identifier for the physical POS device. Must match a pre-provisioned device. Example: POS-8F3A2C91 |
User-Agent | Yes | Viopay-POS/{version} ({OS}; {model}) | POS app version string. Must start with Viopay-POS/. Example: Viopay-POS/1.4.2 (Android 12; PAX-A920) |
X-Client-Type | Yes | pos | Client type identifier. Always pos for POS devices. |
See the Headers Reference for complete details.
Request
No request body or query parameters required.
Response
200 OK
{
"device_status": "claimed",
"is_claimed": true,
"pairing_code_status": "used"
}
| Field | Type | Description |
|---|---|---|
device_status | string | Current device status: inactive, claimed, or activated |
is_claimed | boolean | true if the device has been claimed by a merchant |
pairing_code_status | string | Status of the latest pairing code (see table below) |
Pairing Code Statuses:
| Status | Meaning |
|---|---|
pending | Code is active, waiting for merchant to enter it |
used | Merchant has entered the code — device is claimed |
expired | Code expired (5 min passed) — generate a new one |
none | No pairing code has been generated for this device |
Poll every 3–5 seconds while pairing_code_status is "pending". Once is_claimed becomes true, stop polling and proceed to attestation. If pairing_code_status becomes "expired", generate a new pairing code.
404 Not Found
{
"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 GET https://api.viopay.io/pos/status \
-H "X-Device-Id: POS-8F3A2C91" \
-H "User-Agent: Viopay-POS/1.4.2 (Android 12; PAX-A920)" \
-H "X-Client-Type: pos"
import requests
import time
url = "https://api.viopay.io/pos/status"
headers = {
"X-Device-Id": "POS-8F3A2C91",
"User-Agent": "Viopay-POS/1.4.2 (Android 12; PAX-A920)",
"X-Client-Type": "pos",
}
# Poll until claimed or expired
while True:
response = requests.get(url, headers=headers)
data = response.json()
print(f"Status: {data['device_status']}, Claimed: {data['is_claimed']}")
if data["is_claimed"]:
print("Device claimed! Proceeding to attestation...")
break
if data["pairing_code_status"] == "expired":
print("Pairing code expired. Generate a new one.")
break
time.sleep(3)
require 'net/http'
require 'json'
require 'uri'
uri = URI("https://api.viopay.io/pos/status")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
loop do
request = Net::HTTP::Get.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"
response = http.request(request)
data = JSON.parse(response.body)
puts "Status: #{data['device_status']}, Claimed: #{data['is_claimed']}"
break if data["is_claimed"]
break if data["pairing_code_status"] == "expired"
sleep 3
end
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"time"
)
type POSStatusResponse struct {
DeviceStatus string `json:"device_status"`
IsClaimed bool `json:"is_claimed"`
PairingCodeStatus string `json:"pairing_code_status"`
}
func main() {
client := &http.Client{}
for {
req, _ := http.NewRequest("GET", "https://api.viopay.io/pos/status", 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")
resp, err := client.Do(req)
if err != nil {
panic(err)
}
body, _ := io.ReadAll(resp.Body)
resp.Body.Close()
var result POSStatusResponse
json.Unmarshal(body, &result)
fmt.Printf("Status: %s, Claimed: %v\n", result.DeviceStatus, result.IsClaimed)
if result.IsClaimed {
fmt.Println("Device claimed! Proceeding to attestation...")
break
}
if result.PairingCodeStatus == "expired" {
fmt.Println("Pairing code expired. Generate a new one.")
break
}
time.Sleep(3 * time.Second)
}
}
using System.Net.Http;
using System.Text.Json;
var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-Device-Id", "POS-8F3A2C91");
client.DefaultRequestHeaders.Add("User-Agent", "Viopay-POS/1.4.2 (Android 12; PAX-A920)");
client.DefaultRequestHeaders.Add("X-Client-Type", "pos");
while (true)
{
var response = await client.GetAsync("https://api.viopay.io/pos/status");
var body = await response.Content.ReadAsStringAsync();
var data = JsonSerializer.Deserialize<JsonElement>(body);
var isClaimed = data.GetProperty("is_claimed").GetBoolean();
var pairingStatus = data.GetProperty("pairing_code_status").GetString();
Console.WriteLine($"Claimed: {isClaimed}, Pairing: {pairingStatus}");
if (isClaimed) { Console.WriteLine("Proceeding to attestation..."); break; }
if (pairingStatus == "expired") { Console.WriteLine("Code expired."); break; }
await Task.Delay(3000);
}
<?php
$headers = [
"X-Device-Id: POS-8F3A2C91",
"User-Agent: Viopay-POS/1.4.2 (Android 12; PAX-A920)",
"X-Client-Type: pos",
];
while (true) {
$ch = curl_init("https://api.viopay.io/pos/status");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => $headers,
]);
$response = curl_exec($ch);
curl_close($ch);
$data = json_decode($response, true);
echo "Status: {$data['device_status']}, Claimed: " . ($data['is_claimed'] ? 'true' : 'false') . "\n";
if ($data["is_claimed"]) { echo "Proceeding to attestation...\n"; break; }
if ($data["pairing_code_status"] === "expired") { echo "Code expired.\n"; break; }
sleep(3);
}
import java.net.http.*;
import java.net.URI;
import com.google.gson.*;
HttpClient client = HttpClient.newHttpClient();
while (true) {
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.viopay.io/pos/status"))
.GET()
.header("X-Device-Id", "POS-8F3A2C91")
.header("User-Agent", "Viopay-POS/1.4.2 (Android 12; PAX-A920)")
.header("X-Client-Type", "pos")
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonObject data = JsonParser.parseString(response.body()).getAsJsonObject();
boolean isClaimed = data.get("is_claimed").getAsBoolean();
String pairingStatus = data.get("pairing_code_status").getAsString();
System.out.printf("Claimed: %s, Pairing: %s%n", isClaimed, pairingStatus);
if (isClaimed) { System.out.println("Proceeding to attestation..."); break; }
if ("expired".equals(pairingStatus)) { System.out.println("Code expired."); break; }
Thread.sleep(3000);
}
What's Next?
Once is_claimed is true, the POS device should proceed to attest its identity. But first, the merchant must claim the device via the web portal:
Merchant step → Claim Device (web portal)
POS next step → Attest