Skip to navigation

protect() options

Every option you can pass to protect(), with its type, default and what it does.

HumanApproved.q.push(["protect", {
key: "pk_live_…",
quote: "HTA-4471920",
before: "#continue-to-payment",
quoteDetails: () => ({ quote: { /* your product's fields */ }, mobile: "+1 415 555 0132" }),
userId: "CUST-1001",
onResult: (result) => console.info("HumanApproved", result.outcome),
timeoutMs: 2500,
}]);

Options

OptionTypeRequiredDefaultWhat it does
keystringYesYour publishable key, pk_live_… or pk_test_…. It identifies the product and its environment.
quotestringYesYour quote reference, 1 to 128 characters. Not personal data.
beforestringYesCSS selector for the step to protect: a button or link (its click) or a form (its submit).
quoteDetailsfunctionYesReturns { quote, mobile }, synchronously or as a promise. Called when a review starts, and on each press after an approval. See quoteDetails.
userIdstringNoNoneYour own ID for this customer. See userId.
signalobjectNoNoneYour own detection result, for products set to use it. See signal.
onResultfunctionNoNoneCalled once for each outcome. See Handling the outcome.
timeoutMsnumberNo2500How long the step waits for its check before it proceeds. See timeoutMs.
baseUrlstringNoNoneLeave it unset. The embed works out the host from your key.

quoteDetails

quoteDetails: async () => ({
quote: {
policyholder: { firstName: "Sam" },
destination: "Japan",
dates: { from: "2026-12-03", to: "2026-12-17" },
travellers: 2,
cover: "Comprehensive",
excess: 200,
premium: { amount: 412.6, currency: "USD" },
},
mobile: "+1 415 555 0132",
quoteUrl: "https://www.example.com/quote/resume/9f2c…", // optional
}),
FieldRequiredWhat it is
quoteYesThe quote, shaped by the fields on your product’s Fields page. Fields the product doesn’t define are dropped.
mobileYesThe customer’s own mobile, where the approval code is sent. Any valid mobile number, in international format, starting with + and its country code; a number without a country code is read as one from your region. A landline, or a number that isn’t valid, is refused with 422 invalid_quote.
quoteUrlNoA link where the customer can change the quote themselves. The approval page offers it if something’s wrong. It must be https, on one of the product’s allowed websites, and up to 2,000 characters. Never put personal data in it: use an opaque token your site resolves, with an expiry.

The quote must match your product’s published fields: a variant the product doesn’t list, or an extra it doesn’t name, is refused. If the quote is refused, the step proceeds, as for any error, and the browser console lists each field that was refused.

Keep it fast and free of side effects. It’s called when a review starts, with up to 10 seconds to return. After an approval, it’s called each time the step is used, and the step waits up to 2.5 seconds (or timeoutMs) for it. If it throws, returns something that isn’t { quote, mobile }, or takes too long, the step proceeds and the browser console shows the reason. See After an approval.

userId

Your own ID for this customer, such as a customer or account number. It’s sent with each check, so you can search a customer’s checks and approvals in the portal, and your server gets it back with the review.

  • 1 to 128 characters once trimmed, with no control characters. A value that breaks this is left out with a console warning, and the check still runs.
  • Use an opaque ID from your own system, not an email address, phone number or name. If the value looks like an email address or phone number, it isn’t stored.
  • It’s never kept in the browser’s storage.

signal

Your own detection result, sent instead of the embed’s own measures, for products set to use your own signal on the portal’s Agent detection page. All fields are optional:

signal: { source: "edge", score: 2, verifiedBot: "ChatGPT-User", isAgent: true },
FieldTypeWhat it is
sourcestringWhere the result came from, for your own records.
scorenumberYour detection’s score.
verifiedBotstringA verified bot’s name, if your detection identified one.
isAgentbooleanWhether your detection decided this is an agent.

See Agent detection for how a product uses it.

timeoutMs

How long the step waits for its check before it proceeds (fails open).

DefaultRange
Live keys (pk_live_…)2.5 seconds500 to 20,000 ms
Test keys (pk_test_…)2.5 seconds500 to 20,000 ms

A value outside the range is clamped to it.

  • The same limit bounds the comparison after an approval.
  • A re-check after a fail-open waits 1 second, or timeoutMs if that’s shorter.
  • When it runs out, onResult receives fail_open with reason: "timeout".
  • A longer limit means a customer can wait longer when HumanApproved is slow: at most twice per quote (the limit, then the 1-second re-check).
  • For a monitor-only product no press waits, so timeoutMs only matters for products that can pause a press.