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

# API Testing Tips

> Getting Started with Postman or Bruno for FrankieOne v2 API

## A Practical Guide to Testing FrankieOne v2 APIs

### Document Overview

This guide explains how to use **Postman** or **Bruno** to explore and test FrankieOne's **v2 APIs**, helping you understand how our platform works before integrating it into your application.

**API Version:** This guide focuses on **v2 APIs** (recommended for all new integrations)

### What You'll Learn

* What Postman and Bruno are and why they're useful
* How to choose the right tool for your team
* How to access FrankieOne's v2 API collection
* How to set up your environment
* How to create entities using v2 payloads
* How to run verification checks
* How to view results in the FrankieOne Portal
* Common testing scenarios with v2
* Troubleshooting tips

### Who Should Read This

* Developers evaluating FrankieOne
* Technical teams planning integration
* Anyone wanting to understand FrankieOne's v2 APIs
* Teams testing verification workflows

***

## Table of Contents

1. [Choosing Your API Client](#choosing-your-api-client)
2. [Getting Started](#getting-started)
3. [Setting Up Your Environment](#setting-up-your-environment)
4. [Understanding the v2 API Collection](#understanding-the-v2-api-collection)
5. [Using Testbed Data](#using-testbed-data)
6. [Running Your First v2 API Call](#running-your-first-v2-api-call)
7. [Viewing Results in the Portal](#viewing-results-in-the-portal)
8. [Common Testing Scenarios](#common-testing-scenarios)
9. [Understanding API Responses](#understanding-api-responses)
10. [Best Practices](#best-practices)
11. [Troubleshooting](#troubleshooting)
12. [Next Steps](#next-steps)
13. [FAQs](#faqs)

***

## Choosing Your API Client

### What Are API Clients?

API clients are tools that allow you to send API requests without writing code, see responses in real-time, and test different scenarios easily.

**Think of them as:** A visual interface for interacting with APIs—like a web browser for APIs instead of websites.

### Postman vs Bruno

| Feature               | Postman                 | Bruno                           |
| --------------------- | ----------------------- | ------------------------------- |
| **Price**             | Free tier (with limits) | Completely free and open-source |
| **Storage**           | Cloud-based             | Local filesystem                |
| **Account Required**  | Yes (for full features) | No                              |
| **Collaboration**     | Postman cloud           | Git version control             |
| **Offline Use**       | Limited                 | Full support                    |
| **Collection Format** | JSON                    | Bru (plain text)                |
| **Learning Curve**    | Beginner-friendly       | Beginner-friendly               |

### Which Should You Choose?

<CardGroup cols={2}>
  <Card title="Choose Postman if you:">
    * Want cloud sync across devices
    * Prefer a polished, feature-rich interface
    * Need built-in team collaboration features
    * Are already familiar with Postman
  </Card>

  <Card title="Choose Bruno if you:">
    * Want to version control your API collections with Git
    * Prefer data stored locally (privacy-focused)
    * Don't want to create an account
    * Work offline frequently
    * Want a lightweight, fast tool
  </Card>
</CardGroup>

<Note>
  Both tools work equally well with FrankieOne's v2 APIs. Choose based on your team's preferences.
</Note>

***

## Getting Started

### Step 1: Install Your Chosen Tool

<Tabs>
  <Tab title="Postman">
    **Download:**

    * Visit: [https://www.postman.com/downloads/](https://www.postman.com/downloads/)
    * Choose your operating system (Windows, Mac, Linux)
    * Download and install
    * Create a free account (optional but recommended)

    **Alternative:** Use Postman Web (browser-based) at [https://web.postman.co](https://web.postman.co)
  </Tab>

  <Tab title="Bruno">
    **Download:**

    * Visit: [https://www.usebruno.com/downloads](https://www.usebruno.com/downloads)
    * Choose your operating system (Windows, Mac, Linux)
    * Download and install
    * No account required

    **Alternative (Command Line):**

    ```bash theme={null}
    # macOS (Homebrew)
    brew install bruno

    # Windows (Chocolatey)
    choco install bruno

    # Linux (Snap)
    snap install bruno
    ```
  </Tab>
</Tabs>

### Step 2: Get FrankieOne's v2 API Collection

#### Where to Find It

* FrankieOne Developer documentation: [https://docs.frankieone.com/docs/introduction/resources](https://docs.frankieone.com/docs/introduction/resources)
* Contact your FrankieOne representative

#### What You'll Get

* Collection file (.json format)
* Pre-configured v2 API requests
* Example requests for all v2 endpoints
* Organized by functionality

### Step 3: Import the Collection

<Tabs>
  <Tab title="Postman">
    1. Click **"Import"** (top left)
    2. Choose file or drag and drop
    3. Select the FrankieOne v2 collection file
    4. Click **"Import"**

    **Result:** Collection appears in left sidebar, ready to use.
  </Tab>

  <Tab title="Bruno">
    1. Click **"Import Collection"**
    2. Select **"Postman Collection"**
    3. Choose the FrankieOne v2 collection file (.json)
    4. Select a folder location to store the collection
    5. Click **"Import"**

    **Result:** Bruno converts the collection to Bru format and stores it locally.

    <Tip>
      Since Bruno stores collections as files, you can immediately add them to Git for version control.
    </Tip>
  </Tab>
</Tabs>

### Step 4: Get Your API Credentials

**You'll need:**

| Credential                | Description                                          |
| ------------------------- | ---------------------------------------------------- |
| X-Frankie-CustomerID      | Your main customer/account ID                        |
| X-Frankie-CustomerChildID | Optional - for sub-account isolation (if configured) |
| api\_key                  | Your API authentication key                          |
| Environment               | UAT/Sandbox for testing                              |

**How to Get Them:**

1. Contact your FrankieOne representative
2. Request UAT/Sandbox access
3. Ask about Customer Child ID (if you have sub-accounts)
4. Receive credentials via secure channel
5. Keep credentials secure

**Environments:**

| Environment | Base URL                      | Purpose                                               |
| ----------- | ----------------------------- | ----------------------------------------------------- |
| UAT         | `https://api.uat.frankie.one` | User Acceptance Testing—for testing before production |
| Production  | `https://api.frankie.one`     | Live use only (not for testing)                       |

### Understanding Customer Child ID

**What is Customer Child ID?**

`X-Frankie-CustomerChildID` is an optional header used for **sub-account isolation** within your main FrankieOne account.

**When to Use It:**

| Scenario                          | Use CustomerChildID?                |
| --------------------------------- | ----------------------------------- |
| Single account, no sub-divisions  | ❌ No - leave blank                  |
| Multiple business units or brands | ✅ Yes - if configured by FrankieOne |
| White-label implementations       | ✅ Yes - if configured by FrankieOne |
| Reseller/partner accounts         | ✅ Yes - if configured by FrankieOne |

**How It Works:**

```mermaid theme={null}
graph TD
    A[Main Customer Account] --> B[X-Frankie-CustomerID: main-account-123]
    B --> C[Child 1: Brand A]
    B --> D[Child 2: Brand B]
    B --> E[Child 3: Region APAC]
    C --> F[X-Frankie-CustomerChildID: brand-a]
    D --> G[X-Frankie-CustomerChildID: brand-b]
    E --> H[X-Frankie-CustomerChildID: apac]
    
    style A fill:#e1f5ff,stroke:#333,stroke-width:2px
    style B fill:#d4edda,stroke:#333,stroke-width:2px
    style C fill:#fff3cd,stroke:#333,stroke-width:1px
    style D fill:#fff3cd,stroke:#333,stroke-width:1px
    style E fill:#fff3cd,stroke:#333,stroke-width:1px
```

**Key Points:**

* CustomerChildID is **configured by FrankieOne** - you cannot create child IDs via API
* All entities created with a specific CustomerChildID are isolated to that sub-account
* Reporting and data access are separated by CustomerChildID
* If you don't have sub-accounts, leave this header blank or omit it

<Warning>
  **Important:** If you have CustomerChildID configured, you must use the correct value in the header. Using the wrong CustomerChildID or omitting it when required may result in entities being created in the wrong sub-account or authentication errors.
</Warning>

**To Get Your CustomerChildID:**

1. Contact your FrankieOne representative
2. Ask if you have sub-accounts configured
3. Receive CustomerChildID values if applicable
4. Add to your environment variables

***

## Setting Up Your Environment

### What Are Environments?

Environments store variables like your API base URL, Customer ID, and API Key. They let you:

* Switch between UAT and Production easily
* Keep credentials secure
* Reuse variables across all requests
* Share collections without exposing keys

### Required Variables for v2 API

The following variables match the FrankieOne Postman environment:

| Variable                    | Example Value                     | Description                                                            |
| --------------------------- | --------------------------------- | ---------------------------------------------------------------------- |
| `frankie-environment`       | `uat`                             | Environment segment for URL construction (e.g., `uat`)                 |
| `X-Frankie-CustomerID`      | `your-customer-id`                | Your Customer ID provided by FrankieOne                                |
| `X-Frankie-CustomerChildID` | `your-customer-child-id`          | Optional: Customer Child ID for sub-account isolation                  |
| `api_key`                   | `your-api-key`                    | Your API Key (stored as secret)                                        |
| `serviceName`               | (provided by FrankieOne)          | Service profile name for workflow execution                            |
| `workflowName`              | (provided by FrankieOne)          | Workflow name for execution                                            |
| `entityId`                  | (populated after creating entity) | Entity ID for subsequent requests                                      |
| `executionId`               | (populated after workflow run)    | Workflow execution ID for retrieving results                           |
| `X-Frankie-Username`        | (optional)                        | Username of the API caller                                             |
| `X-Frankie-Channel`         | (optional)                        | Channel the request originates from (e.g., `api`, `portal`, `smartui`) |

<Note>
  **Additional element-level variables** are also available in the Postman environment for use after entity creation: `nameId`, `dateOfBirthId`, `addressId`, `documentId`, `phoneNumberId`, `emailAddressId`, `attachmentId`, and `sessionToken`. These are typically auto-populated by test scripts in the Postman collection.
</Note>

### Creating Your Environment

<Tabs>
  <Tab title="Postman">
    **Step 1: Create New Environment**

    1. Click **"Environments"** (left sidebar)
    2. Click **"+"** to create new
    3. Name it: `FrankieOne KYC V2 AUS`

    **Step 2: Add Variables**

    | Variable                    | Initial Value      | Current Value      | Type    |
    | --------------------------- | ------------------ | ------------------ | ------- |
    | `frankie-environment`       | `uat`              | `uat`              | default |
    | `X-Frankie-CustomerID`      | `your-customer-id` | `your-customer-id` | default |
    | `X-Frankie-CustomerChildID` | (optional)         | (optional)         | default |
    | `api_key`                   | `your-api-key`     | `your-api-key`     | secret  |
    | `serviceName`               |                    |                    | default |
    | `workflowName`              |                    |                    | default |
    | `entityId`                  |                    |                    | default |
    | `executionId`               |                    |                    | default |
    | `X-Frankie-Username`        | (optional)         | (optional)         | default |
    | `X-Frankie-Channel`         | (optional)         | (optional)         | default |

    **Step 3: Activate Environment**

    1. Click **"Save"**
    2. Select environment from dropdown (top right)
  </Tab>

  <Tab title="Bruno">
    **Step 1: Open Environment Settings**

    1. Click the **gear icon** (Environments)
    2. Click **"Create Environment"**
    3. Name it: `FrankieOne KYC V2 AUS`

    **Step 2: Add Variables**

    ```text theme={null}
    frankie-environment: uat
    X-Frankie-CustomerID: your-customer-id
    X-Frankie-CustomerChildID: your-customer-child-id
    api_key: your-api-key
    serviceName:
    workflowName:
    entityId:
    executionId:
    X-Frankie-Username:
    X-Frankie-Channel:
    ```

    <Note>
      **X-Frankie-CustomerChildID** is optional and used for sub-account isolation. Leave blank if not applicable.
    </Note>

    **Step 3: Activate Environment**

    1. Click **"Save"**
    2. Select `FrankieOne KYC V2 AUS` from the environment dropdown

    <Tip>
      Environment files are stored as `.bru` files in your collection's `environments/` folder. You can edit them directly in any text editor.
    </Tip>
  </Tab>
</Tabs>

### Using Variables in Requests

Both Postman and Bruno use the same syntax for variables:

```text theme={null}
{{variableName}}
```

**Example v2 Request URL:**

```text theme={null}
https://api.{{frankie-environment}}.frankie.one/v2/individuals
```

**Example Headers:**

```text theme={null}
api_key: {{api_key}}
X-Frankie-CustomerID: {{X-Frankie-CustomerID}}
X-Frankie-CustomerChildID: {{X-Frankie-CustomerChildID}}
X-Frankie-Channel: {{X-Frankie-Channel}}
X-Frankie-Username: {{X-Frankie-Username}}
Content-Type: application/json
```

<Note>
  **Optional headers:** `X-Frankie-CustomerChildID`, `X-Frankie-Channel`, and `X-Frankie-Username` are all optional. Include them only when applicable to your configuration. In the Postman collection, these optional headers are present but disabled by default.
</Note>

The tool automatically replaces `{{variableName}}` with the actual value from your environment.

***

## Understanding the v2 API Collection

### v2 API Structure

FrankieOne's v2 API collection is organized by entity type and functionality. The following reflects the folder structure in the FrankieOne Postman collection:

```text theme={null}
FrankieOne KYC V2 AUS
│
├── Individual Entities
│   ├── Create Entity with Aus Passport
│   ├── Update Entity
│   ├── Get Entity
│   └── Delete Entity
│
├── Individual Workflows
│   ├── Get Workflows
│   ├── Create Entity and Execute Workflow
│   ├── Execute Workflow
│   ├── Get a Workflow Execution
│   └── Get a List of Workflow Executions
│
├── Individual Documents
│   ├── Create Document
│   └── Delete Document
│
├── Individual IDV
│   ├── Get IDV Token
│   └── Process IDV OCR
│
├── Individual Service Profiles
│   └── Get Service Profile for Entity
│
├── Individual Results
│   ├── Create mKYC results
│   ├── Update AML results
│   └── Get results
│
├── Individual Monitoring
│   └── Toggle AML Monitoring
│
└── Search
    └── Search Service Profiles
```

### Key v2 Endpoints

| Category             | Endpoint                                                                                                     | Method   | Purpose                                            |
| -------------------- | ------------------------------------------------------------------------------------------------------------ | -------- | -------------------------------------------------- |
| **Individuals**      | `/v2/individuals`                                                                                            | `POST`   | Create an individual entity                        |
|                      | `/v2/individuals/{entityId}`                                                                                 | `GET`    | Retrieve individual details                        |
|                      | `/v2/individuals/{entityId}`                                                                                 | `PATCH`  | Update individual information                      |
|                      | `/v2/individuals/{entityId}`                                                                                 | `DELETE` | Delete an individual entity                        |
| **Workflows**        | `/v2/individuals/{entityId}/serviceprofiles/{serviceName}/workflows/{workflowName}/execute`                  | `POST`   | Execute verification workflow                      |
|                      | `/v2/individuals/new/serviceprofiles/{serviceName}/workflows/{workflowName}/execute`                         | `POST`   | Create individual and execute workflow in one call |
|                      | `/v2/individuals/{entityId}/serviceprofiles/{serviceName}/workflows/{workflowName}/executions`               | `GET`    | List workflow executions                           |
|                      | `/v2/individuals/{entityId}/serviceprofiles/{serviceName}/workflows/{workflowName}/executions/{executionId}` | `GET`    | Get a specific workflow execution                  |
| **Documents**        | `/v2/individuals/{entityId}/documents`                                                                       | `POST`   | Create a new document for an individual            |
|                      | `/v2/individuals/{entityId}/documents`                                                                       | `GET`    | Get all documents for an entity                    |
| **IDV**              | `/v2/individuals/{entityId}/actions/idv/token`                                                               | `POST`   | Get IDV token for provider SDK                     |
| **Results**          | `/v2/individuals/{entityId}/results`                                                                         | `GET`    | Get verification results                           |
|                      | `/v2/individuals/{entityId}/results/aml`                                                                     | `PATCH`  | Update AML result status                           |
|                      | `/v2/individuals/{entityId}/results/mkyc`                                                                    | `POST`   | Approve manual KYC                                 |
| **Monitoring**       | `/v2/individuals/{entityId}/monitoring`                                                                      | `PATCH`  | Toggle AML monitoring on/off                       |
| **Service Profiles** | `/v2/individuals/{entityId}/serviceprofiles/{serviceName}`                                                   | `GET`    | Get service profile for entity                     |
| **Search**           | `/v2/search/serviceprofiles`                                                                                 | `POST`   | Search for entity profiles                         |

<Note>
  All v2 endpoint paths start directly with `/v2/`. There is no base path prefix such as `compliance/v1.2` (that belongs to the v1 API).
</Note>

***

## Using Testbed Data

### What is Testbed Data?

Testbed data is pre-configured test data that produces predictable results in the FrankieOne UAT environment.

**Purpose:**

* Test different scenarios
* No real customer data needed
* Consistent, repeatable results
* Safe for testing

**Available at:** [https://docs.frankieone.com/docs/test-data](https://docs.frankieone.com/docs/test-data)

### Test Scenario Types

| Scenario          | Result                              | Use Case                    |
| ----------------- | ----------------------------------- | --------------------------- |
| **PASS (CLEAR)**  | Verification succeeds               | Test successful onboarding  |
| **FAIL (FRAUD)**  | Verification fails / fraud detected | Test rejection flows        |
| **REVIEW**        | Manual review required              | Test escalation workflows   |
| **PEP**           | Politically Exposed Person match    | Test AML screening          |
| **SANCTION**      | Sanctions list match                | Test AML screening          |
| **PEP, SANCTION** | Both PEP and sanctions match        | Test combined AML scenarios |

### v2 Testbed Data Examples

<AccordionGroup>
  <Accordion title="PASS Scenario (Australia) - v2 Format">
    ```json theme={null}
    {
      "individual": {
        "name": {
          "givenName": "JAMES",
          "middleName": "A",
          "familyName": "TESTONE"
        },
        "dateOfBirth": {
          "year": "1950",
          "month": "01",
          "day": "01"
        },
        "addresses": [
          {
            "type": "RESIDENTIAL",
            "status": "CURRENT",
            "unitNumber": "U 1",
            "streetNumber": "35",
            "streetName": "CONN",
            "streetType": "STREET",
            "locality": "FERNTREE GULLY",
            "subdivision": "VIC",
            "postalCode": "3156",
            "country": "AUS",
            "unstructuredLongForm": "U 1/35 CONN STREET, FERNTREE GULLY, VIC 3156"
          }
        ],
        "documents": {
          "IDENTITY": [
            {
              "type": "DRIVERS_LICENSE",
              "primaryIdentifier": "283229690",
              "secondaryIdentifier": "P5403241",
              "country": "AUS",
              "subdivision": "VIC"
            }
          ]
        },
        "consents": [
          {
            "type": "GENERAL"
          },
          {
            "type": "DOCS"
          }
        ]
      }
    }
    ```

    **Expected Result:** CLEAR (PASS)
  </Accordion>

  <Accordion title="FAIL Scenario - v2 Format">
    ```json theme={null}
    {
      "individual": {
        "name": {
          "givenName": "JENNY",
          "familyName": "TESTEIGHT_FAIL"
        },
        "dateOfBirth": {
          "year": "1957",
          "month": "01",
          "day": "01"
        },
        "addresses": [
          {
            "type": "RESIDENTIAL",
            "streetNumber": "56",
            "streetName": "VICTORIA",
            "streetType": "STREET",
            "locality": "FINGAL",
            "subdivision": "TAS",
            "postalCode": "7214",
            "country": "AUS",
            "unstructuredLongForm": "56 VICTORIA STREET, FINGAL, TAS 7214"
          }
        ],
        "documents": {
          "IDENTITY": [
            {
              "type": "DRIVERS_LICENSE",
              "primaryIdentifier": "T56543",
              "secondaryIdentifier": "T03989853",
              "country": "AUS",
              "subdivision": "TAS"
            }
          ]
        },
        "consents": [
          {
            "type": "GENERAL"
          }
        ]
      }
    }
    ```

    **Expected Result:** FAIL
  </Accordion>

  <Accordion title="Minor (Under 18) - v2 Format">
    ```json theme={null}
    {
      "individual": {
        "name": {
          "givenName": "Oliver",
          "middleName": "J",
          "familyName": "Youngten"
        },
        "dateOfBirth": {
          "year": "2015",
          "month": "06",
          "day": "15"
        },
        "addresses": [
          {
            "type": "RESIDENTIAL",
            "streetNumber": "35",
            "streetName": "Conn",
            "streetType": "Street",
            "locality": "Ferntree Gully",
            "subdivision": "VIC",
            "postalCode": "3156",
            "country": "AUS"
          }
        ],
        "consents": [
          {
            "type": "GENERAL"
          },
          {
            "type": "UNDER18"
          }
        ]
      }
    }
    ```
  </Accordion>

  <Accordion title="With Australian Passport - v2 Format">
    ```json theme={null}
    {
      "individual": {
        "name": {
          "givenName": "Sarah",
          "familyName": "Johnson"
        },
        "dateOfBirth": {
          "year": "1985",
          "month": "03",
          "day": "20"
        },
        "nationality": "AUS",
        "addresses": [
          {
            "type": "RESIDENTIAL",
            "locality": "Melbourne",
            "subdivision": "VIC",
            "postalCode": "3000",
            "country": "AUS"
          }
        ],
        "documents": {
          "IDENTITY": [
            {
              "type": "PASSPORT",
              "primaryIdentifier": "N1234567",
              "country": "AUS",
              "issueDate": {
                "year": "2020",
                "month": "01",
                "day": "15"
              },
              "expiryDate": {
                "year": "2030",
                "month": "01",
                "day": "14"
              }
            }
          ]
        },
        "consents": [
          {
            "type": "GENERAL"
          },
          {
            "type": "DOCS"
          }
        ]
      }
    }
    ```
  </Accordion>

  <Accordion title="PEP (Politically Exposed Person) - v2 Format">
    ```json theme={null}
    {
      "individual": {
        "name": {
          "givenName": "JAMES",
          "familyName": "TESTELEVEN"
        },
        "dateOfBirth": {
          "year": "1960",
          "month": "01",
          "day": "01"
        },
        "addresses": [
          {
            "type": "RESIDENTIAL",
            "streetNumber": "23",
            "streetName": "ISA",
            "streetType": "STREET",
            "locality": "FYSHWICK",
            "subdivision": "ACT",
            "postalCode": "2609",
            "country": "AUS"
          }
        ],
        "documents": {
          "IDENTITY": [
            {
              "type": "PASSPORT",
              "primaryIdentifier": "E55173628",
              "country": "AUS"
            }
          ]
        },
        "consents": [
          {
            "type": "GENERAL"
          }
        ]
      }
    }
    ```

    **Expected Result:** PEP match
  </Accordion>

  <Accordion title="SANCTION - v2 Format">
    ```json theme={null}
    {
      "individual": {
        "name": {
          "givenName": "BRUCE",
          "familyName": "TESTNINETEEN"
        },
        "dateOfBirth": {
          "year": "1968",
          "month": "01",
          "day": "01"
        },
        "addresses": [
          {
            "type": "RESIDENTIAL",
            "country": "AUS"
          }
        ],
        "consents": [
          {
            "type": "GENERAL"
          }
        ]
      }
    }
    ```

    **Expected Result:** SANCTION match
  </Accordion>

  <Accordion title="Combined PEP + SANCTION - v2 Format">
    ```json theme={null}
    {
      "individual": {
        "name": {
          "givenName": "STACY",
          "familyName": "TESTTWENTY"
        },
        "dateOfBirth": {
          "year": "1969",
          "month": "01",
          "day": "01"
        },
        "addresses": [
          {
            "type": "RESIDENTIAL",
            "country": "AUS"
          }
        ],
        "consents": [
          {
            "type": "GENERAL"
          }
        ]
      }
    }
    ```

    **Expected Result:** PEP, SANCTION (both flags)
  </Accordion>
</AccordionGroup>

<Note>
  **About Testbed Data:**

  These examples use FrankieOne's official testbed data with test names like TESTONE, TESTTWO, TESTELEVEN, etc. These are real test records in the UAT environment that produce predictable results.

  **Do not use fictional names** like "John Smith" or "Jane Doe" - use the actual testbed names provided above for consistent, reliable testing.
</Note>

<Note>
  **Important: Document Type Values in v2**

  Use **`DRIVERS_LICENSE`** (American spelling with underscore), not `DRIVERS_LICENCE`.

  **Common Document Types (subset — see API reference for complete list):**

  * `DRIVERS_LICENSE` ✅ (correct - American spelling)
  * `PASSPORT`
  * `NATIONAL_ID`
  * `VISA`
  * `IMMIGRATION`
  * `NATIONAL_HEALTH_ID`
  * `TAX_ID`
  * `BIRTH_CERT`
  * `CITIZENSHIP`
  * `MARRIAGE_CERT`
  * `UTILITY_BILL`
  * `BANK_STATEMENT`
  * `CONCESSION`
  * `PENSION`
  * `MILITARY_ID`
  * `OTHER`

  The full `Document-Type` enum in the OpenAPI specification includes additional types such as `HEALTH_CONCESSION`, `DEATH_CERT`, `NAME_CHANGE`, `BANK_ACCOUNT`, `INTENT_PROOF`, `ATTESTATION`, `SELF_IMAGE`, `DEVICE`, `VEHICLE_REGISTRATION`, `PROOF_OF_ADDRESS`, `HOUSE_REGISTRATION`, `WORK_PERMIT`, `EMPLOYMENT_CERTIFICATE`, and several business-related document types. Refer to the [v2 API reference](https://docs.frankieone.com) for the complete list.

  **Australian Driver's License Requirements:** For Australian driver's licenses, you must include both:

  * `primaryIdentifier` - License number (e.g., "283229690")
  * `secondaryIdentifier` - Document number / Card number (e.g., "P5403241")

  Example:

  ```json theme={null}
  {
    "type": "DRIVERS_LICENSE",
    "primaryIdentifier": "283229690",
    "secondaryIdentifier": "P5403241",
    "country": "AUS",
    "subdivision": "VIC"
  }
  ```

  **Common Mistakes:**

  * ❌ `DRIVERS_LICENCE` (British spelling)
  * ❌ `DRIVER_LICENSE` (missing S)
  * ❌ Abbreviations like `DL`
</Note>

<Note>
  **Important v2 Differences from v1:**

  * Dates use objects: `{year: "YYYY", month: "MM", day: "DD"}`
  * Address fields: `locality` (not suburb), `subdivision` (not state), `postalCode` (not postcode)
  * Documents nested by category: `documents.IDENTITY[]`
  * Document ID field: `primaryIdentifier` (not idNumber)
  * `schemaVersion` is a `readOnly` response field — it is **not required** in requests
  * Base URL uses `frankie.one` domain (not `frankiefinancial.io`)
  * No base path prefix — endpoints start directly with `/v2/`
</Note>

***

## Running Your First v2 API Call

### Overview: Create Individual Entity (v2)

This walkthrough demonstrates:

1. Creating an individual entity using v2 API
2. Understanding the v2 response
3. Saving the entity ID for subsequent requests

### Step 1: Select the Create Individual Request (v2)

<Tabs>
  <Tab title="Postman">
    1. Expand **"Individual Entities"** folder in left sidebar
    2. Click **"Create Entity with Aus Passport"**
    3. Request details appear on right
  </Tab>

  <Tab title="Bruno">
    1. Expand **"Individual Entities"** folder in left sidebar
    2. Click **"Create Entity with Aus Passport"**
    3. Request details appear in main panel
  </Tab>
</Tabs>

### Step 2: Review the v2 Request

**URL:**

```text theme={null}
POST https://api.{{frankie-environment}}.frankie.one/v2/individuals
```

**Headers:**

```text theme={null}
api_key: {{api_key}}
X-Frankie-CustomerID: {{X-Frankie-CustomerID}}
X-Frankie-CustomerChildID: {{X-Frankie-CustomerChildID}}
X-Frankie-Channel: {{X-Frankie-Channel}}
X-Frankie-Username: {{X-Frankie-Username}}
Content-Type: application/json
```

<Note>
  **Header Details:**

  * `api_key` (required): Your API authentication key
  * `X-Frankie-CustomerID` (required): Your main customer/account ID
  * `X-Frankie-CustomerChildID` (optional): Used for sub-account isolation when configured by FrankieOne
  * `X-Frankie-Channel` (optional): Identifies the channel the request originates from. Can be used in routing and risk calculations. Default values include `api`, `portal`, `smartui`, or any alphanumeric string.
  * `X-Frankie-Username` (optional): Username of the API caller
  * `Content-Type`: Always `application/json` for v2 API requests

  In the Postman collection, `X-Frankie-CustomerChildID`, `X-Frankie-Channel`, and `X-Frankie-Username` are present but **disabled by default**. Enable them as needed for your configuration.
</Note>

**Body (JSON) - v2 Format:**

```json theme={null}
{
  "individual": {
    "name": {
      "givenName": "JUDY",
      "middleName": "B",
      "familyName": "TESTTWO"
    },
    "dateOfBirth": {
      "year": "1951",
      "month": "01",
      "day": "01"
    },
    "addresses": [
      {
        "type": "RESIDENTIAL",
        "status": "CURRENT",
        "streetNumber": "17",
        "streetName": "HUME",
        "streetType": "STREET",
        "locality": "PARKES",
        "subdivision": "NSW",
        "postalCode": "2870",
        "country": "AUS",
        "unstructuredLongForm": "17 HUME STREET, PARKES, NSW 2870"
      }
    ],
    "emailAddresses": [
      {
        "type": "PERSONAL",
        "email": "judy.testtwo@example.com",
        "isPreferred": true
      }
    ],
    "phoneNumbers": [
      {
        "type": "MOBILE",
        "number": "+61412345678",
        "isPreferred": true
      }
    ],
    "consents": [
      {
        "type": "GENERAL"
      },
      {
        "type": "DOCS"
      }
    ]
  }
}
```

<Note>
  **Example uses FrankieOne testbed data:** JUDY TESTTWO is a real test record in UAT that produces CLEAR (PASS) results. Use actual testbed names for reliable testing.
</Note>

<Note>
  **v2 Key Features:**

  * Dates are objects, not strings
  * Addresses use `locality`, `subdivision`, `postalCode`
  * Email and phone are arrays with type and preference
  * All wrapped in `individual` object
  * `schemaVersion` is **not required** in requests (it is a `readOnly` response field per the OpenAPI spec)
</Note>

### Step 3: Send the Request

<Tabs>
  <Tab title="Postman">
    * Click the blue **"Send"** button (top right)
    * Wait for response (usually 1-3 seconds)
    * Response appears in bottom panel
  </Tab>

  <Tab title="Bruno">
    * Click **"Send"** or press `Cmd/Ctrl + Enter`
    * Wait for response (usually 1-3 seconds)
    * Response appears in right panel
  </Tab>
</Tabs>

### Step 4: Review the v2 Response

**Response Status:** `201 Created`

**`Response Body (illustrative — actual structure per OpenAPI individuals_entity_response schema):`**

```json theme={null}
{
  "requestId": "01HM5XJ7VASZ3EJMB1VQGTBFJ4",
  "individual": {
    "entityId": "abc123-def456-ghi789-jkl012",
    "schemaVersion": 2,
    "name": {
      "nameId": "name-uuid-here",
      "givenName": "JUDY",
      "middleName": "B",
      "familyName": "TESTTWO"
    },
    "dateOfBirth": {
      "dateOfBirthId": "dob-uuid-here",
      "year": "1951",
      "month": "01",
      "day": "01"
    },
    "addresses": [
      {
        "addressId": "addr-uuid-here",
        "type": "RESIDENTIAL",
        "status": "CURRENT",
        "streetNumber": "17",
        "streetName": "HUME",
        "streetType": "STREET",
        "locality": "PARKES",
        "subdivision": "NSW",
        "postalCode": "2870",
        "country": "AUS"
      }
    ],
    "emailAddresses": [
      {
        "emailAddressId": "email-uuid-here",
        "type": "PERSONAL",
        "email": "judy.testtwo@example.com",
        "isPreferred": true
      }
    ],
    "consents": [
      {
        "type": "GENERAL"
      },
      {
        "type": "DOCS"
      }
    ]
  },
  "serviceProfiles": [
    {
      "serviceName": "your-service-name"
    }
  ]
}
```

<Note>
  **Response structure note:** The response wraps the individual data inside an `individual` object and may include a `serviceProfiles` array and a top-level `requestId`. The exact fields returned depend on your configuration. The Postman collection's test scripts extract values like `jsonData.individual.entityId` and `jsonData.serviceProfiles[0].serviceName`, confirming this nested structure.
</Note>

**Key Information:**

| Field                                  | Description                                          |
| -------------------------------------- | ---------------------------------------------------- |
| `requestId`                            | Unique request identifier for tracing                |
| `individual.entityId`                  | Unique identifier for this individual—**save this!** |
| `individual.schemaVersion`             | Confirms v2 format (returned in response)            |
| `individual.name.nameId`               | Assigned ID for the name record                      |
| `individual.dateOfBirth.dateOfBirthId` | Assigned ID for the DOB record                       |
| `serviceProfiles[].serviceName`        | Service profile name (use in workflow execution)     |

### Step 5: Save the Entity ID

You'll need the `entityId` for subsequent requests (workflows, documents, verifications).

<Tabs>
  <Tab title="Postman">
    **Manual Method:**

    1. Copy `entityId` from response (at `individual.entityId`)
    2. Go to your environment (click environment dropdown > Edit)
    3. Update variable: `entityId` = `abc123-def456-ghi789-jkl012`
    4. Save environment

    **Automatic Method (Post-response Script):** The Postman collection includes pre-built test scripts that automatically save key variables. For example, the "Create Entity with Aus Passport" request includes:

    ```javascript theme={null}
    var jsonData = JSON.parse(responseBody);
    pm.environment.set("entityId", jsonData.individual.entityId);
    pm.environment.set("nameId", jsonData.individual.name.nameId);
    pm.environment.set("dateOfBirthId", jsonData.individual.dateOfBirth.dateOfBirthId);
    pm.environment.set("addressId", jsonData.individual.addresses[0].addressId);
    pm.environment.set("documentId", jsonData.individual.documents.IDENTITY[0].documentId);
    pm.environment.set("serviceName", jsonData.serviceProfiles[0].serviceName);
    ```
  </Tab>

  <Tab title="Bruno">
    **Manual Method:**

    1. Copy `entityId` from response (at `individual.entityId`)
    2. Click gear icon and select your environment
    3. Add/update: `entityId: abc123-def456-ghi789-jkl012`
    4. Save

    **Automatic Method (Post-response Script):** Add this to the request's post-response script section:

    ```javascript theme={null}
    const response = res.getBody();
    bru.setEnvVar("entityId", response.individual.entityId);
    ```
  </Tab>
</Tabs>

<Check>
  **Success!** You've created a v2 individual entity.
</Check>

***

## Executing a Workflow (v2)

### What Are Workflows?

Workflows in FrankieOne v2 are pre-configured verification processes that can include:

* KYC (Electronic verification)
* IDV (Document verification)
* AML (Screening)
* Risk assessment

Workflows are **configured by FrankieOne** based on your requirements. You execute them via API but cannot configure them via API.

### Step 6: Execute a Workflow

**Select the Request:**

1. Expand **"Individual Workflows"** folder
2. Click **"Execute Workflow"**

**URL:**

```text theme={null}
POST https://api.{{frankie-environment}}.frankie.one/v2/individuals/{{entityId}}/serviceprofiles/{{serviceName}}/workflows/{{workflowName}}/execute
```

**Required Variables:**

| Variable       | Example Value            | Description            |
| -------------- | ------------------------ | ---------------------- |
| `entityId`     | From previous step       | Individual's entity ID |
| `serviceName`  | (provided by FrankieOne) | Service profile name   |
| `workflowName` | (provided by FrankieOne) | Workflow name          |

**Body:**

```json theme={null}
{
  "comment": {
    "text": "Initial verification workflow"
  }
}
```

Or if updating individual data and executing workflow:

```json theme={null}
{
  "individual": {
    "documents": {
      "IDENTITY": [
        {
          "type": "DRIVERS_LICENSE",
          "primaryIdentifier": "283229690",
          "secondaryIdentifier": "P5403241",
          "country": "AUS",
          "subdivision": "VIC"
        }
      ]
    }
  },
  "comment": {
    "text": "Adding document and executing verification"
  }
}
```

**Send the Request** and review the response.

**Workflow Execute Response (illustrative — per OpenAPI spec):**

The response may return synchronously (`200`) or asynchronously (`202`):

```json theme={null}
{
  "requestId": "01HM5XJ7VASZ3EJMB1VQGTBFJ4",
  "workflowResult": {
    "workflowExecutionId": "wf-exec-12345"
  },
  "serviceProfile": {
    "serviceName": "your-service-name"
  },
  "individual": {
    "entityId": "abc123-def456-ghi789-jkl012"
  }
}
```

The Postman collection's test script extracts the execution ID automatically:

```javascript theme={null}
var jsonData = JSON.parse(responseBody);
postman.setEnvironmentVariable("executionId", jsonData.workflowResult.workflowExecutionId);
```

<Note>
  **Synchronous vs Asynchronous:** Workflow execution may return `200` (completed) or `202` (accepted for async processing). For async requests, use the `requestId` or `workflowExecutionId` to retrieve results via `GET /v2/individuals/{entityId}/results`. You can also set the `X-Frankie-Background` header to `1` to explicitly request asynchronous processing.
</Note>

### Create and Execute in One Call

The v2 API also supports creating an individual and executing a workflow in a single request:

**URL:**

```text theme={null}
POST https://api.{{frankie-environment}}.frankie.one/v2/individuals/new/serviceprofiles/{{serviceName}}/workflows/{{workflowName}}/execute
```

This endpoint accepts the full `individual` object in the request body and returns the combined response with `workflowResult`, `serviceProfile`, and `individual` data.

***

## Viewing Results in the Portal

### Why Use the Portal?

| Your API Client Shows    | Portal Shows                  |
| ------------------------ | ----------------------------- |
| API request and response | Visual representation         |
| Technical details        | Complete verification details |
| Raw data                 | Risk assessment with context  |
|                          | Timeline of events            |
|                          | Easy-to-understand format     |

**Use both together:** Send requests in Postman/Bruno, then view detailed results in the Portal.

### Accessing the Portal

Contact your FrankieOne representative for the correct portal URLs for your environments.

**Login:** Use credentials provided by FrankieOne (same account as API credentials).

### Finding Your Individual

**Method 1: Search by Name**

1. Click **"Entities"** in navigation
2. Enter customer name in search
3. Click on individual to view

**Method 2: Search by Entity ID**

1. Copy `entityId` from your API response
2. Paste into search bar
3. Click on individual

**Method 3: View Recent**

1. Click **"Entities"**
2. Sort by **"Most Recent"**
3. Your test individual should be at top

### Understanding the Portal View

| Section                 | What You'll See                                                |
| ----------------------- | -------------------------------------------------------------- |
| **Individual Overview** | Name, overall status, risk rating, created date                |
| **Verification Checks** | Workflow results, check statuses, timestamps                   |
| **Risk Assessment**     | Overall score, risk factors, contributing elements             |
| **Timeline**            | Chronological view of all events and status changes            |
| **Documents**           | Uploaded documents and verification results (if IDV performed) |

### Real-Time Updates

The Portal updates in real-time:

1. Send API request via Postman/Bruno
2. Refresh Portal (or wait for auto-refresh)
3. See new results immediately

***

## Common Testing Scenarios

### Scenario 1: Create Individual with Minimal Data

**Objective:** Test minimal required fields for v2 individual creation

**v2 Payload:**

```json theme={null}
{
  "individual": {
    "name": {
      "givenName": "PETER",
      "middleName": "C",
      "familyName": "TESTTHREE"
    },
    "dateOfBirth": {
      "year": "1952",
      "month": "01",
      "day": "01"
    },
    "addresses": [
      {
        "type": "RESIDENTIAL",
        "country": "AUS"
      }
    ],
    "consents": [
      {
        "type": "GENERAL"
      }
    ]
  }
}
```

**Expected Result:**

* Status: `201 Created`
* Returns `entityId` within the `individual` object
* Individual created successfully
* Testbed result: CLEAR (PASS)

***

### Scenario 2: Create Individual with Document

**Objective:** Create individual with identity document for verification

**v2 Payload:**

```json theme={null}
{
  "individual": {
    "name": {
      "givenName": "MARY",
      "familyName": "TESTFOUR"
    },
    "dateOfBirth": {
      "year": "1953",
      "month": "01",
      "day": "01"
    },
    "addresses": [
      {
        "type": "RESIDENTIAL",
        "streetNumber": "17",
        "streetName": "WATTLE",
        "streetType": "AVENUE",
        "locality": "WARWICK",
        "subdivision": "QLD",
        "postalCode": "4370",
        "country": "AUS"
      }
    ],
    "documents": {
      "IDENTITY": [
        {
          "type": "DRIVERS_LICENSE",
          "primaryIdentifier": "103188691",
          "secondaryIdentifier": "QUSQP650QB",
          "country": "AUS",
          "subdivision": "QLD"
        }
      ]
    },
    "consents": [
      {
        "type": "GENERAL"
      },
      {
        "type": "DOCS"
      }
    ]
  }
}
```

**Expected Result:**

* Individual created with document
* Ready for workflow execution
* Document details stored
* Testbed result: CLEAR (PASS)

***

### Scenario 3: Minor (Under 18)

**Objective:** Create individual under 18 years old

**v2 Payload:**

```json theme={null}
{
  "individual": {
    "name": {
      "givenName": "Oliver",
      "middleName": "J",
      "familyName": "Young"
    },
    "dateOfBirth": {
      "year": "2015",
      "month": "06",
      "day": "15"
    },
    "addresses": [
      {
        "type": "RESIDENTIAL",
        "streetNumber": "35",
        "streetName": "Conn",
        "streetType": "Street",
        "locality": "Ferntree Gully",
        "subdivision": "VIC",
        "postalCode": "3156",
        "country": "AUS"
      }
    ],
    "consents": [
      {
        "type": "GENERAL"
      },
      {
        "type": "UNDER18"
      }
    ]
  }
}
```

**Key Points:**

* Must include `UNDER18` consent
* Age calculated from `dateOfBirth`
* May require guardian information (check with FrankieOne)

***

### Scenario 4: Individual with Custom Attributes

**Objective:** Store custom business data with individual

**v2 Payload:**

```json theme={null}
{
  "individual": {
    "name": {
      "givenName": "Sarah",
      "familyName": "Johnson"
    },
    "dateOfBirth": {
      "year": "1992",
      "month": "03",
      "day": "10"
    },
    "addresses": [
      {
        "type": "RESIDENTIAL",
        "country": "AUS"
      }
    ],
    "customAttributes": {
      "customerSegment": {
        "type": "STRING",
        "value": "premium"
      },
      "accountType": {
        "type": "STRING",
        "value": "savings"
      },
      "vipStatus": {
        "type": "BOOLEAN",
        "value": "true"
      },
      "creditLimit": {
        "type": "INTEGER",
        "value": "50000"
      }
    },
    "consents": [
      {
        "type": "GENERAL"
      }
    ]
  }
}
```

**Use Cases:**

* Store business-specific data
* Track customer segments
* Store account types
* Custom workflow routing

***

### Scenario 5: International Individual (Non-Australian)

**Objective:** Create individual from another country

**v2 Payload:**

```json theme={null}
{
  "individual": {
    "name": {
      "givenName": "Emma",
      "familyName": "Williams"
    },
    "dateOfBirth": {
      "year": "1988",
      "month": "11",
      "day": "05"
    },
    "nationality": "GBR",
    "addresses": [
      {
        "type": "RESIDENTIAL",
        "locality": "London",
        "postalCode": "SW1A 1AA",
        "country": "GBR"
      }
    ],
    "documents": {
      "IDENTITY": [
        {
          "type": "PASSPORT",
          "country": "GBR",
          "primaryIdentifier": "123456789",
          "issueDate": {
            "year": "2020",
            "month": "01",
            "day": "15"
          },
          "expiryDate": {
            "year": "2030",
            "month": "01",
            "day": "14"
          }
        }
      ]
    },
    "consents": [
      {
        "type": "GENERAL"
      }
    ]
  }
}
```

**Key Points:**

* Use correct ISO 3166-1 alpha-3 country codes (GBR, USA, CAN, etc.)
* Include `nationality` field
* Document types vary by country

***

## Understanding API Responses

### HTTP Status Codes

| Code                        | Meaning                         | Action                                   |
| --------------------------- | ------------------------------- | ---------------------------------------- |
| `200 OK`                    | Success                         | Process response data                    |
| `201 Created`               | Resource created                | Save the new resource ID (entityId)      |
| `202 Accepted`              | Async request accepted          | Use requestId to poll for results        |
| `400 Bad Request`           | Invalid request                 | Check request format and required fields |
| `401 Unauthorized`          | Authentication failed           | Verify API key and Customer ID           |
| `404 Not Found`             | Resource not found              | Verify entity ID exists                  |
| `422 Unprocessable Entity`  | Validation error                | Check field formats and required fields  |
| `500 Internal Server Error` | Server issue                    | Retry or contact support                 |
| `502 Bad Gateway`           | Gateway error                   | Retry or contact support                 |
| `503 Service Unavailable`   | Service temporarily unavailable | Retry after a short delay                |

### Common v2 Response Fields

**Success Response (Create Individual) — per OpenAPI spec:**

```json theme={null}
{
  "requestId": "01HM5XJ7VASZ3EJMB1VQGTBFJ4",
  "individual": {
    "entityId": "abc123-def456-ghi789",
    "schemaVersion": 2,
    "name": {
      "nameId": "...",
      "givenName": "John",
      "familyName": "Smith"
    },
    "dateOfBirth": {
      "dateOfBirthId": "...",
      "year": "1990",
      "month": "01",
      "day": "15"
    },
    "addresses": [...],
    "consents": [...]
  },
  "serviceProfiles": [...]
}
```

**Error Response — per OpenAPI spec:**

```json theme={null}
{
  "errorCode": "API-0400",
  "errorMsg": "Multiple Errors: See Issues list",
  "details": [
    {
      "issue": "entityId in path must be of type uuid: \"test\"",
      "issueLocation": "VALIDATE-entityId"
    }
  ],
  "requestId": "01HM5XJ7VASZ3EJMB1VQGTBFJ4"
}
```

**Authentication Error — per OpenAPI spec:**

```json theme={null}
{
  "errorCode": "AUTH-0002",
  "errorMsg": "Unauthorized",
  "details": [
    {
      "issue": "Invalid Authentication provided. Access denied.",
      "issueLocation": "request"
    }
  ],
  "requestId": "00000000S6MNG7624K2TDXT1E3"
}
```

### Common Validation Errors in v2

| Error                         | Cause                                | Solution                                      |
| ----------------------------- | ------------------------------------ | --------------------------------------------- |
| `Invalid date format`         | Using string instead of object       | Use `{year, month, day}` format               |
| `Unknown field: suburb`       | Using v1 field names                 | Use v2 field names (`locality`, not `suburb`) |
| `documents must be an object` | Using array instead of nested object | Use `documents.IDENTITY: [...]` structure     |
| `Invalid field value`         | Incorrect data type or format        | Check OpenAPI spec for field requirements     |

***

## Best Practices

### 1. schemaVersion is Optional in Requests

`schemaVersion` is marked as `readOnly` in the OpenAPI specification. It is primarily a response field returned by the API. You **do not need** to include it in your request payloads.

```json theme={null}
{
  "individual": {
    "name": {...},
    "dateOfBirth": {...}
  }
}
```

### 2. Use Correct v2 Field Names

**v2 Uses:**

* `locality` (not `suburb`)
* `subdivision` (not `state`)
* `postalCode` (not `postcode`)
* `primaryIdentifier` (not `idNumber`)

### 3. Use Date Objects, Not Strings

**Correct v2 Format:**

```json theme={null}
{
  "dateOfBirth": {
    "year": "1990",
    "month": "01",
    "day": "15"
  }
}
```

**Incorrect (v1 format):**

```json theme={null}
{
  "dateOfBirth": "1990-01-15"
}
```

### 4. Structure Documents Correctly

**Correct v2 Format:**

```json theme={null}
{
  "documents": {
    "IDENTITY": [
      {
        "type": "PASSPORT",
        ...
      }
    ]
  }
}
```

**Incorrect:**

```json theme={null}
{
  "document": {
    "type": "PASSPORT",
    ...
  }
}
```

### 5. Use Environment Variables

**Why:**

* Easy to switch between UAT and Production
* Keep credentials secure
* Reuse across requests
* Save entityId automatically

### 6. Use Testbed Data Only

* **Never** use real customer data in testing
* Testbed data provides predictable results
* Safe and compliant
* Repeatable tests

### 7. Check Both API Response and Portal

Complete testing workflow:

1. Send request in Postman/Bruno
2. Check API response
3. View in Portal
4. Verify both match
5. Understand complete picture

### 8. Version Control (Bruno)

Since Bruno stores collections as files:

```bash theme={null}
cd "FrankieOne KYC V2 AUS"
git init
git add .
git commit -m "Initial FrankieOne v2 API collection"
```

<Warning>
  Add your environment files to `.gitignore` to avoid committing credentials:

  ```
  # .gitignore
  environments/*.bru
  ```
</Warning>

### 9. Test Edge Cases

Don't just test the happy path:

* Missing optional fields
* Invalid data formats
* Different countries
* Various document types
* Minors vs adults
* Multiple addresses

***

## Troubleshooting

### Authentication Error (401)

**Problem:** `Unauthorized` or `Invalid API key`

**Solutions:**

| Check             | Action                                                                                                              |
| ----------------- | ------------------------------------------------------------------------------------------------------------------- |
| API key           | Verify it's correct and not expired                                                                                 |
| Customer ID       | Confirm `X-Frankie-CustomerID` matches your account                                                                 |
| Customer Child ID | If you have sub-accounts, verify `X-Frankie-CustomerChildID` is correct                                             |
| Environment       | Ensure correct environment is selected and `frankie-environment` variable is set (e.g., `uat`)                      |
| Headers           | Verify `api_key` and `X-Frankie-CustomerID` headers are present and enabled                                         |
| Header names      | Use exact header names as specified: `api_key`, `X-Frankie-CustomerID`, `X-Frankie-CustomerChildID`                 |
| Base URL          | Ensure you're using `https://api.{{frankie-environment}}.frankie.one` (not the legacy `frankiefinancial.io` domain) |

<Note>
  **Common Authentication Issues with CustomerChildID:**

  * Using CustomerChildID when you don't have sub-accounts configured
  * Using wrong CustomerChildID value
  * Omitting CustomerChildID when you have sub-accounts
  * Typos in header name (must be exactly `X-Frankie-CustomerChildID`)
</Note>

***

### Date Format Error

**Problem:** `Invalid date format` or date validation errors

**Solutions:**

| Check         | Action                                                 |
| ------------- | ------------------------------------------------------ |
| Use objects   | Dates must be objects: `{year, month, day}`            |
| Not strings   | Don't use `"1990-01-15"` (that's v1 format)            |
| String values | Year, month, day are strings: `"1990"`, not `1990`     |
| Padding       | Month and day should be zero-padded: `"01"`, not `"1"` |

**Correct:**

```json theme={null}
{
  "dateOfBirth": {
    "year": "1990",
    "month": "01",
    "day": "15"
  }
}
```

***

### Field Name Error

**Problem:** `Unknown field` or field not recognized

**Solutions:**

| v1 Field (Wrong) | v2 Field (Correct)       |
| ---------------- | ------------------------ |
| `suburb`         | `locality`               |
| `state`          | `subdivision`            |
| `postcode`       | `postalCode`             |
| `document`       | `documents`              |
| `idNumber`       | `primaryIdentifier`      |
| `region`         | `subdivision`            |
| `emailAddress`   | `emailAddresses` (array) |
| `phoneNumber`    | `phoneNumbers` (array)   |

***

### Document Structure Error

**Problem:** `Invalid document structure` or validation errors

**Solutions:**

**Correct v2 Structure:**

```json theme={null}
{
  "documents": {
    "IDENTITY": [
      {
        "type": "DRIVERS_LICENSE",
        "primaryIdentifier": "12345678",
        "country": "AUS",
        "subdivision": "NSW"
      }
    ]
  }
}
```

**Common Mistakes:**

* Using `document` instead of `documents`
* Not nesting under category (`IDENTITY`)
* Using array instead of object for `documents`
* Using `idNumber` instead of `primaryIdentifier`

***

### Entity Not Found (404)

**Problem:** `Entity not found`

**Solutions:**

| Check           | Action                                                                   |
| --------------- | ------------------------------------------------------------------------ |
| Entity ID       | Verify it's correct (copy/paste carefully)                               |
| Environment     | Confirm you're using the same environment where entity was created       |
| Entity creation | Check that the create request succeeded                                  |
| URL format      | Ensure URL uses `/v2/individuals/{entityId}` with no extra path segments |

***

### No Results in Portal

**Problem:** Can't find individual in Portal

**Solutions:**

| Check       | Action                                                                       |
| ----------- | ---------------------------------------------------------------------------- |
| Environment | Verify you're logged into the correct Portal environment (UAT vs Production) |
| Customer ID | Confirm it matches your API credentials                                      |
| Search      | Try searching by entity ID instead of name                                   |
| Timing      | Wait a few seconds and refresh                                               |
| Filters     | Check if any filters are applied in Portal                                   |

***

### Bruno-Specific Issues

**Collection Not Loading:**

* Ensure the folder contains a valid `bruno.json` file
* Check file permissions on the collection folder
* Verify you're opening the correct folder

**Import Issues:**

* Bruno supports Postman Collection v2.1 format
* If import fails, try exporting from Postman as Collection v2.1
* Check for special characters in collection name

**Environment Variables Not Working:**

* Ensure environment is activated (check dropdown)
* Verify variable syntax: `{{variableName}}`
* Check for typos in variable names

***

### Getting Help

**FrankieOne Support:**

* Contact your FrankieOne representative
* Email: [help@frankieone.com](mailto:help@frankieone.com)
* Include: Entity ID, requestId, full request/response, error messages, screenshots

**Documentation:**

* v2 API Documentation: [https://docs.frankieone.com](https://docs.frankieone.com)
* OpenAPI Specification: Request from FrankieOne
* Testbed Data Guide: [https://docs.frankieone.com/docs/test-data](https://docs.frankieone.com/docs/test-data)

***

## Next Steps

### After Testing v2 APIs

1. **Understand the v2 APIs**
   * Review all v2 endpoints
   * Test various scenarios
   * Document requirements
2. **Plan Your Integration**
   * Determine which v2 APIs you need
   * Design workflow
   * Plan error handling
   * Consider migration from v1 if applicable
3. **Review Documentation**
   * v2 API reference
   * Integration guides
   * Security guidelines
   * Best practices
4. **Start Development**
   * Use your test collection as reference
   * Implement in your application
   * Follow v2 payload structure
   * Handle v2 responses correctly
5. **Move to Production**
   * Complete UAT testing
   * Get production credentials
   * Update `frankie-environment` variable (remove `uat` segment — production URL is `https://api.frankie.one`)
   * Deploy

***

## FAQs

### General

<AccordionGroup>
  <Accordion title="Should I use v1 or v2?">
    **Use v2** for all new integrations. v2 is the current recommended version with:

    * Better structure for complex scenarios
    * Active development and support
    * Clearer entity type separation
    * More explicit field names

    v1 is maintained for backward compatibility only.
  </Accordion>

  <Accordion title="Can I mix v1 and v2?">
    No. Choose one API version and use it consistently throughout your integration.
  </Accordion>

  <Accordion title="Do I need to pay for Postman or Bruno?">
    Bruno is completely free and open-source. Postman has a free tier that's sufficient for testing FrankieOne v2 APIs.
  </Accordion>

  <Accordion title="Can I use real customer data for testing?">
    **No.** Always use testbed data. Never use real customer data in testing environments.
  </Accordion>
</AccordionGroup>

### v2 Specific

<AccordionGroup>
  <Accordion title="What's different in v2 compared to v1?">
    Key differences:

    * **Base URL:** `https://api.{env}.frankie.one` (not `frankiefinancial.io`)
    * **Path:** Endpoints start at `/v2/` directly (no `compliance/v1.2` prefix)
    * **Date format:** Objects `{year, month, day}` instead of strings `"YYYY-MM-DD"`
    * **Field names:** `locality`, `subdivision`, `postalCode` (not `suburb`, `state`, `postcode`)
    * **Documents:** Nested by category `documents.IDENTITY[]`
    * **Entity type:** Implied by endpoint (`/individuals` vs `/organizations`)
    * **Schema version:** `readOnly` response field — not required in requests
    * **Email/Phone:** Arrays instead of single values
    * **Response structure:** Data nested under `individual` object with `requestId` at top level
  </Accordion>

  <Accordion title="Is schemaVersion required?">
    **No.** `schemaVersion` is marked as `readOnly` in the OpenAPI specification. It is a response field returned by the API and is **not required** in request payloads.
  </Accordion>

  <Accordion title="Why do dates use objects instead of strings?">
    v2's object format provides:

    * More explicit structure
    * Better validation
    * Clearer parsing
    * Support for partial dates
  </Accordion>

  <Accordion title="Can I include multiple documents?">
    Yes. v2 supports multiple documents per category:

    ```json theme={null}
    {
      "documents": {
        "IDENTITY": [
          {"type": "PASSPORT", ...},
          {"type": "DRIVERS_LICENSE", ...}
        ]
      }
    }
    ```
  </Accordion>

  <Accordion title="What are the valid consent types?">
    The OpenAPI specification defines the following consent types:

    * `GENERAL` — General consent for verification
    * `DOCS` — Consent for document verification
    * `CREDITHEADER` — Consent for credit header checks
    * `UNDER18` — Consent for minors under 18
    * `PAYROLL` — Consent for payroll verification
    * `INSURANCE` — Consent for insurance verification
    * `SUPERANNUATION` — Consent for superannuation verification
  </Accordion>
</AccordionGroup>

### Tool-Specific

<AccordionGroup>
  <Accordion title="Can I share my collection with my team?">
    * **Postman:** Export and share, or use Postman team workspaces
    * **Bruno:** Share via Git repository (add environment files to `.gitignore`)
  </Accordion>

  <Accordion title="Can I switch from Postman to Bruno?">
    Yes. Bruno can import Postman collections directly (v2.1 format).
  </Accordion>

  <Accordion title="Which tool is better for CI/CD?">
    Both support automation:

    * **Postman:** Newman CLI for running collections
    * **Bruno:** Bruno CLI (`bru run`) for running collections
  </Accordion>

  <Accordion title="How do I auto-save entityId?">
    The FrankieOne Postman collection includes pre-built test scripts that automatically save `entityId` and other variables after entity creation. If creating your own requests:

    **Postman:**

    ```javascript theme={null}
    var jsonData = JSON.parse(responseBody);
    pm.environment.set("entityId", jsonData.individual.entityId);
    ```

    **Bruno:**

    ```javascript theme={null}
    const response = res.getBody();
    bru.setEnvVar("entityId", response.individual.entityId);
    ```

    Note: The entity ID is accessed at `individual.entityId` (nested under the `individual` object), not at the top level.
  </Accordion>
</AccordionGroup>

### FrankieOne-Specific

<AccordionGroup>
  <Accordion title="What's the difference between UAT and Production?">
    * **UAT:** Testing environment (`https://api.uat.frankie.one`) with testbed data, safe for experimentation
    * **Production:** Live environment (`https://api.frankie.one`) with real customers, use only after thorough testing

    Always test in UAT first.
  </Accordion>

  <Accordion title="What is Customer Child ID and do I need it?">
    **Customer Child ID** (`X-Frankie-CustomerChildID`) is for sub-account isolation within your main account.

    **You need it if:**

    * You have multiple brands or business units
    * You're a reseller with multiple clients
    * FrankieOne has configured sub-accounts for you

    **You don't need it if:**

    * You have a single, unified account
    * FrankieOne hasn't mentioned sub-accounts to you

    **How to know:** Contact your FrankieOne representative to confirm if you have CustomerChildID configured.

    **If you have it:** Include the header in all requests:

    ```
    X-Frankie-CustomerChildID: {{X-Frankie-CustomerChildID}}
    ```

    **If you don't:** Omit the header or leave the variable blank. In the Postman collection, this header is disabled by default.
  </Accordion>

  <Accordion title="How long do test entities stay in UAT?">
    Check with FrankieOne for specific retention policies. Generally, test data may be periodically cleaned.
  </Accordion>

  <Accordion title="What workflows are available?">
    Workflows are **configured by FrankieOne** based on your requirements. Contact your representative to:

    * See available workflows
    * Understand what each workflow does
    * Request custom workflows

    You can also retrieve available workflows via `GET /v2/workflows` (with optional `serviceName` query parameter).
  </Accordion>

  <Accordion title="Can I configure workflows via API?">
    **No.** Workflows are configured by FrankieOne. You can only **execute** workflows and **retrieve** workflow information via API.
  </Accordion>

  <Accordion title="What additional headers are available?">
    Beyond the required `api_key` and `X-Frankie-CustomerID`, the v2 API supports these optional headers:

    * `X-Frankie-CustomerChildID` — Sub-account isolation
    * `X-Frankie-Channel` — Channel identifier (e.g., `api`, `portal`, `smartui`). Can be used in routing and risk calculations.
    * `X-Frankie-Username` — Username of the API caller
    * `X-Frankie-Background` — Set to `1` for asynchronous processing (returns `202` instead of waiting)
  </Accordion>
</AccordionGroup>

***

## Summary

### Key Takeaways

| Principle                       | Details                                                                                              |
| ------------------------------- | ---------------------------------------------------------------------------------------------------- |
| **Use v2 for new integrations** | Current recommended version with better structure                                                    |
| **Use correct v2 format**       | Objects for dates, correct field names                                                               |
| **Use correct base URL**        | `https://api.{env}.frankie.one/v2/...` (no legacy `frankiefinancial.io` or `compliance/v1.2` prefix) |
| **Choose your tool**            | Postman for cloud sync; Bruno for Git integration                                                    |
| **Use testbed data**            | Pre-configured scenarios with predictable results                                                    |
| **Check both views**            | API response + Portal for complete understanding                                                     |
| **Test thoroughly**             | Various scenarios including edge cases                                                               |

### v2 Quick Reference

**Minimal v2 Individual:**

```json theme={null}
{
  "individual": {
    "name": {
      "givenName": "John",
      "familyName": "Smith"
    },
    "dateOfBirth": {
      "year": "1990",
      "month": "01",
      "day": "15"
    },
    "addresses": [
      {
        "type": "RESIDENTIAL",
        "country": "AUS"
      }
    ],
    "consents": [
      {
        "type": "GENERAL"
      }
    ]
  }
}
```

### Getting Started Checklist

<Steps>
  <Step title="Install your tool">
    Install Postman or Bruno
  </Step>

  <Step title="Get the v2 collection">
    Download FrankieOne v2 API collection
  </Step>

  <Step title="Import">
    Import collection into your tool
  </Step>

  <Step title="Get credentials">
    Get API credentials from FrankieOne (UAT)
  </Step>

  <Step title="Configure environment">
    Set up environment variables (matching Postman environment)
  </Step>

  <Step title="Review v2 structure">
    Understand v2 payload format
  </Step>

  <Step title="First v2 API call">
    Create your first individual (v2)
  </Step>

  <Step title="Save entityId">
    Auto-save or manually save entity ID (from `individual.entityId`)
  </Step>

  <Step title="View in Portal">
    View results in Portal
  </Step>

  <Step title="Execute workflow">
    Test workflow execution
  </Step>

  <Step title="Test scenarios">
    Test different v2 scenarios
  </Step>

  <Step title="Document findings">
    Document your findings and questions
  </Step>

  <Step title="Plan integration">
    Plan your v2 API integration
  </Step>
</Steps>

***

## Additional Resources

### FrankieOne

| Resource             | URL                                                                                      |
| -------------------- | ---------------------------------------------------------------------------------------- |
| Website              | [https://frankieone.com](https://frankieone.com)                                         |
| v2 API Documentation | [https://docs.frankieone.com](https://docs.frankieone.com)                               |
| Testbed Data         | [https://docs.frankieone.com/docs/test-data](https://docs.frankieone.com/docs/test-data) |
| Support              | [help@frankieone.com](mailto:help@frankieone.com)                                        |

### Postman

| Resource        | URL                                                                    |
| --------------- | ---------------------------------------------------------------------- |
| Download        | [https://www.postman.com/downloads](https://www.postman.com/downloads) |
| Learning Center | [https://learning.postman.com](https://learning.postman.com)           |
| Documentation   | [https://learning.postman.com/docs](https://learning.postman.com/docs) |

### Bruno

| Resource      | URL                                                                      |
| ------------- | ------------------------------------------------------------------------ |
| Download      | [https://www.usebruno.com/downloads](https://www.usebruno.com/downloads) |
| Documentation | [https://docs.usebruno.com](https://docs.usebruno.com)                   |
| GitHub        | [https://github.com/usebruno/bruno](https://github.com/usebruno/bruno)   |

***

**Document Version:** 4.0 (v2 Corrected)\
**Last Updated:** February 2026\
**API Version:** v2\
**Audience:** Developers and technical teams evaluating or integrating FrankieOne v2 APIs
