Skip to content

Challenge API Endpoint

Use this endpoint to send or cancel a Gridy Multi-Factor authentication challenge.

Challenge

Send or Cancel a Gridy ID MFA challenge request.

/v1/svc/challenge Try it Out


Requests

All Requests are POST requests,

1. New Challenge

Send a Gridy MFA challenge to a User.

Request Body
param type required default desccription
idStringfalseYour own internal ref id (max 25 chars)
utctimeStringtrueUTC Timestamp in Milliseconds
apiuserStringtrueYour 9-digit Gridy API UserID
typeinttrue150150 - New Challenge
bodyStringtrueJson Request body
gridyUserStringtrueUser Email address
(max 125 chars)
challengeTypeStringtrueUserKeyAndPattern Set the MFA challenge type you want a User to complete:-

options:
UserKeyAndPattern
UserKeyPatternAndPin
UserKeyAndUserPin
UserKeyAndUserFace
UserKeyAndUserVoice
challengeExpiryStringfalseFifteenMinsSet the authentication challenge expiry time.

options:
ThreeMins
FiveMins
FifteenMins
ThirtyMins
enableQRcodebooleanfalsetrueRequest challenge Base64 encoded QR code png image in response. if set to false only the challenge QR code url will be sent in response.
enableAutoVerifybooleanfalsefalseEnable auto verification of authentication code. See Auto Verify for more details.
profileStringfalse"NONE" Assign a defined role profile to a user on successful authentication
ipAddressStringfalse IPv4 address of User requesting authentication challenge (default: None)
Note: required when checking against your defined IPv4 block rules
statusStringfalse"NEW"
Example
{ 
 "id":< Your own reference >,
 "utctime": "<UTC Timestamp in Milliseconds>",
 "apiUser":"<Your Api User ID>",
 "type":150,
 "body":{
   "gridyUser": "<User Email Address>",
   "challengeType": "UserKeyPatternAndPin",
   "challengeExpiry": "FifteenMins",
   "enableQRCode":true,
   "enableAutoVerify":false,
   "profile":"DEFAULT",
   "ipAddress": "<User IP Address>",    
   "status":"NEW"
 }
}
Sample Code
    curl -X POST "https://api.gridy.io/v1/svc/challenge" 
        -H  "accept: application/json; charset=utf-8" 
        -H  "Authorization: gridy-hmac: apiuser=<Your API User ID>,signedheaders=x-gridy-utctime;x-gridy-cnonce,algorithm=gridy-hmac512,signature=e0025d840dc5368028a90a9e73df67fd520e697254de5f4c956e87afdefd56e455eecf549800ee196738f61e83d07d284dda04253e1a4c33ec68f150b6b5faa5" 
        -H  "x-gridy-apiuser: < Your Api User ID >" 
        -H  "x-gridy-utctime: 1734732919817" 
        -H  "x-gridy-cnonce: 8dcb623a-b56e-4534-838b-5e9e" 
        -H  "Content-Type: application/json; charset=utf-8" 
        -d "{  
            "id":<YOUR OWN REF ID>, 
            "utctime": "<UTC Timestamp in Milliseconds>", 
            "apiUser":"<YOUR API USER ID>", 
            "type":150, 
            "body":{   
                "gridyUser":"<EMAIL ADDRESS>",   
                "challengeType": "UserKeyPatternAndPin",   
                "challengeExpiry":"FifteenMins",   
                "enableQRCode":true,   
                "enableAutoVerify":false,   
                "profile":"DEFAULT",   
                "status":"NEW" 
                  }

        }"
  import io.gridy.client.ApiClient;
  import io.gridy.client.ApiException;
  import io.gridy.client.Configuration;
  import io.gridy.client.auth.HmacSha512Auth;
  import io.gridy.client.model.*;
  import io.gridy.client.api.GridyIdServiceApi

  ApiClient defaultClient = new ApiConfig.Builder()
             # Configure API User Id
            .withApiUser( System.getEnv("GRIDY_API_USER")  )
             # Configure API User Secret
            .withApiSecret( System.getEnv("GRIDY_API_SECRET")  )
             # Configure API Environment
            .withApiEnv(GridyEnv.LIVE)
            .build();   


  GridyIdServiceApi apiInstance = new GridyIdServiceApi(defaultClient);
      ApiRequest apiRequest = new ApiRequest()
            .id("YOUR ID REFERENCE")
            .apiUser( defaultClient.getApiUser() )
            .type(ApiReqstType.CHALLENGE_NEW )
            .body( new ChallengeRequest.Builder()                      
                .forUser( "<USER EMAIL ADDRESS>" )
                .challengeType( ChallengeType.UserKeyAndPattern ) 
                .enableAutoVerify( false )
                .enableQRcode( true )    
                .withExpiry( Expiry.ThirtyMins  )
                .withStatus( Status.NEW )
                .withProfile( Profile.DEFAULT )
                .withIPAddress("")
                .build().toJson()
               );

      try {

        ModelApiResponse result = apiInstance.challenge(apiRequest);
        System.out.println(result);

      } catch (ApiException e) {

        System.err.println("Exception when calling GridyIdServiceApi#challenge");
        System.err.println("Status code: " + e.getCode());
        System.err.println("Reason: " + e.getResponseBody());
        System.err.println("Response headers: " + e.getResponseHeaders());

        e.printStackTrace();
}
    import gridyapi_client
    from gridyapi_client.rest import ApiException
    from pprint import pprint

    # Defining the host is optional and defaults to https://api.gridy.io
    # See configuration.py for a list of all supported configuration parameters.
    configuration = gridyapi_client.Configuration(
            host="https://api.gridy.io"
    )

    # The client must configure the authentication and authorization parameters
    # in accordance with the API server security policy.

    # Configure API User Id
    configuration.api_user = os.environ["GRIDY_API_USER"]

    # Configure API User Secret
    configuration.api_secret = os.environ["GRIDY_API_SECRET"]

    # Enter a context with an instance of the API client
    with gridyapi_client.ApiClient(configuration) as api_client:

        # Create an instance of the API class
        api_instance = gridyapi_client.GridyIDServiceApi(api_client)
        api_request = {
                  "id": < Your own reference >,
                  "utctime": "<UTC Timestamp in Milliseconds>",
                  "apiUser": <Your API User ID>,
                  "type": 150,
                  "body": {
                        "gridyUser": "demo@gridy.io",
                        "challengeType": "UserKeyPatternAndPin",
                        "challengeExpiry": "FifteenMins",
                        "enableQRCode": true,
                        "enableAutoVerify": false,
                        "profile": "<Your Assigned User Profile Reference>",
                        "status": "NEW"
                    }
              }  # ApiRequest | The JSON body of the request. Contains the Gridy ID challenge request.

        try:
            # Send or Cancel a Gridy ID MFA challenge request.
            api_response = api_instance.challenge(api_request)
            print("The response of GridyIDServiceApi->challenge:\n")
            pprint(api_response)
        except ApiException as e:
            print("Exception when calling GridyIDServiceApi->challenge: %s\n" % e)
    import 'package:gridy_mfa_client/gridyapi.dart';

    final api = GridyClient()
        .setHmacAuth('<Your 9-digit API User ID>','<Your API Secret Key>')
        .getGridyIDServiceApi();

        ApiRequest request = ApiRequest( (r) =>
        r
        ..id = 'Your refernence ID'
        ..utcTime = DateTime.now()
            .toUtc().millisecondsSinceEpoch
            .toString()
        ..type = API_CHALLENGE_SEND
        ..apiUser = '<Your API User ID>'
        ..body = {
                "gridyUser": '<User Email Address>',
                "challengeType": "UserKeyPatternAndPin" >,
                "challengeExpiry": "FifteenMins",
                "enableQRCode": true,
                "enableAutoVerify": false,
                "profile": "DEFAULT",
                "status": "NEW"
                }
        );

    try {
            final response = await api.challenge(apiRequest);
            final _dresponse = ApiResponse( (r) =>
            r
             ..id = _response.data?.id
             ..utcTime = _response.data?.utcTime
             ..status = _response.data?.status
             ..message = _response.data?.message
             ..code = _response.data?.code
             ..moreInfo = _response.data?.moreInfo
              );

            print(response);

    } catch on DioException (e) {
            print("Exception when calling GridyIDServiceApi->challenge: $e\n"); 
    }
require_once(__DIR__ . '/vendor/autoload.php');

// Configure Your Gridy API User ID
$config = GridyAPI\Client\Configuration::getDefaultConfiguration()->setApiUser( 'YOUR_API_USER_ID');

// Configure Your Gridy API Secret Key
$config = GridyAPI\Client\Configuration::getDefaultConfiguration()->setApiUser( 'YOUR_API_SECRET_KEY');


$apiInstance = new GridyAPI\Client\Service\GridyIDServiceApi(
        // If you want use custom http client, pass your client which implements `GuzzleHttp\ClientInterface`.
        // This is optional, `GuzzleHttp\Client` will be used as default.
        new GuzzleHttp\Client(),
        $config
);

$api_request = { 
    "id":< Your own reference >,
    "utctime": "<UTC Timestamp in Milliseconds>",
    "apiUser": "<Your API User ID>",
    "type":150,
    "body":{
        "gridyUser":"<User Email Address>",
        "challengeType":"UserKeyPatternAndPin",
        "challengeExpiry":"FifteenMins",
        "enableQRCode":true,
        "enableAutoVerify":false,
        "profile":"DEFAULT",
        "status":"NEW"
        }
    }; // \GridyAPI\Client\Model\ApiRequest | The JSON body of the request. Contains the Gridy ID challenge request.

try {
        $result = $apiInstance->challenge($api_request);
        print_r($result);

} catch (Exception $e) {
        echo 'Exception when calling GridyIDServiceApi->challenge: ', $e->getMessage(), PHP_EOL;
}
    var GridyIdApi = require('gridy_client');
    var defaultClient = GridyIdApi.ApiClient.instance;
    var api = new GridyIdApi.GridyIDServiceApi()

    var apiRequest = { 
     "id":"< Your own reference >",
     "utctime": "<UTC Timestamp in Milliseconds>",
     "apiUser":"<Your API User ID>",
     "type":150,
     "body":{
        "gridyUser":"<User Email Address>",
        "challengeType":"UserKeyPatternAndPin",
        "challengeExpiry":"FifteenMins",
        "enableQRCode":true,
        "enableAutoVerify":false,
        "profile":"DEFAULT",
        "status":"NEW"
     }
    }; // {ApiRequest} The JSON body of the request. Contains the Gridy ID challenge request.

    var callback = function(error, data, response) {
        if (error) {
                console.error(error);
        } else {
                console.log('API called successfully. Returned data: ' + data);
        }
    };

    api.challenge(apiRequest, callback);


Postman Collection

Don't want to write code? Check out the Gridy Postman Collection or the API Explorer for a no-code way to get started with Gridy's API.

2. Cancel Challenge

Cancel a Gridy MFA challenge already sent to a User.

Request Body
type required default desc
idStringfalseYour own internal ref id (max 25 chars)
utctimeStringtrueUTC Timestamp in Milliseconds
apiuserStringtrueYour 9-digit Gridy API UserID
typeinttrue151151 - Cancel Challenge
bodyStringtrueJSON Request body
challengeIdStringtrueGridy MFA Challenge ID
gridyUserStringtrueUser Email address
(max 125 chars)
statusStringtrueCANCEL
Example
{ 
 "id": "< Your own reference>",
 "utctime":"<UTC Timestamp in Milliseconds>",
 "apiUser":"<Your Api User ID>",
 "type":151,
"body": {
   "challengeId":"<User Gridy Challenge ID>",
   "gridyUser": "<User Email Address>",
   "status":"CANCEL"
 }
}
Sample Code
    curl -X POST "https://api.gridy.io/v1/svc/challenge" 
        -H  "accept: application/json; charset=utf-8" 
        -H  "Authorization: gridy-hmac: apiuser=<Your API User ID>,signedheaders=x-gridy-utctime;x-gridy-cnonce,algorithm=gridy-hmac512,signature=e0025d840dc5368028a90a9e73df67fd520e697254de5f4c956e87afdefd56e455eecf549800ee196738f61e83d07d284dda04253e1a4c33ec68f150b6b5faa5" 
        -H  "x-gridy-apiuser: <Your API User ID>" 
        -H  "x-gridy-utctime: 1734732919817" 
        -H  "x-gridy-cnonce: 8dcb623a-b56e-4534-838b-5e9e" 
        -H  "Content-Type: application/json; charset=utf-8" 
        -d "{  
            "id":< Your own reference >, 
            "utctime": "", 
            "apiUser":"<Your API User ID>", 
            "type":151, 
            "body":{ 
                "challengeId":<User Gridy Challenge ID>,
                "gridyUser":"<User Email Address>",
                "status":"CANCEL" 
                  }

        }"
      import io.gridy.client.ApiClient;
  import io.gridy.client.ApiException;
  import io.gridy.client.Configuration;
  import io.gridy.client.auth.HmacSha512Auth;
  import io.gridy.client.model.*;
  import io.gridy.client.api.GridyIdServiceApi

  ApiClient defaultClient = new ApiConfig.Builder()
             # Configure API User Id
            .withApiUser( System.getEnv("GRIDY_API_USER")  )
             # Configure API User Secret
            .withApiSecret( System.getEnv("GRIDY_API_SECRET")  )
             # Configure API Environment
            .withApiEnv(GridyEnv.LIVE)
            .build();

      GridyIdServiceApi apiInstance = new GridyIdServiceApi(defaultClient);
      ApiRequest apiRequest = new ApiRequest()
            .id("YOUR ID REFERENCE")
            .apiUser( defaultClient.getApiUser() )
            .type(ApiReqstType.CHALLENGE_CANCEL )
            .body( new ChallengeRequest.Builder()                      
                .forUser( "<User Email Address>" )
                .withId( "<User Gridy ChallengeID >")
                .withStatus( Status.CANCEL )
                .build().toJson() 
    );      

      try {
        ModelApiResponse result = apiInstance.challenge(apiRequest);
        System.out.println(result);

      } catch (ApiException e) {

        System.err.println("Exception when calling GridyIdServiceApi#challenge");
        System.err.println("Status code: " + e.getCode());
        System.err.println("Reason: " + e.getResponseBody());
        System.err.println("Response headers: " + e.getResponseHeaders());

        e.printStackTrace();
}
    import gridyapi_client
    from gridyapi_client.rest import ApiException
    from pprint import pprint

    # Defining the host is optional and defaults to https://api.gridy.io
    # See configuration.py for a list of all supported configuration parameters.
    configuration = gridyapi_client.Configuration(
            host="https://api.gridy.io"
    )

    # The client must configure the authentication and authorization parameters
    # in accordance with the API server security policy.

    # Configure API User Id
    configuration.api_user = os.environ["GRIDY_API_USER"]

    # Configure API User Secret
    configuration.api_secret = os.environ["GRIDY_API_SECRET"]

    # Enter a context with an instance of the API client
    with gridyapi_client.ApiClient(configuration) as api_client:

        # Create an instance of the API class
        api_instance = gridyapi_client.GridyIDServiceApi(api_client)
        api_request = {
                  "id": < Your own reference >,
                  "utctime": "<UTC Timestamp in Milliseconds>",
                  "apiUser": "<Your API User ID>",
                  "type": 151,
                  "body": {
            "challengeId":"<User Gridy Challenge ID>",  
            "gridyUser": "<User Email Address>",
                            "status": "CANCEL"
                    }
              }  # ApiRequest | The JSON body of the request. Contains the Gridy ID challenge request.

        try:
            # Send or Cancel a Gridy ID MFA challenge request.
            api_response = api_instance.challenge(api_request)
            print("The response of GridyIDServiceApi->challenge:\n")
            pprint(api_response)

        except ApiException as e:
            print("Exception when calling GridyIDServiceApi->challenge: %s\n" % e)
    import 'package:gridy_mfa_client/gridyapi.dart';

    final api = GridyClient()
        .setHmacAuth('<Your 9-digit API User ID>','<Your API Secret Key>')
        .getGridyIDServiceApi();

        ApiRequest request = ApiRequest( (r) =>
        r
        ..id = 'Your refernence ID'
        ..utcTime = DateTime.now()
            .toUtc().millisecondsSinceEpoch
            .toString()
        ..type = API_CHALLENGE_CANCEL
        ..apiUser = '<Your API User ID>'
        ..body = {
                "gridyUser": "<User Email Address>",
        "challengeId":"<User Gridy Challenge ID>",          
                "status": "CANCEL"
                }
        );

    try {
            final response = await api.challenge(apiRequest);
            final _dresponse = ApiResponse( (r) =>
            r
             ..id = _response.data?.id
             ..utcTime = _response.data?.utcTime
             ..status = _response.data?.status
             ..message = _response.data?.message
             ..code = _response.data?.code
             ..moreInfo = _response.data?.moreInfo
              );

            print(response);

    } catch on DioException (e) {
            print("Exception when calling GridyIDServiceApi->challenge: $e\n"); 
    }
require_once(__DIR__ . '/vendor/autoload.php');

// Configure Your Gridy API User ID
$config = GridyAPI\Client\Configuration::getDefaultConfiguration()->setApiUser( 'YOUR_API_USER_ID');

// Configure Your Gridy API Secret Key
$config = GridyAPI\Client\Configuration::getDefaultConfiguration()->setApiUser( 'YOUR_API_SECRET_KEY');


$apiInstance = new GridyAPI\Client\Service\GridyIDServiceApi(
        // If you want use custom http client, pass your client which implements `GuzzleHttp\ClientInterface`.
        // This is optional, `GuzzleHttp\Client` will be used as default.
        new GuzzleHttp\Client(),
        $config
);

$api_request = { 
    "id":< Your own reference >,
    "utctime": <UTC Timestamp in Milliseconds>,
    "apiUser":"<Your API User ID>",
    "type":151,
    "body":{
        "gridyUser":"<User Email Address>",
        "challengeId": "<User Gridy Challenge ID>",
        "status":"CANCEL"
        }
    }; // \GridyAPI\Client\Model\ApiRequest | The JSON body of the request. Contains the Gridy ID challenge request.

try {
        $result = $apiInstance->challenge($api_request);
        print_r($result);

} catch (Exception $e) {
        echo 'Exception when calling GridyIDServiceApi->challenge: ', $e->getMessage(), PHP_EOL;
}
    var GridyIdApi = require('gridy_client');
    var defaultClient = GridyIdApi.ApiClient.instance;
    var api = new GridyIdApi.GridyIDServiceApi()

    var apiRequest = { 
     "id":"<Your own reference >",
     "utctime": "<UTC Timestamp in Milliseconds>",
     "apiUser": "<Your API User ID>",
     "type":151,
     "body":{
        "gridyUser":"<User Email Address>",
        "challengeId": "<User Gridy Challenge ID>", 
        "status":"CANCEL"
     }
    }; // {ApiRequest} The JSON body of the request. Contains the Gridy ID challenge request.

    var callback = function(error, data, response) {
        if (error) {
                console.error(error);
        } else {
                console.log('API called successfully. Returned data: ' + data);
        }
    };

    api.challenge(apiRequest, callback);


Postman Collection

Don't want to write code? Check out the Gridy Postman Collection or the API Explorer for a no-code way to get started with Gridy's API.

Responses

All responses are JSON, with errors indicated in response bodies as negative status values (all application-level errors return a HTTP 400 status code)

   
Http Status API Status Description
202Accepted
2025New Gridy ID Challenge Accepted
2028New Gridy ID Challenge Cancelled
400Bad Request
-1001API User validation error  
-1003API User validation error  
-1026API User permissions error  
-1095API User autoverify disabled error
-2003Account validation error  
-2004Account blocked  
-2005Account too many failed attempts  
-2006Account locked  
-2007Account disabled  
-2008Account not active  
-2009Account locked  
-2010Account temporarily disabled  
-2017Account lock enabled  
-2038Account lockdown activated  
-2035Challenge cancelled error
-4004HTTP Header x-gridy-utctime missing  
-4005HTTP Header x-gridy-utctime format error  
-4006HTTP Header x-gridy-cnonce missing  
-4007HTTP Header x-gridy-cnonce format error  
-4008HTTP Header x-gridy-apiuser missing error  
-4009HTTP Header x-gridy-apiuser format error  
-4000HTTP Authorization Header missing  
-4001HTTP Authorization Header format error  
-4026HTTP Authorization Header HMAC signature missing
-4027HTTP Authorization Header HMAC signature format error  
-4028HTTP Authorization Header HMAC apiuser missing error  
-4029HTTP Authorization Header HMAC apiuser format error  
-4030HTTP Authorization Header HMAC algorithm missing error  
-4031HTTP Authorization Header HMAC algorithm format error  
-4032HTTP Authorization Header HMAC headers missing error  
-4033HTTP Authorization Header HMAC headers format error  
-4034HTTP Authorization Header HMAC nonce reused error  
-4035HTTP Authorization Header HMAC timestamp reused error  
-4036HTTP Authorization Header HMAC utctime clock drift error  
-4037HTTP Authorization Header HMAC signature error  
-5070API Request JSON Null body error  
-5071API Request JSON body type error  
-5072API Request JSON body type unknown error  
-5075API Challenge Request body error
-5076API Challenge Request challenge type error
-5077API Challenge Request body missing User error
-5078API Challenge Request body missing challenge type error
-5079API Challenge Request body invalid email address error
-6021API request blocked - IP address location blocked based on user defined rules
500Internal Error-5000API request rejected due to an Internal error.
Examples
Http Status API Status Description JSON
202Accepted2025New Gridy ID Challenge Accepted
{ 
        "id":< Our reference >,
        "utctime":<UTC Timestamp>,
        "status":202,
        "code":2025,
        "message":{ 
                "challengeId":"<User Gridy Challenge ID>",
                "challengeQRcodeUrl":"<User Gridy Challenge QR code URL>",
                "challengeQRcode":"data:image/png;base64,< User Base64Encoded Challenge QR code Image >" 
        }
        "moreinfo":"https://support.gridy.io/status?code=2025"
}
202Accepted2028New Gridy ID Challenge Cancelled
{ 
    "id":< Our reference >,
    "utctime":<UTC Timestamp>,
    "status":202,
    "code":2028,
    "message":{"status":"CANCELLED"}
    "moreinfo":"https://support.gridy.io/status?code=2028" 
}   
400Bad Request-2035New Gridy ID Challenge Cancelled Error
{ 
 "id":< Our reference >,
 "utctime":<UTC Timestamp>,
 "status":400,
 "code":-2035,
 "message":"BAD REQUEST :- CHALLENGE CANCELLED ERROR"
 "moreinfo":"https://support.gridy.io/error?code=-2035" 
}