## Overview

When the Advanced Prefill workflow completes, it returns one of three outcomes: `ACCEPT`, `REJECT`, or `ON_HOLD`. This page covers how your integration detects, handles, and completes each flow — including OTP step-ups and the transition to Consumer Onboarding.

## Decision routing

Every Advanced Prefill evaluation produces a decision that determines the next action in your integration.

| Decision | Meaning | Your action |
| --- | --- | --- |
| `ACCEPT` | Risk checks passed — prefilled data can be disclosed | Display prefilled onboarding form |
| `REJECT` | Risk checks failed or no data available — data cannot be disclosed | Display blank onboarding form for manual entry |
| `ON_HOLD` | SNA failed — OTP verification required before a final decision | Collect OTP and resume the evaluation |

> 📘
>
> **Note**:
>
> Advanced Prefill decisions are **data disclosure decisions**, not final onboarding decisions. Do not use them to approve or reject applicants. The [Consumer Onboarding](https://help.socure.com/riskos/docs/consumer-onboarding) workflow makes the final KYC and fraud determination.

## Common outcomes

| Scenario | Decision | User experience |
| --- | --- | --- |
| Risk checks pass and Prefill data is available | `ACCEPT` | User sees a prefilled onboarding form |
| User fails Digital Intelligence checks | `REJECT` | User sees a blank onboarding form |
| User matches a deny list or fails Phone Risk / SIM Swap checks | `REJECT` | User sees a blank onboarding form |
| Silent Network Authentication (SNA) fails | `ON_HOLD` | User is prompted to enter an OTP |
| OTP verification fails or is abandoned | `REJECT` | User sees a blank onboarding form |
| Prefill data is not available for the given inputs | `REJECT` | User sees a blank onboarding form |

## Step-up path: OTP verification

Advanced Prefill uses a single step-up path. When Silent Network Authentication (SNA) cannot verify phone possession, the workflow pauses and requests a one-time passcode.

```
High risk or deny match
Pass
Success
Fail or unavailable
Verified
Failed or abandoned
Yes
No
Evaluation submitted
Device and phone checks
REJECT
SNA verification
Run Prefill
ON_HOLD — collect OTP
OTP result
Prefill data available?
ACCEPT — show prefilled form
```

### Detect the ON_HOLD signal

Check the evaluation response for:

- `status` is "ON_HOLD"
- `sub_status` is "Awaiting Customer OTP"

### Resume the evaluation

1. **Prompt** the user to enter the OTP delivered to their phone.
2. **Send** a `PATCH /api/evaluation/{eval_id}` request with the OTP code.
3. **Handle** the updated response — the evaluation returns `ACCEPT` or `REJECT`.

### OTP behavior

- The workflow resumes automatically when the OTP succeeds, fails, or expires.
- There is no API to force continuation — the evaluation remains paused until OTP resolves.
- A failed or expired OTP results in `REJECT`.

## Consumer Onboarding handoff

After Advanced Prefill reaches a terminal state (`ACCEPT` or `REJECT`), the user reviews their information and your integration starts the [Consumer Onboarding](https://help.socure.com/riskos/docs/consumer-onboarding) workflow.

### Accepted users

When Advanced Prefill returns `ACCEPT`:

1. **Display** the prefilled identity data returned in the `data_enrichments` response.
2. **Lock** `phone_number` and `date_of_birth` as read-only — these were verified during Prefill.
3. **Allow** the user to review and edit other fields (name, address, email).
4. **Create a new evaluation** with `workflow: "consumer_onboarding"` when the user submits.

### Rejected users

When Advanced Prefill returns `REJECT`:

1. **Display** a blank onboarding form — do not show any prefilled data.
2. **Collect** all required identity fields from the user manually.
3. **Create a new evaluation** with `workflow: "consumer_onboarding"` when the user submits.

### What to carry forward

When creating the Consumer Onboarding evaluation:

| Action | Detail |
| --- | --- |
| Create a **new**`id` | Each evaluation requires a unique identifier |
| Reuse `phone_number` | Carry forward the verified phone number |
| Reuse `date_of_birth` | Carry forward the verified date of birth |
| Reuse `di_session_token` | Use the same session token from the Advanced Prefill request |
| Include confirmed identity fields | Name, address, email, national ID — prefilled or manually entered |
| Do **not** reuse `eval_id` | The Consumer Onboarding evaluation is a separate workflow run |

### Example Consumer Onboarding request

```json
{
  "id": "onb-12345",
  "timestamp": "2026-04-02T12:05:00Z",
  "workflow": "consumer_onboarding",
  "data": {
    "individual": {
      "given_name": "Jane",
      "family_name": "Smith",
      "national_id": "123456789",
      "date_of_birth": "1990-05-15",
      "email": "jane.smith@example.com",
      "phone_number": "+13125551234",
      "di_session_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ...PiUsws9D6O3DjSjNDCbIJKciX44s",
      "address": {
        "line_1": "742 Evergreen Terrace",
        "line_2": "Apt 12B",
        "locality": "Springfield",
        "major_admin_division": "IL",
        "country": "US",
        "postal_code": "62704"
      },
      "additional_context": {
        "disclosure_purpose": "GLBA_502(e)"
      }
    }
  }
}
```

```curl
curl --request POST \
  --url https://riskos.sandbox.socure.com/api/evaluation \
  --header "Authorization: Bearer YOUR_API_KEY" \
  --header "Content-Type: application/json" \
  --header "Accept: application/json" \
  --data '{
    "id": "onb-12345",
    "timestamp": "2026-04-02T12:05:00Z",
    "workflow": "consumer_onboarding",
    "data": {
      "individual": {
        "given_name": "Jane",
        "family_name": "Smith",
        "national_id": "123456789",
        "date_of_birth": "1990-05-15",
        "email": "jane.smith@example.com",
        "phone_number": "+13125551234",
        "di_session_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ...PiUsws9D6O3DjSjNDCbIJKciX44s",
        "address": {
          "line_1": "742 Evergreen Terrace",
          "line_2": "Apt 12B",
          "locality": "Springfield",
          "major_admin_division": "IL",
          "country": "US",
          "postal_code": "62704"
        },
        "additional_context": {
          "disclosure_purpose": "GLBA_502(e)"
        }
      }
    }
  }'
```

## Operational recommendations

- **Design for ON_HOLD.** Most sessions where SNA is unavailable fall back to OTP. Ensure your UI handles the `ON_HOLD` → OTP → resume flow.
- **Monitor decision distribution.** Track the ratio of `ACCEPT`, `REJECT`, and `ON_HOLD` decisions to detect shifts in coverage or risk thresholds.
- **Handle OTP timeouts.** If a user does not complete OTP within a reasonable window, route them to a blank form rather than leaving the evaluation indefinitely paused.
- **Log routing signals.** Persist `decision`, `status`, `eval_id`, and `tags` for audit and analytics.
- **Do not start Consumer Onboarding early.** Wait for Advanced Prefill to return `ACCEPT` or `REJECT` before initiating the Consumer Onboarding evaluation.

## Common issues

### OTP not delivered
Verify the phone number is in E.164 format. Carrier filtering or unsupported carriers can prevent OTP delivery. Test across multiple carriers in Sandbox.

### OTP always fails
Confirm the `PATCH` request uses the correct `eval_id` from the original evaluation and that the OTP session has not expired. Each OTP code has a limited validity window.

### Prefill returns empty data
The Prefill enrichment did not find matching identity data for the given inputs. Add additional identifiers such as `email` or `address` to improve match accuracy. Confirm the `di_session_token` is present and valid.

### Unexpected REJECT with no clear cause
Advanced Prefill is intentionally conservative — any device, phone, or possession failure results in `REJECT`. Check the `data_enrichments` array for enrichment-level status codes and reason codes that indicate which check failed.

### Same phone number rejected once, then accepted
Advanced Prefill rejects landline, VoIP, and other non-mobile numbers. That classification comes from the Phone Risk enrichment's line-type signal (`phone.lineType`, such as `"landline"` or `"wireless"`), which the enrichment resolves in real time from third-party telecom and phone-validity sources. Because that upstream data is refreshed independently of Socure — and because a fallback source can return a different value when the primary source is slow or unavailable — the same phone number can resolve to a different line-type across two evaluations. A run that classifies the number as a landline returns `REJECT`; a later run that classifies it as wireless can pass. The request inputs are identical; the resolved line-type signal is not. Compare `phone.lineType` and `phone.carrier` in each evaluation's `data_enrichments` block to confirm. This reflects real-time data enrichment, not a workflow change.

### Evaluation stuck in ON_HOLD
The user likely did not complete OTP verification. Implement a timeout in your integration to detect stale paused evaluations and route the user to a blank onboarding form.

## Troubleshooting reference

### Error codes

| Code | Example response | Cause | Resolution |
| --- | --- | --- | --- |
| 400 | `{ "error": "invalid_phone" }` | Malformed input | Validate phone in E.164, DOB in ISO 8601 |
| 422 | `{ "error": "unsupported_schema" }` | Region or schema not supported | Check `address.country` and remove unsupported fields |
| 429 | `{ "error": "rate_limit" }` | Too many requests | Retry with exponential backoff and jitter |
| 500 | `{ "error": "server_error" }` | Transient backend error | Retry with backoff; escalate if persistent |

### OTP errors

| Symptom | Cause | Resolution |
| --- | --- | --- |
| No OTP delivered | Carrier filtering or bad format | Verify E.164 input; test across carriers |
| OTP always fails | Wrong `eval_id` or expired code | Confirm `PATCH` uses correct ID and active session |
| OTP passes but no Prefill | Suppression tag set | Do not display data; require manual entry |

### Escalation path

For production-impacting issues:

1. **Reproduce** the issue in Sandbox if possible.
2. **Capture** relevant identifiers: `eval_id`, full request payload, and `referenceId` from enrichments (if applicable).
3. **Open a support ticket** at [support@socure.com](mailto:support@socure.com) with: workflow name, input fields, expected vs. actual decision, and logs.

## FAQs

Can a single evaluation trigger multiple step-ups?

Advanced Prefill uses a single step-up path: OTP. The evaluation pauses once for OTP when SNA fails. There are no sequential step-ups within the Advanced Prefill workflow.

What happens if the user edits prefilled data?

Users can edit non-sensitive fields (name, address, email) on the prefilled form. The edited values are submitted to the Consumer Onboarding workflow. `phone_number` and `date_of_birth` should remain read-only since they were verified during Prefill.

How do Advanced Prefill decisions differ from Consumer Onboarding decisions?

Advanced Prefill returns **data disclosure decisions** (`ACCEPT`, `REJECT`, `ON_HOLD`) that control whether prefilled data is shown. Consumer Onboarding returns **onboarding decisions** (`ACCEPT`, `REJECT`, `REVIEW`) that determine whether the applicant can proceed. A Prefill `ACCEPT` does not guarantee a Consumer Onboarding `ACCEPT`.

Can I skip Advanced Prefill and go straight to Consumer Onboarding?

Yes. Advanced Prefill is optional. If you skip it, collect all identity data from the user manually and submit directly to the Consumer Onboarding workflow. See [Consumer Onboarding](https://help.socure.com/riskos/docs/consumer-onboarding).

Why did the same phone number pass once and get rejected as a landline another time?

Advanced Prefill does not store a fixed line-type for a phone number. On each evaluation, the Phone Risk enrichment resolves the line-type (`phone.lineType`) in real time from third-party telecom and phone-validity vendors. Those sources update independently — numbers can be ported or reassigned, classifications can be corrected, and a fallback vendor can disagree with the primary one — so the same number can resolve to `"landline"` on one run and `"wireless"` on another. Because the workflow rejects landline numbers, the decision follows the line-type returned at evaluation time. Identical request inputs do not guarantee identical enrichment outputs. To investigate a specific pair of evaluations, compare the `phone.lineType`, `phone.carrier`, and enrichment `referenceId` values — along with the evaluation timestamps — in each `data_enrichments` block.
