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

# Known Behaviors

> Intentional platform behaviors and edge cases to design around.

These are intentional surfaces or active edge cases. Design around them.

## Liveness can return `noFace` intermittently

The `liveness_detection` node occasionally returns `noFace` even when the user is clearly present, typically under poor lighting or when the user tilts their head during the check. Always route every liveness outcome forward. The video AI analysis handles deepfake scoring out of band.

## SMS OTP has a handoff timing issue

`two_factor_sms` currently has a known form-to-speech handoff timing issue where the avatar occasionally asks for the phone number verbally after the form submit. If SMS is required, audit the transition carefully before production use. Prefer `enter_email` followed by `two_factor_email` for most integrations.

## Recognition requires accumulated video

The `recognition` node needs several seconds of video to work. The greeting before recognition must have the avatar speaking for 5 seconds or more. Short greetings cause recognition to fail with `newUser` even for returning users.

See [Conversation Rule 8](/docs/guides/conversation-rules#8-the-greeting-must-be-long-enough-for-video-accumulation) for examples.

## Camera resumption after document scan

On some mobile devices, the camera occasionally does not resume immediately after a successful `document_scan`. If you build a flow where the user returns to a conversational node after a scan, verify this path on the devices you target.

## Document scan report fields are nested objects

Document scan report fields use Microblink nested structures, not plain strings. Use the safe value extractor pattern:

```js title="Safe value extractor" wrap theme={null}
function sv(v) {
  if (v == null) return '';
  if (typeof v === 'string') return v;
  if (v.latin && v.latin.value != null) return String(v.latin.value);
  if (v.originalString) return sv(v.originalString);
  if (v.day != null && v.month != null && v.year != null)
    return v.month + '/' + v.day + '/' + v.year;
  return '';
}
// Usage: sv(docReport.firstName) -> "ADA"
```

## Media URLs expire after 15 minutes

Media URLs in webhook payloads and session responses are signed and expire 15 minutes after generation. Download immediately if you need to retain them. Re-fetch the session to get a fresh URL if the original has expired.

## Delayed report fields

Some session report fields arrive 5-20 seconds after session completion:

| Field                                            | Timing          |
| ------------------------------------------------ | --------------- |
| `transcript`, `aiAnalysis`, `location`, `device` | Immediate       |
| `nodeReports`                                    | Delayed (5-20s) |
| `videoAIAnalysis`                                | Delayed (5-20s) |
| `media.avatarVideo`, `media.userVideo`           | Delayed (5-20s) |
| `media.screenshots`, `media.documentImages`      | Delayed (5-20s) |

Poll or use webhooks to consume delayed fields. See [Custom Pages](/docs/guides/custom-pages) for the split render pattern.

## Next Steps

<CardGroup cols={2}>
  <Card title="Conversation Rules" href="/docs/guides/conversation-rules">
    The 13 rules that make or break avatar behavior.
  </Card>

  <Card title="Production Checklist" href="/docs/guides/production-checklist">
    Pre-release checklist before shipping to production.
  </Card>

  <Card title="Error Reference" href="/docs/reference/errors">
    HTTP status codes and error response shapes.
  </Card>
</CardGroup>
