PowerAuth Cloud Multi-Device API Reference
When deploying the multi-device (v2
) version of the PowerAuth Cloud API, multiple devices are allowed per a particular user.
This PowerAuth Multi-Device API allows following use cases:
single device
: the same basic use case as the Single-Device APImultiple devices
: the mobile application runs on multiple user devices, multiple registrations are allowed per user
The PowerAuth Multi-Device API consists of two major API resource groups:
- The Registrations Services handle use-cases related to the user device registration, such as enrolling a new device, blocking the registration, or permanent registration removal.
- The Services for Operations are responsible for creating operations, such as login requests or payment approvals, and for managing the operation state.
This documentation covers both the general principles of PowerAuth Cloud Multi-Device API, as well as specific services in each API category.
The PowerAuth application is always derived from credentials which are used when accessing the REST API, so the API can be used with multiple PowerAuth applications by switching REST API credentials.
Content Type
All services expect to work with the JSON request and response. Use Content-Type: application/json
header when calling the services:
Content-Type: application/json
Error Handling
In the case of an error, all endpoints will return the response in the following base format:
{
"status": "ERROR",
"responseObject": {
"code": "${ERROR_CODE}",
"message": "${ERROR_MESSAGE}"
}
}
Attribute | Type | Description |
---|---|---|
status * |
String |
Always the ERROR string. |
responseObject.code * |
String |
Error code. |
responseObject.message * |
String |
Error message with more info about the issue. |
Failing the Basic Request Validation
If request validation fails on the syntactic level, the service will return 400 Bad Request
response with the following extended structure:
{
"status": "ERROR",
"responseObject": {
"code": "ERROR_REQUEST",
"message": "Required Long parameter 'timestampFrom' is invalid",
"violations": [
{
"fieldName": "getAuditLog.timestampFrom",
"invalidValue": -1000,
"hint": "must be greater than or equal to 0"
}
]
}
}
Attribute | Type | Description |
---|---|---|
status * |
String |
Always the ERROR string. |
responseObject.code * |
String |
Error code, always the value ERROR_REQUEST . |
responseObject.message * |
String |
Information about the violation. |
responseObject.violations |
Object[] |
Information about the specific fields that were invalid. |
responseObject.violations[].fieldName * |
String |
Field name. |
responseObject.violations[].invalidValue * |
- |
The invalid value that was provided. |
responseObject.violations[].hint * |
String |
Hint on why the validation failed. |
Possible Error Codes
The API may return one of the following error codes:
HTTP | Error Code | Description |
---|---|---|
400 |
ERROR_REGISTRATION |
Registration related error occurred. |
400 |
ERROR_REGISTRATION_NOT_FOUND |
Registration was not found during a call where registration is expected. |
400 |
ERROR_REGISTRATION_NOT_ALLOWED |
Registration was not allowed because another registration is already in progress for the user. |
400 |
ERROR_REGISTRATION_CHANGE |
Invalid registration change was attempted. |
400 |
ERROR_OPERATION_NOT_FOUND |
Operation was not found during a call where operation is expected. |
400 |
ERROR_OPERATION_STATE_CHANGE |
Invalid operation change was attempted. |
400 |
ERROR_OTP_INVALID |
Offline certification - OTP format is invalid. |
400 |
ERROR_AUDIT |
Error occurred while fetching the audit log. |
400 |
ERROR_REQUEST |
Request did not pass validation (mandatory property missing, null/invalid value). |
401 |
ERROR_UNAUTHORIZED |
Returned in the case authentication fails (invalid application credentials). |
404 |
ERROR_NOT_FOUND |
Returned in the case URL is not present (calling wrong API). |
500 |
ERROR_GENERIC |
Unknown error occurred while processing request. |
500 |
ERROR_INTERNAL_API |
Communication with internal service failed. |
Security
All services are protected by the Basic HTTP authentication. Failure to provide correct username or password will result in the 401 Unauthorized
error with the following response body:
{
"status": "ERROR",
"responseObject": {
"code": "HTTP_401",
"message": "Unauthorized"
}
}
Services for Registrations
To bind mobile device with a particular user ID, the user needs to create a registration. Registration is created via an “activation code”. After the user scans the code, the registration needs to be committed. At any point, you can obtain the registration status for a user with given user ID and registration ID.
post /v2/registrations Create New Registration
Initiate a new registration for provided user ID. The service returns a fully prepared content for the registration QR code - you can simply grab the response and encode it using your preferred QR code generator library.
If you want to allow manual code entry as well in your app, you can split the activationQrCodeData
by the #
character and use the first part of the split. The part after the #
is a data signature that helps the mobile device recognize an authentic QR code data while scanning the code.
Request
{
"userId": "$USER_ID",
"flags": ["$FLAG"]
}
Request Params
Attribute | Type | Description |
---|---|---|
userId * |
String |
ID of a user for whom to create new registration. |
flags |
String[] |
Flags which should be stored together with the registration record. |
Response
During successful registration, the API will return the activation code data. You can map the activationQrCodeData
attribute in the response directly to the QR code data. Additionally, a registrationId
value is returned which can be used later on when referring to the registration record. In PowerAuth server this value is stored as the activationId
record.
{
"activationQrCodeData": "23456-DEFGH-77777-77777#MEUCIDFFx60vcqDcqRY014uE+5CH38lJ/NOVNoaGHWpE+7fVAiEA8LsWi9AvRJPwRnlSSOB3O080mXd6YbRt74DLQqrrLlg=",
"registrationId": "8819ac31-ad29-40d1-ac60-1b54293abe61"
}
Attribute | Type | Description |
---|---|---|
activationQrCodeData * |
String |
String for the activation QR code. |
registrationId * |
String |
ID of created registration. |
Registration failed due to a business logic problem.
{
"status": "ERROR",
"responseObject": {
"code": "ERROR_REGISTRATION_NOT_ALLOWED",
"message": "Registration is already in progress"
}
}
Possible error states are:
ERROR_REGISTRATION_NOT_FOUND
- When user does not have access to the registrations.ERROR_REGISTRATION_NOT_ALLOWED
- When registration is not allowed because another registration is already in progress for the user.ERROR_REQUEST
- Request did not pass a structural validation (mandatory field is null, invalid field type, etc.).
Invalid username or password was provided while calling the service.
{
"status": "ERROR",
"responseObject": {
"code": "HTTP_401",
"message": "Unauthorized"
}
}
Error occurred while calling the internal service. This can happen only as a result of misconfiguration. Check your deployment configuration for errors.
{
"status": "ERROR",
"responseObject": {
"code": "ERROR_INTERNAL_API",
"message": "Unable to call upstream service"
}
}
post /v2/registrations/{registrationId}/commit Commit New Registration
Commit the new registration after the mobile device exchanged the data with the server-side in order to make the registration active.
Only registrations that are in the PENDING_COMMIT
state can be committed. Check the registration status by calling GET /v2/registrations
before the commit.
Request
{
"externalUserId": "$EXTERNAL_USER_ID"
}
Path Params
Attribute | Type | Description |
---|---|---|
registrationId * |
String |
ID of registration to be committed. |
Request Params
Attribute | Type | Description |
externalUserId |
String |
ID of an external user who initiated this action (i.e., a call center operator or admin). |
Response
{
"status": "OK"
}
Attribute | Type | Description |
---|---|---|
status * |
String |
Fixed value OK . |
Registration commit failed due to a business logic problem.
{
"status": "ERROR",
"responseObject": {
"code": "ERROR_REGISTRATION_NOT_FOUND",
"message": "Registration cannot be committed, unexpected state: ..."
}
}
Possible error states are:
ERROR_REGISTRATION_NOT_FOUND
- When registration does not exist for given user and application or user does not have access to the registration.ERROR_REGISTRATION_CHANGE
- When the registration is in invalid state.ERROR_REQUEST
- Request did not pass a structural validation (mandatory field is null, invalid field type, etc.).
Invalid username or password was provided while calling the service.
{
"status": "ERROR",
"responseObject": {
"code": "HTTP_401",
"message": "Unauthorized"
}
}
Error occurred while calling the internal service. This can happen only as a result of misconfiguration. Check your deployment configuration for errors.
{
"status": "ERROR",
"responseObject": {
"code": "ERROR_INTERNAL_API",
"message": "Unable to call upstream service"
}
}
get /v2/registrations/{registrationId} Get Registration Status
Get the registration status for a given user and registration identifier.
Request
Path Params
Param | Type | Description |
---|---|---|
registrationId * |
String |
ID of registration record. |
Response
The response body attributes depend on the registration status. There are four possible response structures:
- Created Registration
- Pending Commit Registration
- Active Registration
- Blocked Registration
Created Registration
The registration was just created, no other activity occurred. The expected step at this stage is exchange between mobile authenticator and server-side components. This step is initiated by scanning the activation QR code with a mobile app.
{
"registrationId": "8819ac31-ad29-40d1-ac60-1b54293abe61",
"registrationStatus": "CREATED",
"activationQrCodeData": "NTF5I-R3KHV-SZN6E-ISYBA#MEYCIQC99lzXIlz3V3nLFBz1MyN0EV6y7IZDdheI14BetT/J5QIhAJReYRX8GKQYm1YzExJatYUBLHJgvhCLnjYeltVYDr1a",
"flags": ["FLAG_1"],
"timestampCreated": 1617787702781
}
Attribute | Type | Description |
---|---|---|
registrationId * |
String |
Registration identifier. |
registrationStatus * |
String |
Fixed value CREATED . |
activationQrCodeData * |
String |
String for the activation QR code. |
flags * |
String[] |
Registration flags. |
timestampCreated * |
Long |
Unix timestamp in milliseconds, represents when the registration was created. |
Pending Commit Registration
The exchange between mobile authenticator and server-side components is completed and activation is ready to be committed, which makes it usable for operation approval. In this state, the activation fingerprint contains the value representing exchanged cryptographic material. You can show the value in both mobile app and web interface to let user check that the exchange completed successfully.
{
"registrationId": "8819ac31-ad29-40d1-ac60-1b54293abe61",
"registrationStatus": "PENDING_COMMIT",
"name": "iPhone",
"platform": "ios",
"deviceInfo": "iPhone10,6",
"activationFingerprint": "52649917",
"flags": ["FLAG_1"],
"timestampCreated": 1617787702781
}
Attribute | Type | Description |
---|---|---|
registrationId * |
String |
Registration identifier. |
registrationStatus * |
String |
Fixed value PENDING_COMMIT . |
name * |
String |
Name of the registration, usually a device name. |
platform * |
String |
Platform of the mobile client, ios or android . |
deviceInfo * |
String |
Information about the device model, i.e. iPhone10,6 |
activationFingerprint * |
String |
Numerical value representing the exchanged data. You may show this value in the web interface to allow user check that the same value is displayed on the mobile device and hence exchange was completed successfully. |
flags * |
String[] |
Registration flags. |
timestampCreated * |
Long |
Unix timestamp in milliseconds, represents when the registration was created. |
Active Registration
The registration is active, and it can be used to approve operations.
{
"registrationId": "8819ac31-ad29-40d1-ac60-1b54293abe61",
"registrationStatus": "ACTIVE",
"name": "iPhone",
"platform": "ios",
"deviceInfo": "iPhone10,6",
"flags": ["FLAG_1"],
"timestampCreated": 1617787702781
}
Attribute | Type | Description |
---|---|---|
registrationId * |
String |
Registration identifier. |
registrationStatus * |
String |
Fixed value ACTIVE . |
name * |
String |
Name of the registration, usually a device name. |
platform * |
String |
Platform of the mobile client, ios or android . |
deviceInfo * |
String |
Information about the device model, i.e. iPhone10,6 |
flags * |
String[] |
Registration flags. |
timestampCreated * |
Long |
Unix timestamp in milliseconds, represents when the registration was created. |
Blocked Registration
The registration is blocked, either because of too many failed attempts to authenticate, or because it was actively blocked by the user, admin, call center, or any other similar mechanism. The blocked registration cannot be used to approve operations, it has to be unblocked first, or the user needs to re-activate the device.
{
"registrationId": "8819ac31-ad29-40d1-ac60-1b54293abe61",
"registrationStatus": "BLOCKED",
"name": "iPhone",
"platform": "ios",
"deviceInfo": "iPhone10,6",
"flags": ["FLAG_1"],
"timestampCreated": 1617787702781
}
Attribute | Type | Description |
---|---|---|
registrationId * |
String |
Registration identifier. |
registrationStatus * |
String |
Fixed value BLOCKED . |
name * |
String |
Name of the registration, usually a device name. |
platform * |
String |
Platform of the mobile client, ios or android . |
deviceInfo * |
String |
Information about the device model, i.e. iPhone10,6 |
flags * |
String[] |
Registration flags. |
timestampCreated * |
Long |
Unix timestamp in milliseconds, represents when the registration was created. |
Registration status failed due to a business logic problem.
{
"status": "ERROR",
"responseObject": {
"code": "ERROR_REQUEST",
"message": "Required String parameter 'userId' is not present"
}
}
Possible error states are:
ERROR_REQUEST
- Request did not pass a structural validation (mandatory field is null, invalid field type, etc.)ERROR_REGISTRATION_NOT_FOUND
- When user does not have access to the registration.
Invalid username or password was provided while calling the service.
{
"status": "ERROR",
"responseObject": {
"code": "HTTP_401",
"message": "Unauthorized"
}
}
Error occurred while calling the internal service. This can happen only as a result of misconfiguration. Check your deployment configuration for errors.
{
"status": "ERROR",
"responseObject": {
"code": "ERROR_INTERNAL_API",
"message": "Unable to call upstream service"
}
}
get /v2/registrations Get Registration List
Get the registration list for a given user.
Request
Query Params
Param | Type | Description |
---|---|---|
userId * |
String |
ID of a user for whom to get the registration list. |
Response
The response body contains list of registrations. You can obtain additional details by calling the Get Registration Status endpoint.
The example below shows two registrations, one in CREATED
state and another one in ACTIVE
state.
{
"registrations": [
{
"registrationId": "8819ac31-ad29-40d1-ac60-1b54293abe61",
"registrationStatus": "CREATED",
"name": "iPhone 8",
"flags": ["FLAG_1"],
"timestampCreated": 1617787702781
},
{
"registrationId": "59f1cd5b-63a4-4cc3-82c7-544c246cfa77",
"registrationStatus": "ACTIVE",
"name": "iPhone SE",
"flags": ["FLAG_2"],
"timestampCreated": 1617787702781
}
]
}
Attribute | Type | Description |
---|---|---|
registrations[].registrationId * |
String |
Registration identifier. |
registrations[].registrationStatus * |
String |
Registration status: CREATED , PENDING_COMMIT , ACTIVE , or BLOCKED . |
registrations[].name * |
String |
Name of the registration, usually a device name.. |
registrations[].flags * |
String[] |
Registration flags. |
registrations[].timestampCreated * |
Long |
Unix timestamp in milliseconds, represents when the registration was created. |
Request validation failed.
{
"status": "ERROR",
"responseObject": {
"code": "ERROR_REQUEST",
"message": "Required String parameter 'userId' is not present"
}
}
ERROR_REQUEST
- Request did not pass a structural validation (mandatory field is null, invalid field type, etc.).ERROR_REGISTRATION_NOT_FOUND
- When user does not have access to the registrations.
Invalid username or password was provided while calling the service.
{
"status": "ERROR",
"responseObject": {
"code": "HTTP_401",
"message": "Unauthorized"
}
}
Error occurred while calling the internal service. This can happen only as a result of misconfiguration. Check your deployment configuration for errors.
{
"status": "ERROR",
"responseObject": {
"code": "ERROR_INTERNAL_API",
"message": "Unable to call upstream service"
}
}
put /v2/registrations/{registrationId} Edit Registration Status
Edit the registration status, for example: block, unblock or delete registration. The method checks if the particular change is allowed for the current registration status.
The following actions are allowed for particular registration states:
CREATED
=>REMOVE
PENDING_COMMIT
=>REMOVE
ACTIVE
=>BLOCK
,REMOVE
BLOCKED
=>UNBLOCK
,REMOVE
Request
{
"change": "$CHANGE",
"externalUserId": "$EXTERNAL_USER_ID",
"blockReason": "$BLOCK_REASON"
}
Path Params
Param | Type | Description |
---|---|---|
registrationId * |
String |
ID of registration record. |
Request Params
Attribute | Type | Description |
---|---|---|
change * |
String |
Type of the requested change. |
externalUserId |
String |
ID of an external user who created this change, i.e., admin or call center operator. |
blockReason |
String |
Reason for blocking the activation. |
Possible changes are:
BLOCK
- Block the active registration.UNBLOCK
- Unblock the blocked registration.REMOVE
- Remove the registration, can be called in any registration state.
Response
{
"status": "OK"
}
Attribute | Type | Description |
---|---|---|
status * |
String |
Fixed value OK . |
Registration status change failed due to a business logic problem.
{
"status": "ERROR",
"responseObject": {
"code": "ERROR_REGISTRATION_CHANGE",
"message": "Activation is BLOCKED, you can only UNBLOCK or REMOVE it."
}
}
{
"status": "ERROR",
"responseObject": {
"code": "ERROR_REGISTRATION_NOT_FOUND",
"message": "Registration not found for state change"
}
}
Possible error states are:
ERROR_REGISTRATION_NOT_FOUND
- Registration is not found or user does not have access to the registration.ERROR_REGISTRATION_CHANGE
- The requested change cannot be performed due to invalid initial state.
Invalid username or password was provided while calling the service.
{
"status": "ERROR",
"responseObject": {
"code": "HTTP_401",
"message": "Unauthorized"
}
}
Error occurred while calling the internal service. This can happen only as a result of misconfiguration. Check your deployment configuration for errors.
{
"status": "ERROR",
"responseObject": {
"code": "ERROR_INTERNAL_API",
"message": "Unable to call upstream service"
}
}
delete /v2/registrations/{registrationId} Remove Registration
Remove the registration.
The call is equivalent to calling PUT /v2/registrations/{registrationId}
with the REMOVE
change.
Request
Path Params
Param | Type | Description |
---|---|---|
registrationId * |
String |
ID of registration record. |
Response
{
"status": "OK"
}
Attribute | Type | Description |
---|---|---|
status * |
String |
Fixed value OK . |
Registration removal failed due to a business logic problem.
{
"status": "ERROR",
"responseObject": {
"code": "ERROR_REGISTRATION_NOT_FOUND",
"message": "Registration not found for state change"
}
}
Possible error states are:
ERROR_REGISTRATION_NOT_FOUND
- Registration is not found or user does not have access to the registration.
Invalid username or password was provided while calling the service.
{
"status": "ERROR",
"responseObject": {
"code": "HTTP_401",
"message": "Unauthorized"
}
}
Error occurred while calling the internal service. This can happen only as a result of misconfiguration. Check your deployment configuration for errors.
{
"status": "ERROR",
"responseObject": {
"code": "ERROR_INTERNAL_API",
"message": "Unable to call upstream service"
}
}
post /v2/registrations/{registrationId}/flags Add Registration Flags
Add registration flags to a registration record.
Request
{
"flags": ["$FLAG"]
}
Path Params
Param | Type | Description |
---|---|---|
registrationId * |
String |
ID of registration record. |
Request Params
Attribute | Type | Description |
---|---|---|
flags * |
String[] |
Array with flags to be added to the registration record. |
Response
{
"status": "OK"
}
Attribute | Type | Description |
---|---|---|
status * |
String |
Fixed value OK . |
Flag addition failed due to a business logic problem.
{
"status": "ERROR",
"responseObject": {
"code": "ERROR_REGISTRATION_NOT_FOUND",
"message": "Registration not found"
}
}
Possible error states are:
ERROR_REGISTRATION_NOT_FOUND
- Registration is not found or user does not have access to the registration.
Invalid username or password was provided while calling the service.
{
"status": "ERROR",
"responseObject": {
"code": "HTTP_401",
"message": "Unauthorized"
}
}
Error occurred while calling the internal service. This can happen only as a result of misconfiguration. Check your deployment configuration for errors.
{
"status": "ERROR",
"responseObject": {
"code": "ERROR_INTERNAL_API",
"message": "Unable to call upstream service"
}
}
put /v2/registrations/{registrationId}/flags Update Registration Flags
Update registration flags for a registration record.
By calling this method, you will completely replace the registration flags. Use POST /v2/registrations/{registrationId}/flags
to add individual flags to the registration.
Request
{
"flags": ["$FLAG"]
}
Path Params
Param | Type | Description |
---|---|---|
registrationId * |
String |
ID of registration record. |
Request Params
Attribute | Type | Description |
---|---|---|
flags * |
String[] |
Array with flags to be set for the registration record. |
Response
{
"status": "OK"
}
Attribute | Type | Description |
---|---|---|
status * |
String |
Fixed value OK . |
Flag update failed due to a business logic problem.
{
"status": "ERROR",
"responseObject": {
"code": "ERROR_REGISTRATION_NOT_FOUND",
"message": "Registration not found"
}
}
Possible error states are:
ERROR_REGISTRATION_NOT_FOUND
- Registration is not found or user does not have access to the registration.
Invalid username or password was provided while calling the service.
{
"status": "ERROR",
"responseObject": {
"code": "HTTP_401",
"message": "Unauthorized"
}
}
Error occurred while calling the internal service. This can happen only as a result of misconfiguration. Check your deployment configuration for errors.
{
"status": "ERROR",
"responseObject": {
"code": "ERROR_INTERNAL_API",
"message": "Unable to call upstream service"
}
}
post /v2/registrations/{registrationId}/flags/remove Remove Registration Flags
Remove registration flags for a registration record.
Request
{
"flags": ["$FLAG"]
}
Path Params
Param | Type | Description |
---|---|---|
registrationId * |
String |
ID of registration record. |
Attribute | Type | Description |
---|---|---|
flags * |
String[] |
Array with flags to be deleted for the registration record. |
Response
{
"status": "OK"
}
Attribute | Type | Description |
---|---|---|
status * |
String |
Fixed value OK . |
Flag deletion failed due to a business logic problem.
{
"status": "ERROR",
"responseObject": {
"code": "ERROR_REGISTRATION_NOT_FOUND",
"message": "Registration not found"
}
}
Possible error states are:
ERROR_REGISTRATION_NOT_FOUND
- Registration is not found or user does not have access to the registration.
Invalid username or password was provided while calling the service.
{
"status": "ERROR",
"responseObject": {
"code": "HTTP_401",
"message": "Unauthorized"
}
}
Error occurred while calling the internal service. This can happen only as a result of misconfiguration. Check your deployment configuration for errors.
{
"status": "ERROR",
"responseObject": {
"code": "ERROR_INTERNAL_API",
"message": "Unable to call upstream service"
}
}
Services for Operations
Mobile token API is based on the concept of an “operation”. Operation is an activity that user needs to review and either approve or reject via the mobile token app. Each operation has a unique “operation ID” that can be used to obtain information about that particular operation and poll for the operation status.
Operations are created based on a “template” (registered in the system) that is filled with specific parameters. Template represents a type of an operation, parameters assign the particular operation properties. This way, you can create an operation, for example, for a payment (payment
template, to initiate authorize_payment
operation type) with a particular amount (passed in the parameters.amount
and parameters.currency
field).
post /v2/operations Create New Operation
Create a new operation to be approved.
Request
{
"userId": "$USER_ID",
"template": "$TEMPLATE",
"language": "en",
"externalId": "$EXTERNAL_ID",
"flag": "$FLAG",
"parameters": {
"param1": "$PARAM1",
"param2": "$PARAM2",
"param3": "$PARAM3"
}
}
Attribute | Type | Description |
---|---|---|
userId * |
String |
ID of a user for whom to create a new operation. |
template * |
String |
Template to use for the particular operation. |
language |
char[2] |
Language code to be used for this operation. Default: en |
externalId |
String |
ID of the operation in some external system, for example, an ID of the transaction. |
flag |
String |
Activation flag which limits scope of the operation to activations marked with specified flag. |
parameters |
Map<String, String> |
Parameters of the particular operation. The keys used in the map depend on the specific operation template, there is no limitation on the count. However, we recommend using reasonable amount (i.e., up-to 5) of parameters. |
Response
{
"operationId": "$OPERATION_ID",
"userId": "$USER_ID",
"externalId": "$EXTERNAL_ID",
"status": "PENDING",
"operationType": "$OPERATION_TYPE",
"flag": "$FLAG",
"parameters": {
"param1": "$PARAM1",
"param2": "$PARAM2",
"param3": "$PARAM3"
},
"failureCount": 0,
"maxFailureCount": 5,
"timestampCreated": 1617787702781,
"timestampExpires": 1617788002781
}
Attribute | Type | Description |
---|---|---|
operationId * |
UUID |
ID of the just created operation. |
userId * |
String |
ID of the user who created the operation. |
externalId |
String |
ID of the operation in some external system, for example, an ID of the transaction. |
status * |
String |
For just created operation, PENDING value is always returned. See operation states in GET /operations . |
operationType * |
String |
The operation type, created according to provided template. |
flag |
String |
Activation flag which limits scope of the operation to activations marked with specified flag. |
parameters |
Map<String, String> |
Parameters used while creating the operation. |
failureCount * |
Long |
How many failed approval attempts user made (always 0 for a newly created operation). |
maxFailureCount * |
Long |
How many failed approval attempts are allowed for this operation. |
timestampCreated * |
Long |
Unix timestamp in milliseconds, represents when the operation was created. |
timestampExpires * |
Long |
Unix timestamp in milliseconds, represents when the operation will expire. |
Operation could not be created due to a business logic problem.
{
"status": "ERROR",
"responseObject": {
"code": "ERROR_REGISTRATION_NOT_FOUND",
"message": "No active registration found matching operation criteria"
}
}
Possible error states are:
ERROR_REGISTRATION_NOT_FOUND
- No registration is found for provided user or user does not have access to the registrations.
Invalid username or password was provided while calling the service.
{
"status": "ERROR",
"responseObject": {
"code": "HTTP_401",
"message": "Unauthorized"
}
}
Error occurred while calling the internal service. This can happen only as a result of misconfiguration. Check your deployment configuration for errors.
{
"status": "ERROR",
"responseObject": {
"code": "ERROR_INTERNAL_API",
"message": "Unable to call upstream service"
}
}
get /v2/operations/{operationId} Get Operation Status
Get the status of the operation by operation ID.
Request
Path Params
Param | Type | Description |
---|---|---|
operationId |
UUID |
ID of an operation to obtain status for. |
Response
{
"operationId": "$OPERATION_ID",
"userId": "$USER_ID",
"status": "PENDING",
"operationType": "$OPERATION_TYPE",
"flag": "$FLAG",
"parameters": {
"param1": "$PARAM1",
"param2": "$PARAM2",
"param3": "$PARAM3"
},
"additionalData": {
"activationId": "$ACTIVATION_ID"
},
"failureCount": 0,
"maxFailureCount": 5,
"timestampCreated": 1617787702781,
"timestampExpires": 1617788002781
}
Attribute | Type | Description |
---|---|---|
operationId * |
UUID |
ID of the just created operation. |
userId * |
String |
ID of the user who created the operation. |
status * |
String |
For just created operation, “PENDING” value is always returned. See operation states in GET /operations . |
operationType * |
String |
The operation type, created according to provided template. |
flag |
String |
Activation flag which limits scope of the operation to activations marked with specified flag. |
parameters |
Map<String, String> |
Parameters used while creating the operation. |
additionalData |
Map<String, String> |
Additional data stored within the operation, such as activation identifier used for approving the operation. |
failureCount * |
Long |
How many failed approval attempts user made. |
maxFailureCount * |
Long |
How many failed approval attempts are allowed for this operation. |
timestampCreated * |
Long |
Unix timestamp in milliseconds, represents when the operation was created. |
timestampExpires * |
Long |
Unix timestamp in milliseconds, represents when the operation will expire. |
The possible operation states are:
PENDING
- Operation is active, waiting for the user’s action.CANCELED
- The operation was cancelled, for example, by clicking the “Cancel” button in the web interface.EXPIRED
- The operation expired.APPROVED
- The operation was approved by the user.REJECTED
- The operation was rejected by the user.FAILED
- The operation approval failed due to too many failed approval attempts.
Operation status could not be obtained due to a business logic problem.
{
"status": "ERROR",
"responseObject": {
"code": "ERROR_OPERATION_NOT_FOUND",
"message": "Operation with given ID was not found"
}
}
Possible error states are:
ERROR_REGISTRATION_NOT_FOUND
- User does not have access to the registrations.ERROR_OPERATION_NOT_FOUND
- Operation with provided ID was not found.
Invalid username or password was provided while calling the service.
{
"status": "ERROR",
"responseObject": {
"code": "HTTP_401",
"message": "Unauthorized"
}
}
Error occurred while calling the internal service. This can happen only as a result of misconfiguration. Check your deployment configuration for errors.
{
"status": "ERROR",
"responseObject": {
"code": "ERROR_INTERNAL_API",
"message": "Unable to call upstream service"
}
}
delete /v2/operations/{operationId} Cancel Operation
Delete the pending operation. The call checks the status of the operation and returns error in the case operation cannot be canceled (i.e., operation already expired).
Request
Path Params
Param | Type | Description |
---|---|---|
operationId * |
UUID |
ID of an operation to cancel. |
Response
{
"status": "OK"
}
Attribute | Type | Description |
---|---|---|
status * |
String |
Fixed value OK . |
Operation could not be canceled due to a business logic problem.
{
"status": "ERROR",
"responseObject": {
"code": "ERROR_OPERATION_NOT_FOUND",
"message": "Operation with given ID was not found"
}
}
{
"status": "ERROR",
"responseObject": {
"code": "ERROR_OPERATION_STATE_CHANGE",
"message": "Operation is in invalid state for requested action"
}
}
Possible error states are:
ERROR_REGISTRATION_NOT_FOUND
- User does not have access to the registrations.ERROR_OPERATION_NOT_FOUND
- Operation with provided ID was not found.ERROR_OPERATION_STATE_CHANGE
- Operation state does not allow canceling, i.e., operation already expired.
Invalid username or password was provided while calling the service.
{
"status": "ERROR",
"responseObject": {
"code": "HTTP_401",
"message": "Unauthorized"
}
}
Error occurred while calling the internal service. This can happen only as a result of misconfiguration. Check your deployment configuration for errors.
{
"status": "ERROR",
"responseObject": {
"code": "ERROR_INTERNAL_API",
"message": "Unable to call upstream service"
}
}
get /v2/operations/{operationId}/offline/qr Get Operation QR Code (Offline Approval)
Get the QR code for an offline approval of the particular operation. The user scans the QR code with the mobile device, computes the OTP which is then validated via POST /v2/operations/{operationId}/offline/otp
call. The call also returns the nonce
value, which is required during the OTP code verification later.
Tip: Store the nonce
value in the hidden form field on the page, next to the generated QR code and text field for the OTP input.
Request
Path Params
Param | Type | Description |
---|---|---|
operationId * |
UUID |
ID of an operation to obtain QR code for. |
Query Params
Param | Type | Description |
---|---|---|
registrationId * |
String |
ID of registration for the device which is expected to read the QR code. |
Response
{
"operationQrCodeData": "b67a77d6-8308-4ffd-b6e0-9f42f36a41a7\nApprove Login\nPlease confirm the login request.\nA2\nB\n7YLYRMvRIX0GZD94/oGPjg==\n1MEQCIDh0mCFv9uKdE7Gec+dE4WRfwDLpMltCy4hSMqMo1FwxAiAJwmzrMa6QsWeFoZEvQgRZeBd6v7e4vVw84w2bsvT7+Q==",
"nonce": "7YLYRMvRIX0GZD94/oGPjg=="
}
Attribute | Type | Description |
---|---|---|
operationQrCodeData * |
String |
Contents of the QR code to be scanned by the mobile token app. |
nonce * |
String |
Cryptographic nonce, used during the OTP verification. |
Operation QR code for offline approvals could not be created due to business logic error.
{
"status": "ERROR",
"responseObject": {
"code": "ERROR_OPERATION_NOT_FOUND",
"message": "Operation with given ID was not found"
}
}
{
"status": "ERROR",
"responseObject": {
"code": "ERROR_OPERATION_STATE_CHANGE",
"message": "Operation is in invalid state for requested action"
}
}
Possible error states are:
ERROR_REGISTRATION_NOT_FOUND
- Registration does not exist, it is not active or user does not have access to the registration.ERROR_OPERATION_NOT_FOUND
- Operation with provided ID was not found.ERROR_OPERATION_STATE_CHANGE
- Operation state does not allow obtaining the QR code, i.e., operation already expired.
Invalid username or password was provided while calling the service.
{
"status": "ERROR",
"responseObject": {
"code": "HTTP_401",
"message": "Unauthorized"
}
}
Error occurred while calling the internal service. This can happen only as a result of misconfiguration. Check your deployment configuration for errors.
{
"status": "ERROR",
"responseObject": {
"code": "ERROR_INTERNAL_API",
"message": "Unable to call upstream service"
}
}
post /v2/operations/{operationId}/offline/otp Verify Operation OTP (Offline Approval)
Verify operation OTP for offline operation approval. After the user scans the QR code with operation data, the mobile authenticator prompts the user for an authentication and calculates the OTP code. The user then rewrites the OTP in the web browser, into a form that stores operation ID and nonce values.
Tip: The OTP code is accepted in the “credit card number” format of 4x4 digits separated by a dash (9301-7407-1055-2502
), as well as 2x8 digits separated by a dash ( 93017407-10552502
), or simply as 16 digits (9301740710552502
).
Request
Path Params
Param | Type | Description |
---|---|---|
operationId * |
UUID |
ID of an operation to validate OTP for. |
Request Params
{
"otp": "$OTP",
"nonce": "$NONCE",
"registrationId": "$REGISTRATION_ID"
}
Attribute | Type | Description |
---|---|---|
otp * |
String |
OTP value as entered by the user. |
nonce * |
String |
Cryptographic nonce obtained while creating the QR code. |
registrationId * |
String |
ID of registration of the device used for operation OTP verification. |
Response
{
"otpValid": true,
"userId": "test-user",
"operationId": "cb21daf7-8b06-4f88-8277-171fc1d5131e",
"registrationId": "b4c73d24-050f-4aaa-9fab-bda401079879",
"registrationStatus": "ACTIVE",
"signatureType": "POSSESSION_KNOWLEDGE",
"remainingAttempts": 5,
"flags": [
"FLAG1"
],
"application": {
"name": "APP1",
"roles": [
"ROLE1"
]
}
}
Attribute | Type | Description |
---|---|---|
otpValid * |
boolean | Whether offline OTP verification succeeded. |
userId * |
String |
Identifier of user who requested the signature verification. |
registrationId * |
String |
Identifier of registration used when verifying the signature. |
registrationStatus * |
String |
Registration status. |
signatureType * |
String |
PowerAuth signature type. |
remainingAttempts * |
Long |
Number of remaining attempts for signature verification. |
flags * |
String[] |
Registration flags. |
application.name * |
String |
Application name. |
application.roles * |
String[] |
Assigned application roles. |
Operation OTP code verification for offline approvals failed due to a business logic problem.
{
"status": "ERROR",
"responseObject": {
"code": "ERROR_OTP_INVALID",
"message": "Operation OTP format is invalid, OTP validation skipped."
}
}
{
"status": "ERROR",
"responseObject": {
"code": "ERROR_OPERATION_NOT_FOUND",
"message": "Operation with given ID was not found"
}
}
{
"status": "ERROR",
"responseObject": {
"code": "ERROR_OPERATION_STATE_CHANGE",
"message": "Operation is in invalid state for requested action"
}
}
Possible error states are:
ERROR_OTP_INVALID
- OTP verification failed due to invalid OTP format.ERROR_REGISTRATION_NOT_FOUND
- User does not have access to the registration.ERROR_OPERATION_NOT_FOUND
- Operation with provided ID was not found.ERROR_OPERATION_STATE_CHANGE
- Operation state does not allow verifying the OTP, i.e., operation already expired.
Invalid username or password was provided while calling the service.
{
"status": "ERROR",
"responseObject": {
"code": "HTTP_401",
"message": "Unauthorized"
}
}
Error occurred while calling the internal service. This can happen only as a result of misconfiguration. Check your deployment configuration for errors.
{
"status": "ERROR",
"responseObject": {
"code": "ERROR_INTERNAL_API",
"message": "Unable to call upstream service"
}
}
Signature Verification
post /v2/signature/verify Verify Signature (Online Approval)
Verify PowerAuth signature for online operation approval. This endpoint simplifies signature verification by using the PowerAuth
authentication header received from the mobile application together with HTTP request parameters: HTTP method, resource URI and request body / query parameters.
Request
Path Params
Param | Type | Description |
---|---|---|
operationId * |
UUID |
ID of an operation to validate OTP for. |
Request Params
{
"method": "$HTTP_METHOD",
"uriId": "$RESOURCE_URI",
"authHeader": "$POWERAUTH_HEADER",
"requestBody": "$REQUEST_BODY_BASE64",
"queryParams": {
"param1": "$PARAM1",
"param2": "$PARAM2",
"param3": "$PARAM3"
}
}
Attribute | Type | Description |
---|---|---|
method * |
String |
HTTP method: GET , POST , PUT , or DELETE . |
uriId * |
String |
Resource URI of the endpoint used for signature verification, e.g. /pa/signature/validate . |
authHeader * |
String |
PowerAuth authentication header in format PowerAuth pa_activation_id=\"$ACTIVATION_ID\", pa_application_key=\"$APPLICATION_KEY\", pa_nonce=\"$NONCE\", pa_signature_type=\"$SIGNATURE_TYPE\", pa_signature=\"$SIGNATURE\", pa_version=\"$VERSION\" . |
requestBody |
String |
Base64-encoded request body for POST , PUT , and DELETE HTTP methods. Use null value for GET HTTP method. |
queryParams |
String |
Query parameters for the GET HTTP method as a map. The map keys should be unique and the values should not be URL-encoded, sensitive characters should be escaped using regular JSON normalization syntax. Use null value for for POST , PUT , and DELETE HTTP methods. |
Response
{
"signatureValid": true,
"userId": "test-user",
"operationId": "cb21daf7-8b06-4f88-8277-171fc1d5131e",
"registrationId": "b4c73d24-050f-4aaa-9fab-bda401079879",
"registrationStatus": "ACTIVE",
"signatureType": "POSSESSION_KNOWLEDGE",
"remainingAttempts": 5,
"flags": [
"FLAG1"
],
"application": {
"name": "APP1",
"roles": [
"ROLE1"
]
}
}
Attribute | Type | Description |
---|---|---|
signatureValid * |
boolean | Whether signature verification succeeded. |
userId * |
String |
Identifier of user who requested the signature verification. |
registrationId * |
String |
Identifier of registration used when verifying the signature. |
registrationStatus * |
String |
Registration status. |
signatureType * |
String |
PowerAuth signature type. |
remainingAttempts * |
Long |
Number of remaining attempts for signature verification. |
flags * |
String[] |
Registration flags. |
application.name * |
String |
Application name. |
application.roles * |
String[] |
Assigned application roles. |
Signature verification for online approvals failed due to a business logic problem.
{
"status": "ERROR",
"responseObject": {
"code": "ERROR_SIGNATURE_INVALID",
"message": "Signature HTTP header validation failed"
}
}
Possible error states are:
ERROR_SIGNATURE_INVALID
- Signature HTTP header is invalid.
Invalid username or password was provided while calling the service.
{
"status": "ERROR",
"responseObject": {
"code": "HTTP_401",
"message": "Unauthorized"
}
}
Error occurred while calling the internal service. This can happen only as a result of misconfiguration. Check your deployment configuration for errors.
{
"status": "ERROR",
"responseObject": {
"code": "ERROR_INTERNAL_API",
"message": "Unable to call upstream service"
}
}
Auditing Services
get /audit/log Get Audit Log
The functionality of the audit log is currently experimental and may change in the future. Any information required for detailed examination of a particular situation can be found in system logs or application database.
Get the event log for auditing purposes.
Request
Query Params
Param | Type | Description |
---|---|---|
userId * |
String |
ID of user to fetch the audit logs for. |
timestampFrom |
Long |
Unix timestamp in milliseconds from which to obtain the log (the date more in the past), default: 30 days ago. |
timestampTo |
Long |
Unix timestamp in milliseconds to which to obtain the log (the date more in the past), default: now. |
Response
{
"items": [
{
"activationId": "6cf201c0-a410-4dd1-96a6-c859ccb060f5",
"eventType": "signature_ok",
"eventData": "POST\n/operation/cancel\n{\"requestObject\":{\"id\":\"82b98a73-5402-4f08-98a2-78b75015dafd\",\"reason\":\"UNKNOWN\"}}",
"timestamp": 1617787708677
},
{
"activationId": "6cf201c0-a410-4dd1-96a6-c859ccb060f5",
"eventType": "signature_ok",
"eventData": "POST\n/operation/authorize\n{\"requestObject\":{\"id\":\"600eac37-3e1f-4c95-9458-fabc45d75f20\",\"data\":\"A1*A1000.23EUR*ICZ3855000000003643174999\"}}",
"timestamp": 1617173535559
}
]
}
Attribute | Type | Description |
---|---|---|
items * |
Object[] |
Items of the audit log. |
items[].activationId * |
String |
ID of the device / registration. |
items[].eventType * |
String |
Type of the event. |
items[].eventData * |
String |
Additional information about the event. |
items[].timestamp * |
String |
Event unix timestamp in milliseconds. |
Fetching the audit log failed due to a business logic problem.
{
"status": "ERROR",
"responseObject": {
"code": "ERROR_AUDIT",
"message": "Unable to obtain an audit log information."
}
}
Possible error states are:
ERROR_AUDIT
- When an error occurred that prevents fetching the audit log, i.e., invalid dates on input or user ID that does not exist.
Invalid username or password was provided while calling the service.
{
"status": "ERROR",
"responseObject": {
"code": "HTTP_401",
"message": "Unauthorized"
}
}
Error occurred while calling the internal service. This can happen only as a result of misconfiguration. Check your deployment configuration for errors.
{
"status": "ERROR",
"responseObject": {
"code": "ERROR_INTERNAL_API",
"message": "Unable to call upstream service"
}
}
Internal Services
Internal callbacks are not supposed to be directly called by the app developer. They are intended for internal systems, as a means to notify the cloud component about various internal changes.
post /internal/callback/operation Operation Callback
Operation status changed internally, i.e., operation expired.
Request
{
"operationId": "$OPERATION_ID"
}
Attribute | Type | Description |
---|---|---|
operationId * |
UUID |
ID of an operation check the status on callback in order to obtain the current status. |
Response
{
"status": "OK"
}
Attribute | Type | Description |
---|---|---|
status * |
String |
Fixed value OK . |
Request validation failed.
{
"status": "ERROR",
"responseObject": {
"code": "ERROR_REQUEST",
"message": "Required String parameter 'userId' is not present"
}
}
ERROR_REQUEST
- Request did not pass a structural validation (mandatory field is null, invalid field type, etc.).
Invalid username or password was provided while calling the service.
{
"status": "ERROR",
"responseObject": {
"code": "HTTP_401",
"message": "Unauthorized"
}
}
Error occurred while calling the internal service. This can happen only as a result of misconfiguration. Check your deployment configuration for errors.
{
"status": "ERROR",
"responseObject": {
"code": "ERROR_INTERNAL_API",
"message": "Unable to call upstream service"
}
}
Application Services
post /admin/application Create Application
Create a new app with provided ID.
Request
{
"id": "MY_APP_01"
}
Response
{
"serviceBaseUrl": "https://api.example.com/",
"masterServerPublicKey": "MIIB...==",
"appKey": "b34...==",
"appSecret": "aef...=="
}
Attribute | Type | Description |
---|---|---|
status * |
String |
Fixed value OK . |
responseObject.serviceBaseUrl * |
URL | Base URL of the PowerAuth Standard RESTful API. |
responseObject.masterServerPublicKey * |
String | Master Server Public Key (value for the mobile app configuration). |
responseObject.appKey * |
String | App Key (value for the mobile app configuration). |
responseObject.appSecret * |
String | App Secret (value for the mobile app configuration). |
Unable to return registration because of the invalid application name or version.
{
"status": "ERROR",
"responseObject": {
"code": "ERROR_ADMIN",
"message": "No registration found that can be committed"
}
}
Invalid username or password was provided while calling the service.
{
"status": "ERROR",
"responseObject": {
"code": "HTTP_401",
"message": "Unauthorized"
}
}
Error occurred while calling the internal service. This can happen only as a result of misconfiguration. Check your deployment configuration for errors.
{
"status": "ERROR",
"responseObject": {
"code": "ERROR_INTERNAL_API",
"message": "Unable to call upstream service"
}
}
get /admin/application Get App Details
Obtain the configuration for an app with provided ID.
Request
Query Param
Param | Type | Description |
---|---|---|
id * |
String |
ID of an app. |
version |
String |
Specific version name. |
Response
{
"serviceBaseUrl": "https://api.example.com/",
"masterServerPublicKey": "MIIB...==",
"appKey": "b34...==",
"appSecret": "aef...=="
}
Attribute | Type | Description |
---|---|---|
status * |
String |
Fixed value OK . |
responseObject.serviceBaseUrl * |
URL | Base URL of the PowerAuth Standard RESTful API. |
responseObject.masterServerPublicKey * |
String | Master Server Public Key (value for the mobile app configuration). |
responseObject.appKey * |
String | App Key (value for the mobile app configuration). |
responseObject.appSecret * |
String | App Secret (value for the mobile app configuration). |
Unable to return registration because of the invalid application name or version.
{
"status": "ERROR",
"responseObject": {
"code": "ERROR_ADMIN",
"message": "No registration found that can be committed"
}
}
Invalid username or password was provided while calling the service.
{
"status": "ERROR",
"responseObject": {
"code": "HTTP_401",
"message": "Unauthorized"
}
}
Error occurred while calling the internal service. This can happen only as a result of misconfiguration. Check your deployment configuration for errors.
{
"status": "ERROR",
"responseObject": {
"code": "ERROR_INTERNAL_API",
"message": "Unable to call upstream service"
}
}