> ## 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.

# endstate.tapIntents.create

> Opens a tap intent on one of your units and returns it with `tapCode`, the code to show the person; only this response carries the code.

```ts theme={null}
create(body: CreateTapIntentRequest, options?: IdempotentRequestOptions): Promise<CreatedTapIntent>
```

| | |
| - | - |
| Endpoint | [`POST /v1/tap-intents`](https://docs.endstate.io/api-reference/tap-intents/open-a-tap-intent) |
| Credential | Secret key (`end_sk_...`) |
| Retry class | `keyed` |
| Idempotency key | Accepted |

Carries an idempotency key. Retried on network failure, timeout, `429`, and `409 idempotency.in_progress` - never on a `5xx`.

## Example

```ts theme={null}
const result = await endstate.tapIntents.create({
  rule: "own",
  unitId: "6f1d2c3b-4a59-4e68-9f70-8a1b2c3d4e5f",
  action: { type: "listing.confirm", reference: "listing_8271" },
});
```

## Parameters

**rule** `'own'` *required*

Who may open the intent. `own` opens it on a unit in your own environment.

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

The unit the person will tap.

**action** `object` *required*

Opaque to Endstate. Stored with surrounding whitespace trimmed, returned on reads and in webhooks, and compared exactly when you consume.

**ttl** `integer`

Seconds the intent waits for a tap. A tap after that does not count.

**use\_within** `integer`

Seconds after the person approves in which you can consume the approval. Fixed here: `use_by` is `approved_at` plus this, and no call extends it.

**code** `boolean`

Whether the person must enter a code to confirm. On by default: the response carries `tap_code` for you to show them. Pass `false` only where the person asking is the person holding the item and a wrong approval costs little, because anyone who taps the item can then confirm.

**redirect\_url** `string`

Where the person is sent after they confirm. `tap_intent=<id>` is added to it. Must be on one of the environment's allowed origins.

**display** `object`

## Returns

`201` - `CreatedTapIntent`.

## 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 |
| `environment.invalid_configuration` | 409 | Do not retry |
| `idempotency.in_progress` | 409 | Safe to retry |
| `idempotency.key_conflict` | 409 | Do not retry |
| `internal.error` | 500 | Safe to retry |
| `not_found.resource` | 404 | Do not retry |
| `rate_limit.exceeded` | 429 | Safe to retry |
| `tap_intent.busy` | 503 | Safe to retry |
| `tap_intent.disabled` | 403 | Do not retry |
| `tap_intent.redirect_origin_not_allowed` | 400 | Do not retry |
| `tap_intent.too_many_open` | 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.