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

# PII Detection

> Read and redact personally identifiable information metadata on supported SDK text objects.

PII detection metadata is attached to text content when your network has PII detection enabled server-side. The native SDK helpers let apps read detected entities and produce redacted display text without changing the original post, comment, or message.

<Info>
  This page covers the client SDK surface only. Feature enablement, quota, billing, and moderation-console behavior are product or backend concerns and are intentionally not documented here.
</Info>

## SDK Surface

| Platform   | PII metadata helper                                               | Redaction helper                                               | Current SDK note                                                                       |
| ---------- | ----------------------------------------------------------------- | -------------------------------------------------------------- | -------------------------------------------------------------------------------------- |
| iOS        | `getPIIData()` on `AmityPost`, `AmityComment`, and `AmityMessage` | `redactedText(piiCategories:replaceChar:)` on the same objects | Public helper API is available.                                                        |
| Android    | `getPIIData()` on `AmityPost`, `AmityComment`, and `AmityMessage` | `redactedText(piiCategories, replaceChar)` on `Data.TEXT`      | Public helper API is available for text data.                                          |
| TypeScript | Not exposed in the current public SDK source                      | Not exposed                                                    | Use backend-provided data only if your integration has a separate API contract for it. |
| Flutter    | Not exposed in the current public SDK source                      | Not exposed                                                    | Use native SDK helpers through platform code only if your app owns that bridge.        |

## Data Model

Each detected entity is represented as a PII item.

| Field        | iOS type           | Android type        | Meaning                                                                                |
| ------------ | ------------------ | ------------------- | -------------------------------------------------------------------------------------- |
| `offset`     | `Int`              | `Int`               | Start index of the detected entity in the text.                                        |
| `length`     | `Int`              | `Int`               | Number of characters in the detected entity.                                           |
| `category`   | `AmityPIICategory` | `AmityPII.Category` | Normalized category when the SDK has one, or an `others` value for unknown categories. |
| `confidence` | `Double`           | `Double`            | Detection confidence score from the server-provided metadata.                          |

## Categories

The current native SDK helpers define dedicated categories for these values.

| Category                  | iOS               | Android                             |
| ------------------------- | ----------------- | ----------------------------------- |
| Email                     | `.email`          | `AmityPII.Category.EMAIL`           |
| Phone number              | `.phoneNumber`    | `AmityPII.Category.PHONE_NUMBER`    |
| IP address                | `.ipAddress`      | `AmityPII.Category.IP_ADDRESS`      |
| Address                   | `.address`        | `AmityPII.Category.ADDRESS`         |
| Passport number           | `.passportNumber` | `AmityPII.Category.PASSPORT_NUMBER` |
| Unknown or newer category | `.others(value)`  | `AmityPII.Category.OTHERS(value)`   |

<Tip>
  Handle unknown categories deliberately. The server can introduce category strings before every client UI has a named enum case.
</Tip>

## Parameters

| Parameter       | iOS type             | Android type              | Default    | Behavior                                                                                      |
| --------------- | -------------------- | ------------------------- | ---------- | --------------------------------------------------------------------------------------------- |
| `piiCategories` | `[AmityPIICategory]` | `List<AmityPII.Category>` | Empty list | Empty means redact every detected category. Provide categories to redact only selected types. |
| `replaceChar`   | `Character`          | `Char`                    | `*`        | Character used to replace each redacted character.                                            |

## Read and Redact

Use `getPIIData()` when you need entity metadata for moderation UI, highlighting, or audit views. Use `redactedText(...)` when the app should display masked text.

<CodeGroup>
  ```swift iOS theme={null}
  var cancellables = Set<AnyCancellable>()

  let livePost = postRepository.getPost(withId: postId)
  livePost.$snapshot
      .sink { post in
          guard let post else { return }

          let piiItems = post.getPIIData()
          let redactedText = post.redactedText(
              piiCategories: [.email, .phoneNumber],
              replaceChar: "#"
          )

          piiItems.forEach { pii in
              print("\(pii.category.value): \(pii.offset)-\(pii.length)")
          }

          showSuccessMessage(redactedText)
      }
      .store(in: &cancellables)

  let liveComment = commentRepository.getComment(withId: commentId)
  liveComment.$snapshot
      .sink { comment in
          guard let comment else { return }
          showSuccessMessage(comment.redactedText())
      }
      .store(in: &cancellables)

  let liveMessage = messageRepository.getMessage(messageId)
  liveMessage.$snapshot
      .sink { message in
          guard let message else { return }
          showSuccessMessage(message.redactedText())
      }
      .store(in: &cancellables)
  ```

  ```kotlin Android theme={null}
  import AmityPII

  val piiItems = post?.getPIIData().orEmpty()
  val redactedText = (post?.getData() as? AmityPost.Data.TEXT)
      ?.redactedText(
          piiCategories = listOf(
              AmityPII.Category.EMAIL,
              AmityPII.Category.PHONE_NUMBER
          ),
          replaceChar = '#'
      )
      .orEmpty()

  piiItems.forEach { pii ->
      print("${pii.category}: ${pii.offset}-${pii.length}")
  }

  val redactedComment = (comment?.getData() as? AmityComment.Data.TEXT)
      ?.redactedText()
      .orEmpty()

  val redactedMessage = (message?.getData() as? AmityMessage.Data.TEXT)
      ?.redactedText()
      .orEmpty()

  print(redactedText + redactedComment + redactedMessage)
  ```
</CodeGroup>

## Behavior Notes

* Redaction is non-destructive: it returns a string for display and does not change the stored text.
* The native helpers skip PII ranges that overlap with mention ranges so user and channel mentions are not accidentally masked.
* Metadata can be empty even when content is text. Treat an empty list as "no PII metadata on this object", not as a detection failure.
* Android redaction is available on `Data.TEXT`; non-text post, comment, or message data returns no redacted text through this helper.
* TypeScript and Flutter do not expose public PII helper methods in the current SDK source, so do not document `getPIIData()` or `redactedText()` for those SDKs.
