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

# Métadonnées de transaction d'actions

> Describes how to pass user or application metadata between login and post-login Actions.

<Warning>
  Actions Transaction Metadata is currently in Early Access. By using this feature, you agree to the applicable Free Trial terms in Okta’s [Master Subscription Agreement](https://www.okta.com/legal/?_gl=1*agihqh*_gcl_au*NjM2NjA1MDg4LjE3NTM5ODE4NjY.*_ga*MTgyNDA4MjM2Ny4xNzE1MTAyMjQy*_ga_QKMSDV5369*czE3NTQ0NzQ3NTAkbzM1MyRnMSR0MTc1NDQ3NjU5MCRqNiRsMCRoMA..). To learn more, read [Product Release Stages](/docs/fr-CA/troubleshoot/product-lifecycle/product-release-stages).
</Warning>

Actions Transaction Metadata stores, accesses, and/or shares, custom metadata within a [post-login](/docs/fr-CA/fr-ca/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger) Action for the duration of a transaction.

Previously, each Action operated independently, making it difficult to pass information between them. With Actions Transaction Metadata, now it's possible to:

* Share data across Actions, such as API responses or intermediate calculations.
* Eliminate the need to re-fetch or re-calculate the same information in different Actions.

<Note>
  Before using transaction metadata in development, we recommend reviewing the limitations. To learn more, read [Actions Limitations](/docs/fr-CA/customize/actions/limitations).
</Note>

<div id="how-it-works">
  ## How it works
</div>

Use the [post-login API object](/docs/fr-CA/fr-ca/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger/post-login-api-object) `api.transaction.setMetadata` to set the key/value pair in order to store transaction metadata.

Use the [post-login Event object](/docs/fr-CA/fr-ca/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger/post-login-event-object) `event.transaction.metadata` to access stored key/value pair in the same Action or subsequent Actions on the post-login trigger for a single execution.

The API and Event objects accept the following parameters:

<table class="table">
  <thead>
    <tr>
      <th><strong>Value</strong></th>
      <th><strong>Type</strong></th>
      <th><strong>Description</strong></th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td><code>Key</code></td>
      <td><code>String</code></td>
      <td>The key of the metadata property to be set.</td>
    </tr>

    <tr>
      <td><code>Value</code></td>
      <td><code>String</code>, <code>Number</code>, <code>Boolean</code></td>
      <td>The value of the metadata property.<br />Set to <code>null</code> removes the property.</td>
    </tr>
  </tbody>
</table>

To learn more about writing Actions, read [Write Your First Action](/docs/fr-CA/fr-ca/customize/actions/write-your-first-action).

<div id="latency">
  ## Latency
</div>

Using Actions Transaction Metadata could cause a nominal additional latency. Any latency would be proportional to the metadata payload size and would be relevant when Action suspensions happen. For example, triggering <Tooltip data-tooltip-id="react-containers-DefinitionTooltip-0" tip="">MFA</Tooltip>, redirecting from Actions, or rendering Forms, could cause latency issues due to the need of reloading data from storage.

Still, the potential latency should be minimal than the redundant outgoing HTTP requests to retrieve data the sequence of Actions needs.

<div id="examples">
  ## Examples
</div>

<div id="access-metadata-immediately">
  ### Access metadata immediately
</div>

Set key/value pairs in transaction metadata and access values immediately.

```javascript lines theme={null}
exports.onExecutePostLogin = async (event, api) => {
  api.transaction.setMetadata('hello', 'Auth0');

  console.log('Hello ', event.transaction?.metadata?.hello);
  /* Outputs "Hello Auth0" */
};
```

<div id="set-supported-values">
  ### Set supported values
</div>

Set values of types: `string`, `number`, and `boolean`.

```javascript lines theme={null}
exports.onExecutePostLogin = async (event, api) => {
  api.transaction.setMetadata('string_value', 'Auth0');
  api.transaction.setMetadata('boolean_value', true);
  api.transaction.setMetadata('number_value', 12);

  console.log('string_value', event.transaction?.metadata?.string_value);
  /* Outputs "string_value Auth0" */
  console.log('boolean_value', event.transaction?.metadata?.boolean_value);
  /* Outputs "boolean_value true" */
  console.log('number_value', event.transaction?.metadata?.number_value);
  /* Outputs "number_value 12" */
};
```

<div id="serialize-values">
  ### Serialize values
</div>

Serialize values as `strings` within [limits](https://auth0.com/docs/customize/actions/limitations#transaction-metadata).

<Note>
  You cannot set values of types: `object` or `array`, but you can serialize as `strings.`
</Note>

```javascript lines theme={null}
exports.onExecutePostLogin = async (event, api) => {
  const serialized_object_value = JSON.stringify({
    string_value: 'Auth0',
    boolean_value: true,
    number_value: 12
  });

  api.transaction.setMetadata('serialized_object_value', serialized_object_value);

  const serialized_array_value = JSON.stringify([
    'Auth0',
    true,
    12
  ]);
  api.transaction.setMetadata('serialized_array_value', serialized_array_value);

  console.log('serialized_object_value',
    JSON.parse(event.transaction?.metadata?.serialized_object_value)
  );
  /* Outputs "serialized_object_value { string_value: 'Auth0', boolean_value: true, number_value: 12 }" */

  console.log('serialized_array_value',
    JSON.parse(event.transaction?.metadata?.serialized_array_value)
  );
  /* Outputs "serialized_array_value [ 'Auth0', true, 12 ]" */
};
```

<div id="share-values-between-actions">
  ### Share values between Actions
</div>

Share key/value pairs between Actions in the same execution sequence.

**Action 1**

Set `hello` key with `Auth0` value with the `api` object `setMetadata` method.

```javascript lines theme={null}
exports.onExecutePostLogin = async (event, api) => {
  api.transaction.setMetadata('hello', 'Auth0');
};
```

**Action 2**

Log the `Auth0` value for `hello` key in the transaction metadata with the `event` object `transaction.metadata` property to access the set values.

```javascript lines theme={null}
exports.onExecutePostLogin = async (event, api) => {
  console.log('Hello', event.transaction?.metadata?.hello);
  /* Outputs "Hello Auth0" */
};
```

<div id="update-metadata">
  ### Update metadata
</div>

Set an existing key with a different value to update metadata.

**Action 1**

Set transaction metadata key/value pair as `custom_tx_id` and `xyz123`.

```javascript lines theme={null}
exports.onExecutePostLogin = async (event, api) => {
  api.transaction.setMetadata('custom_tx_id', 'xyz123');
};
```

**Action 2**

Log the key as `custom_tx_id` and the value as `xyz123`. Then, set `custom_tx_id` to `abc456` to log again with the latest value for `custom_tx_id` in the transaction metadata.

```javascript lines theme={null}
exports.onExecutePostLogin = async (event, api) => {
  console.log('custom_tx_id', event.transaction?.metadata?.custom_tx_id);
  /* Outputs "custom_tx_id xyz123" */

  api.transaction.setMetadata('custom_tx_id', 'abc456');

  console.log('custom_tx_id', event.transaction?.metadata?.custom_tx_id);
  /* Outputs "custom_tx_id abc456" */
};
```

**Action 3**

Log the `abc456` value for `custom_tx_id`.

```javascript lines theme={null}
exports.onExecutePostLogin = async (event, api) => {
  console.log('custom_tx_id', event.transaction?.metadata?.custom_tx_id);
  /* Outputs "custom_tx_id abc456" */
};
```

<div id="remove-metadata">
  ### Remove metadata
</div>

Remove transaction metadata values by nullifying the value of each particular key.

**Action 1**

Set `custom_tx_id` in the transaction metadata.

```javascript lines theme={null}
exports.onExecutePostLogin = async (event, api) => {
  api.transaction.setMetadata('custom_tx_id', 'xyz123');
};
```

**Action 2**

Set `custom_tx_id` to `null` and log the `null` value for `custom_tx_id`.

```javascript lines theme={null}
exports.onExecutePostLogin = async (event, api) => {
  console.log('custom_tx_id', event.transaction?.metadata?.custom_tx_id);
  /* Outputs "custom_tx_id xyz123" */

  api.transaction.setMetadata('custom_tx_id', null);

  console.log('custom_tx_id', event.transaction?.metadata?.custom_tx_id);
  /* Outputs "custom_tx_id undefined" */
};
```

**Action 3**

Logs the `null` value for `custom_tx_id`.

```javascript lines theme={null}
exports.onExecutePostLogin = async (event, api) => {
  console.log('custom_tx_id', event.transaction?.metadata?.custom_tx_id);
  /* Outputs "custom_tx_id undefined" */
};
```

<div id="preserve-values-on-redirect-to-external-sites">
  ### Preserve values on redirect to external sites
</div>

Preserve transaction metadata during [redirects](/docs/fr-CA/fr-ca/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger/redirect-with-actions). Values are available when users continue the authentication flow.

**Action 1**

Sets a `custom_tx_id` in the transaction metadata.

```javascript lines theme={null}
exports.onExecutePostLogin = async (event, api) => {
  api.transaction.setMetadata('custom_tx_id', 'xyz123');
};
```

**Action 2**

Redirects to an external site sending a token with the `custom_tx_id` from the transaction metadata. Then it compares the `custom_tx_id` value at the transaction metadata with the one passed to the external site that has been sent back in the payload of another token.

```javascript lines theme={null}
exports.onExecutePostLogin = async (event, api) => {
  const token = api.redirect.encodeToken({
    secret: event.secrets.REDIRECT_SECRET,
    expiresInSeconds: 60, 
    payload: {
      custom_tx_id: event.transaction?.metadata?.custom_tx_id,
      continue_uri: `https://${event.secrets.TENANT_DOMAIN}/continue`
    },
  });

  api.redirect.sendUserTo(event.secrets.REDIRECT_URL, {
    query: { session_token: token }
  });
};

exports.onContinuePostLogin = async (event, api) => {
  const payload = api.redirect.validateToken({
    secret: event.secrets.REDIRECT_SECRET
  });

  console.log('Does custon_tx_id match?',
    payload?.custom_tx_id === event.transaction?.metadata?.custom_tx_id
  );
  /* Outputs "Does custon_tx_id match? True" */
};
```

<div id="preserve-values-on-forms-rendering">
  ### Preserve values on Forms rendering
</div>

[Render Forms using Actions](/docs/fr-CA/fr-ca/customize/forms/render) and transaction metadata values would be preserved and available when users continue the authentication flow.

To learn more about using Forms with Actions, read [Render Forms using Actions](/docs/fr-CA/fr-ca/customize/forms/render).

**Action 1**

Sets a `custom_tx_id` in the transaction metadata.

```javascript lines theme={null}
exports.onExecutePostLogin = async (event, api) => {
  api.transaction.setMetadata('custom_tx_id', 'xyz123');
};
```

**Action 2**

Renders a Form. Then it logs the preserved `custom_tx_id` when continuing the Actions execution.

```javascript lines theme={null}
exports.onExecutePostLogin = async (event, api) => {
  api.prompt.render(event.secrets.FORM_ID);
};

exports.onContinuePostLogin = async (event, api) => {
  console.log('custon_tx_id', event.transaction?.metadata?.custom_tx_id);
  /* Outputs "custom_tx_id xyz123" */
};
```

<div id="share-values-with-forms">
  ### Share values with Forms
</div>

You can render Forms using Actions and pass transaction metadata values to the Form.

**Action 1**

Sets a `custom_tx_id` in the transaction metadata.

```javascript lines theme={null}
exports.onExecutePostLogin = async (event, api) => {
  api.transaction.setMetadata('custom_tx_id', 'xyz123');
};
```

**Action 2**

Renders a Form passing the `custom_tx_id` from the transaction metadata as `vars` parameter. Then it compares the `custom_tx_id` value at the transaction metadata with the one passed to the Form, when continuing the Actions execution.

```javascript lines theme={null}
exports.onExecutePostLogin = async (event, api) => {
  api.prompt.render(event.secrets.FORM_ID, {
    vars: {
      custom_tx_id: event.transaction?.metadata?.custom_tx_id
    }
  });
};

exports.onContinuePostLogin = async (event, api) => {
  console.log('Does custon_tx_id match?',
    event.prompt?.vars?.custom_tx_id === event.transaction?.metadata?.custom_tx_id
  );
  /* Outputs "Does custon_tx_id match? True" */
};
```
