> ## Documentation Index
> Fetch the complete documentation index at: https://docs.endstate.io/llms.txt
> Use this file to discover all available pages before exploring further.

# session.tapIntents.approve

> Approves a tap intent with the code the person typed and returns `redirectUrl`, where to send them next; it sends no idempotency key and is not retried after a failure.

```ts theme={null}
approve(tapIntentId: string, body?: ApproveUnitTapIntentRequest, options?: RequestOptions): Promise<TapIntentOutcome>
```

| | |
| - | - |
| Endpoint | [`POST /v1/units/{unit_id}/tap-intents/{tap_intent_id}/approve`](https://docs.endstate.io/api-reference/tap-intents/approve-a-tap-intent-with-this-tap) |
| Credential | Session token (`end_sess_...`) |
| Retry class | `write` |

Never repeated. The API accepts no idempotency key here, so a second send is a second write. Only `429 rate_limit.exceeded` is retried.

## Example

```ts theme={null}
const result = await session.tapIntents.approve("tapIntentId", {
  tapCode: "482913",
});
```

## Parameters

**unit\_id** `string` *required*

**tap\_intent\_id** `string` *required*

**tap\_code** `string`

The code the person typed. Required when the tap intent has `code_required`.

## Returns

`200` - `TapIntentOutcome`.

**id** `string` *required*

**status** `'approved' | 'canceled'` *required*

**redirect\_url** `string | null` *required*

Where to send the person after they confirm, with `tap_intent=<id>` added. Null after a cancel and when the tap intent has no redirect URL.

## Errors

Branch on `error.code`, never on the HTTP status - several codes share one.

| Code | HTTP | Retry |
| - | - | - |
| `auth.forbidden` | 403 | Do not retry |
| `auth.unauthorized` | 401 | Do not retry |
| `internal.error` | 500 | Safe to retry |
| `rate_limit.exceeded` | 429 | Safe to retry |
| `session_token.invalid_or_expired` | 401 | Do not retry |
| `session_token.wrong_chip` | 403 | Do not retry |
| `tap_intent.already_approved` | 409 | Do not retry |
| `tap_intent.already_consumed` | 409 | Do not retry |
| `tap_intent.busy` | 503 | Safe to retry |
| `tap_intent.canceled` | 409 | Do not retry |
| `tap_intent.code_attempts_exhausted` | 409 | Do not retry |
| `tap_intent.code_incorrect` | 400 | Do not retry |
| `tap_intent.code_required` | 400 | Do not retry |
| `tap_intent.code_unavailable` | 409 | Do not retry |
| `tap_intent.expired` | 409 | Do not retry |
| `tap_intent.not_found` | 404 | Do not retry |
| `tap_intent.tap_not_matched` | 409 | Do not retry |
| `tap_intent.unit_vaulted` | 409 | Do not retry |
| `unit.not_found` | 404 | Do not retry |
| `validation.failed` | 400 | Do not retry |

See [Errors and retries](https://docs.endstate.io/sdks/core/errors-and-retries.md) for the error types and how to narrow them.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.