Guides

AWS WAF mobile token integration guide

Build a documented AWS WAF mobile token integration: create and poll AntiAwsWafMobileTask, then use the returned cookie in authorized API calls.

AWS WAF mobile token integration guide

AWS WAF mobile token integration guide

Mobile APIs protected by AWS WAF can expect an aws-waf-token cookie that was produced by the AWS WAF mobile SDK. For an authorized integration, the documented CapBypass AntiAwsWafMobileTask creates a mobile token task, then returns a cookie and token when the task is ready. This guide shows the request shape, a polling pattern, and how to attach the returned cookie to an API request.

Use this task only for an application and API you are authorized to test or automate. The mobile task is distinct from the AWS WAF web task types: it takes only task.type. It does not accept a page URL, web challenge parameters, or a proxy.

Choose the mobile task deliberately

The current AWS WAF documentation lists three AWS WAF task types. AntiAwsWafTaskProxyLess is for a web challenge using CapBypass proxy infrastructure. AntiAwsWafTask is for a web challenge where you supply a proxy. AntiAwsWafMobileTask is the mobile-app task.

For the mobile task, create the task with exactly this object:

{
  "type": "AntiAwsWafMobileTask"
}

That difference matters. Do not copy websiteURL, awsChallengeJS, awsApiJs, or proxy from a web-task example into a mobile task. The documented mobile flow returns a fresh solution.cookie and solution.token. The cookie is already formatted as an aws-waf-token cookie value, while the token lets an authorized client construct that header itself when needed.

A production integration normally has three boundaries:

  1. A server-side component holds the CapBypass API key.
  2. The component creates and polls a task.
  3. The authorized mobile API request receives the returned cookie without logging its value.

Keeping task creation on the server prevents a mobile app bundle from exposing the API key. It also makes polling, error handling, and request auditing consistent across clients.

Create and poll the task with curl

Set one environment variable before running the examples:

export CAPBYPASS_API_KEY='replace-with-your-key'

Create the task at https://api.capbypass.pro/createTask. Save the returned taskId; it is the only value needed to poll getTaskResult.

curl --fail-with-body --silent --show-error \
  --request POST 'https://api.capbypass.pro/createTask' \
  --header 'Content-Type: application/json' \
  --data "{\"clientKey\":\"${CAPBYPASS_API_KEY}\",\"task\":{\"type\":\"AntiAwsWafMobileTask\"}}"

A successful creation response contains errorId: 0 and a taskId. Poll with the same key and that task identifier:

curl --fail-with-body --silent --show-error \
  --request POST 'https://api.capbypass.pro/getTaskResult' \
  --header 'Content-Type: application/json' \
  --data "{\"clientKey\":\"${CAPBYPASS_API_KEY}\",\"taskId\":\"YOUR_TASK_ID\"}"

Do not treat every non-ready response as a failure. Continue polling until status is ready, but stop immediately when the response reports a nonzero errorId. When ready, read solution.cookie. Pass it as the Cookie header on the authorized request rather than adding it to a URL or query string.

Use a bounded Python polling helper

This complete Python example reads the key from CAPBYPASS_API_KEY, creates the documented mobile task, polls with a timeout, and returns the cookie. Install requests in the environment that runs the integration.

import os
import time
import requests

BASE_URL = "https://api.capbypass.pro"
API_KEY = os.environ["CAPBYPASS_API_KEY"]


def post(path, payload):
    response = requests.post(f"{BASE_URL}{path}", json=payload, timeout=30)
    response.raise_for_status()
    body = response.json()
    if body.get("errorId"):
        raise RuntimeError(body.get("errorDescription", "CapBypass task error"))
    return body


def get_mobile_cookie():
    created = post(
        "/createTask",
        {
            "clientKey": API_KEY,
            "task": {"type": "AntiAwsWafMobileTask"},
        },
    )
    task_id = created["taskId"]
    deadline = time.monotonic() + 120

    while time.monotonic() < deadline:
        result = post(
            "/getTaskResult",
            {"clientKey": API_KEY, "taskId": task_id},
        )
        if result.get("status") == "ready":
            cookie = result["solution"]["cookie"]
            if not cookie.startswith("aws-waf-token="):
                raise RuntimeError("Unexpected mobile task cookie format")
            return cookie
        time.sleep(2)

    raise TimeoutError("Mobile task did not become ready before the deadline")


if __name__ == "__main__":
    cookie = get_mobile_cookie()
    print("Mobile token task is ready; attach the returned cookie to your authorized request.")

The helper does not print the cookie. Treat it as a credential for the protected request. If your authorized API client uses a persistent session, scope the cookie to the single request or short sequence that needs it rather than placing it in a shared global cookie jar.

Attach the cookie in an authorized client request

A token task is not the final API request. After polling returns ready, pass the cookie to the authorized endpoint using the normal HTTP Cookie header. The target URL below is intentionally an application-owned endpoint. Replace it with an endpoint you control or are permitted to test.

import os
import requests

cookie = "aws-waf-token=VALUE_RETURNED_BY_YOUR_TASK"
response = requests.get(
    os.environ["AUTHORIZED_API_URL"],
    headers={"Cookie": cookie},
    timeout=30,
)
response.raise_for_status()
print(response.status_code)

Keep the solver call and target API call close together. The documentation describes mobile tokens as single-use and short-lived, so a queue that produces a large backlog of tokens is a poor fit. Create a task when an authorized request is ready to be made, then consume the returned cookie promptly.

You may receive solution.token as well as solution.cookie. Prefer the documented cookie field when the HTTP client accepts a complete cookie value. If an approved native client needs only the value, build the header as aws-waf-token=<token> and avoid changing the token text.

TypeScript service example

The following TypeScript function uses the same two endpoints and stops on a task error or timeout. It relies on the fetch implementation included in current Node.js releases.

const baseUrl = "https://api.capbypass.pro";
const apiKey = process.env.CAPBYPASS_API_KEY;

if (!apiKey) {
  throw new Error("CAPBYPASS_API_KEY is required");
}

type TaskResponse = {
  errorId?: number;
  errorDescription?: string;
  taskId?: string;
  status?: string;
  solution?: { cookie?: string; token?: string };
};

async function capbypassPost(path: string, payload: object): Promise<TaskResponse> {
  const response = await fetch(`${baseUrl}${path}`, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify(payload),
  });
  if (!response.ok) {
    throw new Error(`CapBypass HTTP ${response.status}`);
  }
  const body = (await response.json()) as TaskResponse;
  if (body.errorId) {
    throw new Error(body.errorDescription ?? "CapBypass task error");
  }
  return body;
}

export async function getAwsWafMobileCookie(): Promise<string> {
  const created = await capbypassPost("/createTask", {
    clientKey: apiKey,
    task: { type: "AntiAwsWafMobileTask" },
  });
  if (!created.taskId) {
    throw new Error("createTask did not return taskId");
  }

  const deadline = Date.now() + 120_000;
  while (Date.now() < deadline) {
    const result = await capbypassPost("/getTaskResult", {
      clientKey: apiKey,
      taskId: created.taskId,
    });
    if (result.status === "ready" && result.solution?.cookie) {
      if (!result.solution.cookie.startsWith("aws-waf-token=")) {
        throw new Error("Unexpected mobile task cookie format");
      }
      return result.solution.cookie;
    }
    await new Promise((resolve) => setTimeout(resolve, 2000));
  }
  throw new Error("Mobile task did not become ready before the deadline");
}

In a server route, call getAwsWafMobileCookie() immediately before the permitted request. Never return the solver key to an app client. If the target client must receive a token, apply the same access controls and short lifetime you would use for any other transient credential.

Handle errors without guessing task parameters

The documented API can return an error response during creation or polling. Record the error code and task ID in protected operational logs, but do not record API keys, tokens, or cookie values. A nonzero errorId is a stop condition for that attempt.

For ERROR_INVALID_TASK_DATA, compare the payload with the mobile schema first. The mobile task needs type: "AntiAwsWafMobileTask"; web fields do not belong in that object. For ERROR_TASK_NOT_FOUND, make sure the poll request uses the task ID returned by the same create request. For an authentication or balance error, resolve the account condition outside the retry loop.

Avoid turning a transient poll into an unbounded loop. A deadline, a modest polling interval, and a single clear error path make request behavior observable. If you retry a complete solve after an error, create a new task and do not reuse an old token.

Operate the integration as a short-lived exchange

A clean mobile-token integration treats each solve as a short-lived exchange rather than a reusable session credential. Start by deciding which server component is allowed to call CapBypass. Give that component the API key through its deployment environment, not through source code, a mobile configuration file, or a client-side analytics event. The component should be the only place that can make createTask and getTaskResult calls.

Next, define the request boundary. An authorized caller asks the server to perform a specific protected operation. The server validates that caller and operation before it creates a task. After the task is ready, the server attaches the returned cookie to the permitted request. This order avoids creating tokens for requests that will never be sent and keeps the sensitive result close to its use.

Use structured logs that identify the lifecycle without revealing values. Useful fields include a local request ID, the CapBypass task ID, the time spent waiting, the final status, and the error code when there is one. Do not include clientKey, solution.token, solution.cookie, an authorization header, or the full protected request in those logs. If operational staff must investigate a failure, the task ID and error description are enough to correlate the event.

A timeout should be visible to the caller as a retryable application outcome only when the caller is still authorized to repeat the operation. It should not silently fall back to a web task type, invent web parameters, or reuse a cookie from an earlier request. The mobile task schema is intentionally minimal. A schema mismatch is a configuration problem to correct, not a signal to add guessed fields.

Finally, test the whole path in an environment you own. Confirm that the task result is held in memory only long enough to make the authorized API request, that the cookie is sent in the expected header, and that application telemetry masks sensitive values. These checks turn the documented task response into a maintainable server-side integration rather than an opaque client-side workaround. Review the authorization decision, task timing, and sensitive-data masking whenever the protected API client changes. Keep ownership records current for every approved target and test environment.


Bonus: +5% credits on every top-up

New to CapBypass? Apply code WELCOME_2026 at checkout for an extra 5% in credits on every top-up, with no minimum and no expiry. Redeem it on the top-up page.


FAQ

Is AntiAwsWafMobileTask the same as an AWS WAF web task?

No. The current documentation separates the mobile task from AntiAwsWafTaskProxyLess and AntiAwsWafTask. The mobile task is created with its type only, while the web task types use a protected page URL and can use web challenge parameters.

Should a mobile client contain the CapBypass API key?

No. Keep the key in a server-side environment variable. Let a controlled server component create and poll the task, then use the result only in an authorized request flow.

Do I need to send both solution.cookie and solution.token?

No. The ready response provides both representations. For an HTTP request, use the documented solution.cookie as the Cookie header. Use the token only when an approved client needs to construct that header itself.

What should I do when a task is not ready?

Poll https://api.capbypass.pro/getTaskResult with the task ID returned by createTask, with a bounded deadline. Stop and handle a nonzero errorId; do not change the task type or add undocumented fields.

Next step

Validate the flow against an API you own or are explicitly authorized to test. Start with the minimal mobile task object, keep task results out of logs, and attach the returned cookie promptly to the authorized API request.

Ready to start solving CAPTCHAs?

Get started with CapBypass in minutes. No credit card required.

Published on September 4, 2026
Share:

Related Articles