Troubleshooting, API Status, and Health Checks

This page tells you:

  • How to check on whether the Arkose Labs APIs are up.
  • How to see regional health checks.
  • How to troubleshoot problems with Arkose Bot Manager.
  • How to handle errors you may encounter.

Note the following terminology:

Fail-Open: When we want the overall process to proceed, even when failure conditions for Arkose Bot Manager are present.

Fail-Close: When we want to block the workflow (retry, hard no-go), because failure conditions for Arkose Bot Manager are present.

In general, we recommend that you write your integration with Arkose Bot Manager so that, in the rare event of a disruption of our servers, your system fails-open.

Fail-Open Options: Reducing the Impact of Arkose API Service Disruption

We recommend you integrate and configure Arkose APIs so that they can be bypassed in the rare event of any Arkose API-related service disruption. The following sections discuss options for this and how to troubleshoot customer issues.

Feature Flag

When writing your integration of Arkose Bot Manager with your system:

  1. Set up a Feature Flag or key that can turn off Arkose Labs Enforcement on both the Server and Client.

  2. If the below issues/symptoms occur, call the Status API as shown later on this page.

  3. If the Status response indicates a problem at Arkose Labs, use the Feature Flag to turn off Enforcement.

  4. Periodically recheck Arkose’s status.

  5. When it returns to being operational, use the Feature Flag to turn Enforcement back on.

Client-Side Troubleshooting

IssueSymptomsMitigation Suggestions
The Arkose JS API script does not load.The onReady callback will NOT be called.1. Implement a timer that checks if the onReady callback has been triggered. If not:

a. Ask the user to refresh the page

b. Retry loading the Arkose API Script

2. Use the Arkose Labs Status API to check for service issues. Based on the response (none, partial, outage), take customer specific action as necessary.
The Arkose API runs, but fails session creation due to not being able to communicate with the Arkose servers.The onError callback is triggered.1. When the onError callback is triggered, call reset to retry creating the session. Then run methods on the Arkose Enforcement Object.

2. If onError is triggered multiple times, use the Arkose Labs Status API to check for service issues. Based on the response (none, partial, outage), take customer specific action as necessary.
An Enforcement Challenge is shown, but there is a communication error between the EC and the Arkose servers.The EC shows an error screen, such as:

The connection to a verification server was interrupted. To prove you're not a spammer, please refresh this page

The EC automatically tries to reconnect with the Arkose servers and continue once it does
1. Retry session creation by calling the reset() method on the Arkose Enforcement Object

a. In lightbox mode, if the lightbox has been opened, reset() closes the lightbox and resets the challenge. To reopen it, call run(). However, if the error is thrown before the lightbox is triggered to open, just call reset().

2. Use the Arkose Labs Status API to check for service issues. Based on the response (none, partial, outage), take customer specific action as necessary.

Server-Side

SymptomsMitigation Suggestions
Unexpectedly long response time from a Verify API call.1. Use the Arkose Labs Status API to check for service issues.

2. If there is an outage or disruption, your server should bypass any validity checks for the Arkose token and let the user continue the session.
Verify API call returns an HTTP error code.1. Use the Arkose Labs Status API to check for service issues.

2. If there is an outage or disruption, your server should bypass any validity checks for the Arkose token and let the user continue the session.

Fail-Open Error Handling Sample Code

<html>
  <head>
    <meta charset="UTF-8" />
  </head>
  <body>
    <!--
    The trigger element can exist anywhere in your page and can be added to the DOM at any time.
    -->
    <button id="enforcement-trigger">trigger element</button>
    <script>
      const publicKey = '<YOUR PUBLIC KEY>';
      const maxRetryCount = 3;
      const arkoseScriptSrc = `https://client-api.arkoselabs.com/v2/11111111-1111-1111-1111-111111111111/api.js`;
      let scriptRetryCount = 0;
      let enforcementRetryCount = 0;

      function handleFailure() {
        // Handle Arkose script failure here
        // We strongly advise to confirm the status from the server side
      }

      function onArkoseScriptError(error) {
        if (scriptRetryCount === maxRetryCount) {
          removeArkoseScript();
          handleFailure();
          return;
        }
        // Retry loading of Arkose script
        removeArkoseScript();
        createArkoseScript();
        scriptRetryCount++;
      }

      function removeArkoseScript() {
        const arkoseScripts = document.querySelectorAll(
          `script[src="${arkoseScriptSrc}"]`
        );
        for (const script of arkoseScripts) {
          script.remove();
        }
      }

      function createArkoseScript() {
        const script = document.createElement('script');
        script.type = 'text/javascript';
        script.src = arkoseScriptSrc;
        script.setAttribute('data-callback', 'setupEnforcement');
        script.async = true;
        script.defer = true;
        script.onerror = onArkoseScriptError;
        script.id = 'arkose-script';
        document.head.append(script);
      }

      async function checkArkoseAPIHealthStatus() {
        try {
          const healthResponse = await fetch(
            'https://status.arkoselabs.com/api/v2/status.json'
          );
          const healthJson = await healthResponse.json();
          const status = healthJson.status.indicator;
          return status === 'none'; // status "none" indicates Arkose systems are healthy
        } catch (error) {
          return false;
        }
      }
      /*
        This global function will be invoked when the API is ready. Ensure the name is the same name
        that is defined on the attribute `data-callback` in the script tag that loads the api for your
        public key.
        */
      function setupEnforcement(myEnforcement) {
        myEnforcement.setConfig({
          selector: '#enforcement-trigger',
          onCompleted: function (response) {
            console.log(response.token);
          },
          onError: async function (response) {
            const arkoseStatus = await checkArkoseAPIHealthStatus();
            if (arkoseStatus && enforcementRetryCount < maxRetryCount) {
              myEnforcement.reset();
              // To ensure the enforcement has been successfully reset, we need to set a timeout here
              setTimeout(function () {
                myEnforcement.run();
              }, 500);
              enforcementRetryCount++;
              return;
            }
            // The Arkose API is unhealthy or retry count has exceeded
            handleFailure();
          },
        });
      }
      createArkoseScript(); // load Arkose script on page load
    </script>
  </body>
</html>

Real Time Arkose Labs API Status

You can view real-time status of the Arkose Labs APIs at: http://status.arkoselabs.com.

This takes you to a dashboard that shows the health of Arkose Labs services.

Arkose Labs Status Endpoint

You can check whether the Arkose Labs APIs are up either visually or via an API call,

The Status check API call is:

GET https://status.arkoselabs.com/api/v2/status.json

The call returns one of the following JSON responses. The key part is the status field and its indicator and description subfields which can have these paired values:

FieldValueFieldValue
"indicator""none""description""All Systems Operational"
"indicator""minor""description""Partially Degraded Service"
"indicator""minor""description""Minor Service Outage"
"indicator""major""description""Partial System Outage"
"indicator""critical""description""Major System Outage"

All Systems Operational

{
    "page": {
        "id": "ntmkcpjv4jzt",
        "name": "Arkose Labs",
        "url": "https://status.arkoselabs.com",
        "time_zone": "Australia/Brisbane",
        "updated_at": "2019-12-21T12:23:44.180+10:00"
    },
    "status": {
        "indicator": "none",
        "description": "All Systems Operational"
    }
}

Partially Degraded Service (1 or all regions)

{
    "page": {
        "id": "ntmkcpjv4jzt",
        "name": "Arkose Labs",
        "url": "https://status.arkoselabs.com",
        "time_zone": "Australia/Brisbane",
        "updated_at": "2020-03-06T09:01:34.496+10:00"
    },
    "status": {
        "indicator": "minor",
        "description": "Partially Degraded Service"
    }
}

Partial System Outage (1 or more regions partial outage but not all regions)

{
    "page": {
        "id": "ntmkcpjv4jzt",
        "name": "Arkose Labs",
        "url": "https://status.arkoselabs.com",
        "time_zone": "Australia/Brisbane",
        "updated_at": "2020-03-06T09:07:06.394+10:00"
    },
    "status": {
        "indicator": "minor",
        "description": "Minor Service Outage"
    }
}

Partial System Outage (All regions)

{
    "page": {
        "id": "ntmkcpjv4jzt",
        "name": "Arkose Labs",
        "url": "https://status.arkoselabs.com",
        "time_zone": "Australia/Brisbane",
        "updated_at": "2020-03-06T09:07:06.394+10:00"
    },
    "status": {
        "indicator": "major",
        "description": "Partial System Outage"
    }
}


Major System Outage (1 or more regions major outage but not all regions)

{
    "page": {
        "id": "ntmkcpjv4jzt",
        "name": "Arkose Labs",
        "url": "https://status.arkoselabs.com",
        "time_zone": "Australia/Brisbane",
        "updated_at": "2020-03-06T09:07:06.394+10:00"
    },
    "status": {
        "indicator": "major",
        "description": "Partial System Outage"
    }
}

Major System Outage (All regions major outage)

{
    "page": {
        "id": "ntmkcpjv4jzt",
        "name": "Arkose Labs",
        "url": "https://status.arkoselabs.com",
        "time_zone": "Australia/Brisbane",
        "updated_at": "2020-03-06T09:07:06.394+10:00"
    },
    "status": {
        "indicator": "critical",
        "description": "Major System Outage"
    }
}

The status:description will contain information regarding outages. If there are no outages it will contain All Systems Operational.

Using the API Status Endpoint With Your Service

We use the term Fail Open to mean that even when failure conditions for the Arkose Platform are present, we want the overall process to proceed. We recommend you integrate and configure Arkose APIs so that they can be bypassed in the rare event of any Arkose API-related service disruption and your process can proceed.

Server-Side

On the server side, Verify API calls ensure that a valid token is present. An unexpectedly long response time or server side HTTP error code could signal an issue with a call. To rule out localized issues, please check Arkose Services' status by calling the Arkose Status API as shown above. You can use the response (All Systems Operational, Partially Degraded Service, Minor Service Outage, Partial System Outage, or Major System Outage) to decide on the right fallback flow. If there is an outage or disruption, then your server should bypass any validity checks for the Arkose token and let the user continue the session.

Client-Side

An unexpected failure of the Client API could stop a website from loading or negatively impact the user experience. Use the Arkose Client API's onError() callback to handle errors gracefully.

When the Client API request timeouts, use the Enforcement Object's reset callback to retry the call. If the issue persists, check the service's status by calling the Arkose Status API as shown above. If the response confirms an outage, switch to your system's fallback flow. You should check for other JavaScript or third-party errors before bypassing the Arkose Client API or switching to a fallback option.

Regional Endpoint Health Checks

📘

The values in the table below are subject to change at any time.

Use the following code to access regional health checks and response time information:

// General format:
GET https://status.arkoselabs.com/metrics-display/{component_ID}/{timerange}

// Or for a specific example getting the Singapore response time:
GET https://status.arkoselabs.com/metrics-display/13lww8jwjcfq/day.json

Use the table below to get the correct component_ID and timerange.

Healthcheckcomponent_idtimerange
North Virginia Healthcheckx7vj2bf6ckzvday.json
week.json
month.json
North Virginia Response Time6wbnmjn5w03xday.json
week.json
month.json
Oregon Healthcheckf5txw3k5rpbsday.json
week.json
month.json
Oregon Response Timem3pl0rjry4cyday.json
week.json
month.json
Singapore Healthcheckp3frx5vqjd5xday.json
week.json
month.json
Singapore Response Time13lww8jwjcfqday.json
week.json
month.json
Ireland Healthcheckcdplvgx9msf1day.json
week.json
month.json
Ireland Response Time8t7xx4yjbswjday.json
week.json
month.json
Sydney Healthcheckwcd34f7xkc0cday.json
week.json
month.json
Sydney Response Timegljgfg9zqpcgday.json
week.json
month.json

Here is a sample of code interrogates the Regional Endpoints for status and metrics.

const axios = require("axios");
const NorthVirginiaHealth = "x7vj2bf6ckzv";
const NorthVirginiaTiming = "6wbnmjn5w03x";

function getOperationalStatus() {
  axios
    .get(`https://status.arkoselabs.com/api/v2/status.json`)
    .then(function(response) {
      console.log(`Arkose Labs Status: ${response.data.status.description}`);
    })
    .catch(function(error) {
      console.log(error);
    });
}

function getCurrentHealthcheck(endpoint, timerange) {
  axios
    .get(
      `https://status.arkoselabs.com/metrics-display/${endpoint}/${timerange}`
    )
    .then(function(response) {
      console.log(`North Virginia health is ${response.data.summary.last}%`);
    })
    .catch(function(error) {
      console.log(error);
    });
}

function getLastResponseTiming(endpoint, timerange) {
  axios
    .get(
      `https://status.arkoselabs.com/metrics-display/${endpoint}/${timerange}`
    )
    .then(function(response) {
      console.log(`North Virginia last response time was: ${response.data.summary.last}ms`);
    })
    .catch(function(error) {
      console.log(error);
    });
}