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

# PII Tokenisation in Blnk

> Learn how to secure sensitive customer data using PII tokenization.

export const CtaCallout = props => {
  const {title, buttonLabel, href, trackingEvent, buttonTarget, rel = "noopener noreferrer", children} = props;
  const handleCtaClick = () => {
    if (typeof window === "undefined" || !trackingEvent) {
      return;
    }
    try {
      window.dispatchEvent(new CustomEvent("blnk:docs-cta", {
        detail: {
          name: trackingEvent,
          href
        }
      }));
    } catch {}
    try {
      window.posthog?.capture?.(trackingEvent, {
        href
      });
    } catch {}
    const gaPayload = {
      cta_href: href
    };
    try {
      window.gtag?.("event", trackingEvent, gaPayload);
    } catch {}
    try {
      window.dataLayer = window.dataLayer || [];
      window.dataLayer.push({
        event: trackingEvent,
        ...gaPayload
      });
    } catch {}
  };
  const isExternal = typeof href === "string" && (/^https?:\/\//i).test(href);
  const target = buttonTarget ?? (isExternal ? "_blank" : undefined);
  const linkRel = isExternal ? rel : undefined;
  return <section className="cta-callout not-prose relative my-8 w-full min-w-0 overflow-hidden rounded-xl border border-zinc-200 p-5 dark:border-white/10">
      <div className="cta-callout-noise" aria-hidden="true" />
      <div className="cta-callout-layout">
        {title ? <div className="cta-callout-title-row">
            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 28 28" width="14" height="14" className="cta-callout-icon shrink-0 text-zinc-800 dark:text-zinc-200" aria-hidden="true">
              <g fill="none" fillRule="nonzero">
                <path d="M28 0v28H0V0h28ZM14.691833333333335 27.134333333333334l-0.012833333333333334 0.0023333333333333335 -0.08283333333333333 0.04083333333333334 -0.023333333333333334 0.004666666666666667 -0.016333333333333335 -0.004666666666666667 -0.08283333333333333 -0.04083333333333334c-0.011666666666666667 -0.004666666666666667 -0.022166666666666668 -0.0011666666666666668 -0.028000000000000004 0.005833333333333334l-0.004666666666666667 0.011666666666666667 -0.019833333333333335 0.49933333333333335 0.005833333333333334 0.023333333333333334 0.011666666666666667 0.015166666666666667 0.12133333333333333 0.08633333333333333 0.0175 0.004666666666666667 0.014000000000000002 -0.004666666666666667 0.12133333333333333 -0.08633333333333333 0.014000000000000002 -0.018666666666666668 0.004666666666666667 -0.019833333333333335 -0.019833333333333335 -0.4981666666666667c-0.0023333333333333335 -0.011666666666666667 -0.0105 -0.019833333333333335 -0.019833333333333335 -0.021Zm0.3091666666666667 -0.13183333333333336 -0.015166666666666667 0.0023333333333333335 -0.21583333333333335 0.1085 -0.011666666666666667 0.011666666666666667 -0.0035000000000000005 0.012833333333333334 0.021 0.5016666666666667 0.005833333333333334 0.014000000000000002 0.009333333333333334 0.008166666666666668 0.23450000000000004 0.1085c0.014000000000000002 0.004666666666666667 0.026833333333333334 0 0.03383333333333334 -0.009333333333333334l0.004666666666666667 -0.016333333333333335 -0.03966666666666667 -0.7163333333333334c-0.0035000000000000005 -0.014000000000000002 -0.011666666666666667 -0.023333333333333334 -0.023333333333333334 -0.025666666666666667Zm-0.8341666666666667 0.0023333333333333335a0.026833333333333334 0.026833333333334334 0 0 0 -0.0315 0.007000000000000001l-0.007000000000000001 0.016333333333333335 -0.03966666666666667 0.7163333333333334c0 0.014000000000000002 0.008166666666666668 0.023333333333333334 0.019833333333333335 0.028000000000000004l0.0175 -0.0023333333333333335 0.23450000000000004 -0.1085 0.011666666666666667 -0.009333333333333334 0.004666666666666667 -0.012833333333333334 0.019833333333333335 -0.5016666666666667 -0.0035000000000000005 -0.014000000000000002 -0.011666666666666667 -0.011666666666666667 -0.21466666666666667 -0.10733333333333334Z" strokeWidth="1.1667" />
                <path fill="currentColor" d="M14 2.916666666666667A1.75 1.75 0 0 1 15.750000000000002 4.666666666666667v6.302333333333334L21.207666666666668 7.816666666666667a1.75 1.75 0 0 1 1.75 3.031L17.5 14l5.457666666666667 3.151166666666667a1.75 1.75 0 0 1 -1.75 3.031l-5.457666666666667 -3.1500000000000004V23.333333333333336a1.75 1.75 0 0 1 -3.5 0v-6.302333333333334L6.792333333333334 20.183333333333337a1.75 1.75 0 1 1 -1.75 -3.031L10.5 14 5.042333333333334 10.848833333333333a1.75 1.75 0 0 1 1.75 -3.031l5.457666666666667 3.1500000000000004V4.666666666666667A1.75 1.75 0 0 1 14 2.916666666666667Z" strokeWidth="1.1667" />
              </g>
            </svg>
            <p className="cta-callout-title min-w-0 font-semibold text-zinc-800 dark:text-zinc-200">
              {title}
            </p>
          </div> : null}
        <div className={`cta-callout-body text-sm leading-normal text-zinc-800 dark:text-zinc-200${title ? " cta-callout-body--indented" : ""}`}>
          {children}
        </div>
        <a href={href} target={target} rel={linkRel} onClick={handleCtaClick} data-docs-cta={trackingEvent || undefined} className="cta-callout-button inline-flex items-center justify-center gap-1 rounded-full bg-white px-3 py-1.5 text-sm font-semibold transition hover:bg-zinc-100 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-white/50 dark:bg-white dark:hover:bg-zinc-200">
          {buttonLabel}
          <span className="cta-callout-button-arrow" aria-hidden="true">
            →
          </span>
        </a>
      </div>
    </section>;
};

<Info>Available in version 0.8.8 and later.</Info>

PII (Personally Identifiable Information) tokenization allows you to replace sensitive customer data with non-sensitive tokens while maintaining the ability to use the data for business operations.

By tokenizing PII within your identity records, you can enhance security, reduce compliance scope, and still maintain full functionality within your applications.

Blnk Ledger supports two types of tokenization:

1. **Standard Tokenization:** Replaces the original value with a completely random token.
2. **Format-Preserving Tokenization:** Creates a token that maintains the format and structure of the original data.

***

## Tokenizable fields

The following identity fields can be tokenized in Blnk Ledger:

* `FirstName`
* `LastName`
* `OtherNames`
* `EmailAddress`
* `PhoneNumber`
* `Street`
* `PostCode`

<Warning>
  Identity JSON uses **snake\_case** (`first_name`, `email_address`). Tokenization paths and `fields` arrays use **PascalCase** (`FirstName`, `EmailAddress`). They are not interchangeable.
</Warning>

| Identity JSON field | Tokenization name |
| :------------------ | :---------------- |
| `first_name`        | `FirstName`       |
| `last_name`         | `LastName`        |
| `other_names`       | `OtherNames`      |
| `email_address`     | `EmailAddress`    |
| `phone_number`      | `PhoneNumber`     |
| `street`            | `Street`          |
| `post_code`         | `PostCode`        |

Use PascalCase in tokenize and detokenize URLs, and in the `fields` array for multi-field requests.

***

## Tokenize a specific field

To tokenize a specific field, use the [Tokenize Field](/reference/tokenize-field) endpoint:

<CodeGroup>
  ```bash cURL wrap theme={"system"}
  curl -X POST "http://YOUR_BLNK_INSTANCE_URL/identities/{identity_id}/tokenize/EmailAddress" \
    -H "X-blnk-key: <api-key>"
  ```

  ```typescript TypeScript wrap theme={"system"}
  const response = await blnk.Identity.tokenizeField(
    'idt_3b63c8da-af29-4cc3-ad38-df17d87456e6',
    'EmailAddress',
  );
  ```
</CodeGroup>

```json Response theme={"system"}
{
  "message": "Field tokenized successfully"
}
```

***

## Tokenize multiple fields

To tokenize multiple fields in an identity at once, use the [Tokenize Identity](/reference/tokenize-identity) endpoint:

<CodeGroup>
  ```bash cURL wrap theme={"system"}
  curl -X POST "http://YOUR_BLNK_INSTANCE_URL/identities/{identity_id}/tokenize" \
    -H "X-blnk-key: <api-key>" \
    -H "Content-Type: application/json" \
    -d '{
      "fields": ["FirstName", "LastName", "EmailAddress", "PhoneNumber"]
    }'
  ```

  ```typescript TypeScript wrap theme={"system"}
  const response = await blnk.Identity.tokenize(
    'idt_3b63c8da-af29-4cc3-ad38-df17d87456e6',
    {
      fields: ['FirstName', 'LastName', 'EmailAddress', 'PhoneNumber'],
    },
  );
  ```
</CodeGroup>

```json Response theme={"system"}
{
  "message": "Fields tokenized successfully"
}
```

***

## View tokenized fields

To check which fields are currently tokenized for an identity, use the [Get Tokenized Fields](/reference/get-tokenized-fields) endpoint:

<CodeGroup>
  ```bash cURL wrap theme={"system"}
  curl -X GET "http://YOUR_BLNK_INSTANCE_URL/identities/{identity_id}/tokenized-fields" \
    -H "X-blnk-key: <api-key>"
  ```

  ```typescript TypeScript wrap theme={"system"}
  const response = await blnk.Identity.getTokenizedFields(
    'idt_3b63c8da-af29-4cc3-ad38-df17d87456e6',
  );
  ```
</CodeGroup>

```json Response theme={"system"}
{
  "tokenized_fields": ["FirstName", "LastName", "EmailAddress", "PhoneNumber"]
}
```

***

## Detokenize a specific field

To retrieve the original value of a tokenized field, use the [Detokenize Field](/reference/detokenize-field) endpoint:

<CodeGroup>
  ```bash cURL wrap theme={"system"}
  curl -X GET "http://YOUR_BLNK_INSTANCE_URL/identities/{identity_id}/detokenize/EmailAddress" \
    -H "X-blnk-key: <api-key>"
  ```

  ```typescript TypeScript wrap theme={"system"}
  const response = await blnk.Identity.detokenizeField(
    'idt_3b63c8da-af29-4cc3-ad38-df17d87456e6',
    'EmailAddress',
  );
  ```
</CodeGroup>

```json Response theme={"system"}
{
  "field": "EmailAddress",
  "value": "alice.smith@example.com"
}
```

***

## Detokenize multiple fields

To retrieve the original values of multiple tokenized fields, use the [Detokenize Identity](/reference/detokenize-identity) endpoint:

<CodeGroup>
  ```bash cURL wrap theme={"system"}
  curl -X POST "http://YOUR_BLNK_INSTANCE_URL/identities/{identity_id}/detokenize" \
    -H "X-blnk-key: <api-key>" \
    -H "Content-Type: application/json" \
    -d '{
      "fields": ["FirstName", "LastName", "EmailAddress", "PhoneNumber"]
    }'
  ```

  ```typescript TypeScript wrap theme={"system"}
  const response = await blnk.Identity.detokenize(
    'idt_3b63c8da-af29-4cc3-ad38-df17d87456e6',
    {
      fields: ['FirstName', 'LastName', 'EmailAddress', 'PhoneNumber'],
    },
  );
  ```
</CodeGroup>

```json Response theme={"system"}
{
  "fields": {
    "first_name": "Alice",
    "last_name": "Smith",
    "email_address": "alice.smith@example.com",
    "phone_number": "+1234567890"
  }
}
```

***

## Format-preserving tokenization example

When using format-preserving tokenization, the tokens maintain the same structure as the original data:

Original Email: `alice.smith@example.com`

Tokenized Email: `FPT:utlgv.jtwka@ifvnpgq.dfe:8jygO668erXz6F+2sQbaGh3StrdkiI7++8nthzFzk7lVtPtZqNgscpsUDWav9jYv4J8x`

The tokenized value preserves the email format while securing the actual content. This allows systems that rely on email formatting to continue functioning properly with tokenized data.

***

## Error handling

<Info>
  Structured errors are available from Blnk Core 0.15.0 and later.
</Info>

Tokenization requests can return `400 Bad Request`, `403 Forbidden`, or `409 Conflict` depending on the field state and server configuration.

| Code                          | When it happens                                                                                                                                                                       |
| :---------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `IDT_FIELD_NOT_TOKENIZABLE`   | Field name is wrong or not in the [tokenizable set](#tokenizable-fields). **Wrong casing is a common cause** - `first_name` returns this code even though `FirstName` is tokenizable. |
| `IDT_FIELD_ALREADY_TOKENIZED` | You tokenize a field that is already tokenized                                                                                                                                        |
| `IDT_FIELD_NOT_TOKENIZED`     | You detokenize a field that is not tokenized                                                                                                                                          |
| `IDT_TOKENIZATION_DISABLED`   | Tokenization is not configured on the server                                                                                                                                          |

```json 400 Bad Request wrap theme={"system"}
{
  "error": "field first_name is not tokenizable",
  "error_detail": {
    "code": "IDT_FIELD_NOT_TOKENIZABLE",
    "message": "field first_name is not tokenizable",
    "details": {}
  }
}
```

To resolve the error:

| Code                          | What to do                                                                                                                                      |
| :---------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------- |
| `IDT_FIELD_NOT_TOKENIZABLE`   | Use the PascalCase name from the [mapping table](#tokenizable-fields). For example, tokenize `/tokenize/FirstName`, not `/tokenize/first_name`. |
| `IDT_FIELD_ALREADY_TOKENIZED` | Skip tokenization or detokenize the field first if you need to replace the value                                                                |
| `IDT_FIELD_NOT_TOKENIZED`     | Tokenize the field before calling detokenize                                                                                                    |
| `IDT_TOKENIZATION_DISABLED`   | Configure `tokenization_secret` on your Blnk Core instance                                                                                      |

For the full error catalogue, see [API error codes](/advanced/error-codes).

***

## Why use PII tokenization?

1. **Enhanced Security:**

   **Reduced risk exposure**: Sensitive data is removed from your systems and replaced with tokens.
   **Breach protection**: Even if tokens are compromised, they cannot be reversed to obtain the original data without access to the tokenization system.

2. **Simplified Compliance:**

   **Reduced PCI DSS scope**: By tokenizing payment information, you can reduce the scope of compliance requirements.
   **GDPR and data privacy**: Helps meet data minimization requirements by limiting where actual PII is stored.

3. **Data Usability:**

   **Maintain functionality**: Systems can continue to process tokenized data without modification.
   **Format preservation**: Tokens can maintain the format of the original data, ensuring compatibility with existing systems.

4. **Audit and Access Control:**

   **Granular permissions**: Control which users and systems can detokenize specific fields.
   **Comprehensive audit trails**: All tokenization and detokenization events are logged for security monitoring.

***

## Best practices

1. **Only detokenize when necessary:** Keep data in tokenized form whenever possible
2. **Implement proper access controls:** Restrict detokenization capabilities to authorized users only
3. **Use format-preserving tokens:** When systems require specific data formats, use format-preserving tokenization
4. **Regular security reviews:** Periodically review tokenization practices and access patterns

***

## Need help?

We are very happy to help you make the most of Blnk, regardless of whether it is your first time or you are switching from another tool.

To ask questions or discuss issues, please [contact us](mailto:support@blnkfinance.com) or [join our Discord community](https://discord.gg/7WNv94zPpx).

<CtaCallout title="Connect your ledger to Blnk Cloud" href="https://cloud.blnkfinance.com/auth/sign-up?utm_source=blnk_docs&utm_medium=documentation&utm_campaign=need-help" buttonLabel="Open Blnk Cloud" trackingEvent="clicked_cloud_signup">
  Sign up and manage your ledger with our back-office dashboard. You can invite teammates to collaborate and manage your ledger operations directly from the dashboard.
</CtaCallout>
