Skip to main content

Claim Device

POST /pos/claim

Claims a POS device by entering the pairing code displayed on the device screen. This endpoint is called from the merchant web portal (not the POS device itself). It links the physical device to the merchant's account. This is the fourth step in the POS activation flow.

Purpose

  • Merchant enters the 6-character pairing code from the POS screen into the backoffice portal
  • Validates the pairing code is not expired and not already used
  • Verifies the device belongs to the merchant's account
  • Marks the pairing code as used and updates the device status to claimed

Authentication

Bearer Token — Keycloak JWT. The merchant must be logged in to the backoffice portal.

HeaderRequiredFormatDescription
AuthorizationYesBearer {jwt_token}Keycloak JWT access token obtained via user login or POST /client/session (API client credentials). A session must be initiated via /session/initiate before making merchant-scoped requests. The merchant context is resolved from the token. Example: Bearer eyJhbGciOiJSUzI1NiIs...
Content-TypeYesapplication/jsonRequest body format. Always application/json.
Different caller

Unlike other POS endpoints, this is called by the merchant from the web portal, not by the POS device itself. The merchant must be authenticated with a Bearer token, and the device being claimed must belong to the merchant's account.

See the Headers Reference for complete details.

Request

{
"pairing_code": "K7M3NP"
}
FieldTypeRequiredDescription
pairing_codestringYesThe 6-character code displayed on the POS device screen

Response

200 OK

{
"status": "claimed",
"device_id": "POS-8F3A2C91"
}
FieldTypeDescription
statusstringAlways "claimed" on success
device_idstringThe device ID that was claimed

400 Bad Request — Invalid or Missing Code

{
"error": {
"code": "4000",
"message": "Invalid request body",
"details": {
"message": "Key: 'ClaimDeviceRequest.PairingCode' Error:Field validation for 'PairingCode' failed on the 'required' tag"
},
"trace_id": "abc123..."
}
}

400 Bad Request — Code Not Found

{
"error": {
"code": "4004",
"message": "Pairing code not found",
"details": {
"pairing_code": "XXXXXX"
},
"trace_id": "abc123..."
}
}

400 Bad Request — Code Expired

{
"error": {
"code": "4220",
"message": "Pairing code has expired",
"details": {
"pairing_code": "K7M3NP"
},
"trace_id": "abc123..."
}
}

400 Bad Request — Code Already Used

{
"error": {
"code": "4220",
"message": "Pairing code has already been used",
"details": {
"pairing_code": "K7M3NP"
},
"trace_id": "abc123..."
}
}

403 Forbidden — Device Not Owned

{
"error": {
"code": "4003",
"message": "Device does not belong to your merchant account",
"details": {
"device_id": "POS-8F3A2C91"
},
"trace_id": "abc123..."
}
}

Code Examples

curl -X POST https://api.viopay.io/pos/claim \
-H "Authorization: Bearer eyJhbGciOiJSUzI1NiIs..." \
-H "Content-Type: application/json" \
-d '{"pairing_code": "K7M3NP"}'

What's Next?

Once the device is claimed, the POS device (which has been polling /pos/status) will detect is_claimed: true and proceed to attest its identity:

Next step → Attest