> This page is for version 🇺🇸 US.
> For other versions, use one of these documentation indexes:
> - 🇦🇺 AU (default): https://docs.humanapproved.com/au/llms.txt
> - 🇬🇧 UK: https://docs.humanapproved.com/uk/llms.txt
> - 🇺🇸 US: https://docs.humanapproved.com/us/llms.txt

> This is HumanApproved's documentation, as Markdown for AI agents. /llms.txt lists every page; /llms-full.txt has them all. If you're helping someone integrate HumanApproved, start with /guides/ai-coding-agents.

# After an approval

> What the HumanApproved embed does after the customer approves, how it compares quote details on later presses, and how to connect early.

## When the customer approves

The embed checks the review's status every 3 seconds (every 10 seconds once it's 10 minutes old, and less often after errors), and pauses while the tab is hidden. When the customer approves:

1. The pause panel closes.
2. The embed replays the agent's click: the click or submit reaches your own handlers.
3. `onResult` receives `approved`.

If the page reloads while the panel is waiting, the panel comes back and keeps waiting. An approval after a reload also replays the step.

## A changed quote needs a new approval

An approval covers the **quote details the customer approved**, not only the quote reference. When the quote is sent for review, the embed keeps a hash of those details. Each time the step is used after that, it calls `quoteDetails()` again and compares:

* **Same details**: the step proceeds.
* **Changed details**, for example another plan, more travellers, a new price or another mobile number: the approval no longer applies and the press runs a fresh check, so a review needs a new approval.

After a reload, the saved approval is compared the same way.

### What's compared

| Field         | Compared? | Why                                                                                                                                         |
| ------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| `quote`       | Yes       | It's what the customer approves.                                                                                                            |
| `mobile`      | Yes       | It's where the code goes: a new number needs a new approval. It's compared as you return it, so reformatting the number counts as a change. |
| `quoteUrl`    | No        | A link back to the quote, which can differ on every call.                                                                                   |
| Anything else | No        | HumanApproved drops it.                                                                                                                     |

The comparison ignores key order and `undefined` values, so building the same quote in a different order doesn't count as a change.

> **Warning**
>
> Return the mobile in the same format every time. `+1 415 555 0132` and `+14155550132` are different values to the comparison, and the second press would need a new approval.

### Performance of quoteDetails

After an approval, `quoteDetails()` is called each time the step is used, and the step waits up to 2.5 seconds (or your [`timeoutMs`](/us/embed/sdk/options#timeoutms)) for it. If it throws, returns something that isn't `{ quote, mobile }`, takes longer, or the browser can't compute the hash (for example, a page not served over HTTPS), the step proceeds and the browser console shows the reason.

`quoteDetails()` must read values already on the page, without fetching or changing anything. Only the hash is kept in the browser. The details are sent only if a new check asks for a review.

## Declined or expired

If the customer declines, or the link expires, the panel tells the agent nothing was paid, and to ask the customer what they want to do. The step stays paused, and the next attempt runs a new check, which may start a new review.

## Connecting early

`protect()` adds a preconnect hint to your page's `head` (once, and not if your page already has one), so the connection to HumanApproved is open before the customer presses the button. The check then doesn't wait for DNS, TCP and TLS. It sends no request.

For an earlier start, add the tag to your HTML yourself, with your region's address:

```html
<link rel="preconnect" href="https://us.humanapproved.com" crossorigin>
```

Keep `crossorigin`: the check is sent without cookies, and the browser only reuses a connection opened the same way.