# Dalmore API Documentation

**Base URL:**

{% tabs %}
{% tab title="DEV" %}
[https://platform.dalmoredev.com](https://platform.dalmoredev.com/)
{% endtab %}

{% tab title="PROD" %}
[https://platform.dalmoregroup.com](https://platform.dalmoregroup.com/)
{% endtab %}
{% endtabs %}

**Authentication:** All API requests require an `X-API-KEY` header with your API key.

#### Getting Started

* Create a developer account like as:

{% tabs %}
{% tab title="DEV" %}
[https://compliance.dalmoredev.com](https://compliance.dalmoredev.com/)
{% endtab %}

{% tab title="PROD" %}
[https://compliance.dalmoregroup.com](https://compliance.dalmoredev.com/)
{% endtab %}
{% endtabs %}

* Navigate to API Keys to generate your API key

#### API Resources

{% tabs %}
{% tab title="DEV" %}
[Swagger Documentation](https://platform.dalmoredev.com/clients)
{% endtab %}

{% tab title="PROD" %}
[Swagger Documentation](https://platform.dalmoregroup.com/clients)
{% endtab %}
{% endtabs %}

***

### Postman Collection

{% file src="/files/Uzxeb2OUINgQr9tLtO9R" %}

### Authentication

All API requests must include your API key in the request header:

```http
X-API-KEY: <your_api_key>
```

***

### 1. Creating an Offering

The offering creation workflow consists of three main steps: registering an issuer account, creating an issuer entity, and creating the offering with associated assets.

#### Step 1: Register Issuer Account

Creates a user account with authentication credentials for managing the issuer entity and offerings.

**Endpoint:** `POST /register/issuer`

**Request Body:**

```json
{
  "firstName": "Jessica",
  "lastName": "Bennett",
  "email": "jessica.bennett@example.com",
  "password": "Pass123!",
  "confirmPassword": "Pass123!",
  "accountName": "Jessica Bennett",
  "accountType": "DALMORE"
}
```

**Response:**

```json
{
  "accessToken": "eyJhbGciOiJIUzI1NixxxxxxIkpXVCJ9.eyJ1c2VyTGxxxxInVzZXJfbG9naW5f01abc2df456xxxx9i0jk",
  "userId": "user_login_01kfeg1234abcd5678xyz"
}
```

#### Step 2: Create Issuer Entity

Establishes a legal issuer entity representing the company or organization conducting the offering.

**Endpoint:** `POST /issuers`

**Request Body:**

```json
{
  "title": "Bennett Capital",
  "description": "Bennett Consulting Services",
  "legalName": "BennettCo LLC",
  "dba": "Bennett Consulting Services",
  "doi": "02/20/1990",
  "ein": "987654321",
  "type": "LLC",
  "address": "500 Park Avenue",
  "address2": "Suite 400",
  "city": "Austin",
  "country": "US",
  "state": "TX",
  "zip": "78701"
}
```

**Response:**

```json
{
  "id": "issuer_01kfegxw7yexsbpcye9kfas8y2",
  "__entity": "Issuer",
  "createdAt": "2026-01-08T12:57:26.527Z",
  "updatedAt": "2026-01-08T12:57:26.527Z",
  "deletedAt": null,
  "legalName": "BennettCo LLC",
  "dba": "Bennett Consulting Services",
  "title": "Bennett Capital",
  "description": "Bennett Consulting Services",
  "ein": "98-7654321",
  "type": "LLC",
  "address": "500 Park Avenue",
  "address2": "Suite 400",
  "city": "Austin",
  "state": "TX",
  "zip": "78701",
  "country": "US",
  "accountId": "account_01jg44hdyp2qfsw8pm0x8h19cz",
  "ss4LetterFileId": null,
  "status": "SUBMITTED",
  "coverArtId": null,
  "doi": "1990-02-20T00:00:00.000Z"
}
```

#### Step 3: Create Offering

Creates a new offering with regulatory type, funding goals, investment limits, and timeline. Automatically creates a primary asset.

**Endpoint:** `POST /offerings`

**Request Body:**

```json
{
  "issuerId": "issuer_01abcxyz123xxxxxx",
  "name": "Tech Growth IPO",
  "type": "REG_D",
  "targetAmount": 150000,
  "raiseAmount": 250000,
  "minInvestment": 1000,
  "maxInvestment": 25000,
  "contingencyAmount": 5000,
  "startAt": "11/15/2024",
  "endAt": "11/22/2026",
  "active": true,
  "cancellationPeriod": 5,
  "description": "This is a description of the Tech Growth offering.",
  "managedBy": "DALMORE",
  "assetName": "Tech Growth Stock",
  "assetType": "STOCK",
  "pricePerUnit": 1500,
  "totalUnits": 6000,
  "template": "STANDARD"
}
```

**Response:**

```json
{
  "issuerId": "issuer_01abcxyz123masked",
  "name": "Tech Growth IPO",
  "type": "REG_D",
  "targetAmount": 150000,
  "raiseAmount": 250000,
  "minInvestment": 1000,
  "maxInvestment": 25000,
  "contingencyAmount": 5000,
  "startAt": "2024-11-15T00:00:00.000Z",
  "endAt": "2026-11-22T00:00:00.000Z",
  "active": true,
  "cancellationPeriod": 5,
  "description": "This is a description of the Tech Growth offering.",
  "managedBy": "DALMORE",
  "accountId": "account_01abcxyz456masked",
  "id": "offering_01abcxyz789masked",
  "platform": "dalmore",
  "enabled": true,
  "complianceReview": "PENDING",
  "onboardingStatus": "IN_REVIEW",
  "showTotalRaised": true,
  "assets": [
    {
      "name": "Tech Growth Stock",
      "type": "STOCK",
      "pricePerUnit": 1500,
      "totalUnits": 6000,
      "totalAmount": 9000000,
      "offeringId": "offering_01abcxyz789masked",
      "accountId": "account_01abcxyz456masked",
      "template": "STANDARD",
      "id": "asset_01abcxyz012masked",
      "enableBonus": false
    }
  ]
}
```

#### Step 4: Create Additional Assets (Optional)

Creates additional assets for an existing offering to offer multiple types of securities.

**Endpoint:** `POST /assets`

**Request Body:**

```json
{
  "offeringId": "offering_xxxxxx",
  "name": "Tech Growth Asset",
  "type": "STOCK",
  "pricePerUnit": 1500,
  "totalUnits": 6000,
  "template": "STANDARD",
  "enableBonus": false
}
```

**Response:**

```json
{
  "name": "Tech Growth Asset",
  "type": "STOCK",
  "pricePerUnit": 1500,
  "totalUnits": 6000,
  "totalAmount": 9000000,
  "accountId": "account_xxxxxx",
  "offeringId": "offering_xxxxxx",
  "template": "STANDARD",
  "enableBonus": false,
  "id": "asset_xxxxxx",
  "yield": null,
  "duration": null,
  "durationType": null,
  "tiers": null,
  "createdAt": "2026-01-08T13:09:25.797Z",
  "updatedAt": "2026-01-08T13:09:25.797Z",
  "deletedAt": null,
  "__entity": "Asset"
}
```

#### API Calling Flow

```
1. Register Issuer Account
   POST /register/issuer
   └─> Returns: accessToken, userId

2. Create Issuer Entity
   POST /issuers
   └─> Returns: issuerId

3. Create Offering
   POST /offerings
   └─> Returns: offeringId, primary assetId

4. Create Additional Assets (Optional)
   POST /assets
   └─> Returns: additional assetId(s)
```

**Important Notes:**

* Each step depends on successful completion of the previous step
* The `issuerId` from Step 2 is required for Step 3
* The `offeringId` from Step 3 is required for Step 4
* Store returned IDs for subsequent API calls
* All offerings initially have status "PENDING" for compliance review

***

### 2. Creating an Investor Account

This section covers the complete process of creating and setting up investor accounts. The workflow varies by account type and includes compliance steps for Regulation D offerings.

#### Investor Account Types

The platform supports three investor account types:

* **INDIVIDUAL**: Single person investor account
* **JOINT**: Jointly held account (requires 2 individuals with shared ownership)
* **LEGAL\_ENTITY**: Business entity investor account (requires entity information and authorized signers)

#### Step 1: Register Investor User

Creates user authentication credentials for the investor.

**Endpoint:** `POST /auth/register/investor`

**Request Body:**

```json
{
  "firstName": "Michael",
  "lastName": "Harrington",
  "email": "michael.harrington.investor@example.com",
  "password": "Pass123!",
  "confirmPassword": "Pass123!",
  "phoneNumber": "+12025550123",
  "site": "investors.exampledev.com"
}
```

**Response:**

```json
{
  "userId": "user_01kfeq123abc9xfy48nm01qqwz"
}
```

**Key Fields:**

* `userId`: Unique identifier for the registered user (required for creating investor accounts)
* `site`: The investor portal domain where this user will access their account

#### Step 2: Create Investor Account

Creates the investor account structure and defines the account type.

**Endpoint:** `POST /investor-accounts`

**Request Body:**

```json
{
  "investorAccountType": "INDIVIDUAL",
  "email": "michael.harrington.individual@example.com",
  "name": "Michael Harrington Individual",
  "tid": "782451",
  "userId": "user_01kfeq123abc9xfy48nm01qqwz"
}
```

**Response:**

```json
{
  "investorAccountType": "INDIVIDUAL",
  "email": "michael.harrington.individual@example.com",
  "name": "Michael Harrington Individual",
  "tid": "782451",
  "userId": "user_01kfeq123abc9xfy48nm01qqwz",
  "accountId": "account_01jf90dhxt7py4wgkz93da11vm",
  "id": "investor_account_01kfeqj9qve8f1fn4tj03n87kd",
  "regAQualified": false,
  "regCfQualified": false,
  "regDQualified": false,
  "setupStatus": "IN_PROGRESS",
  "userDataType": "LIVE"
}
```

**Key Fields:**

* `id`: Unique investor account identifier (required for creating individuals/entities)
* `investorAccountType`: Determines the account structure
* `regAQualified`, `regCfQualified`, `regDQualified`: Qualification status for different regulations
* `setupStatus`: Current stage of account setup

**Next Steps by Account Type:**

* **INDIVIDUAL**: Proceed to Step 3 (Create Individual)
* **JOINT**: Proceed to Step 3, then create a second individual with `role: "JOINT"`
* **LEGAL\_ENTITY**: Proceed to Step 4 (Create Legal Entity)

#### Step 3: Create Individual

Creates a comprehensive individual profile with personal, financial, and compliance information.

**Endpoint:** `POST /individuals`

**Request Body:**

```json
{
  "lastName": "Jackson",
  "investorAccountId": "investor_account_01kfeqj9qve8f1fn4tj03n87kd",
  "firstName": "Michael",
  "dob": "1991-03-21T12:11:46.530Z",
  "isUsCitizenOrGreenCardHolder": true,
  "citizenship": "AD",
  "ssn": "111111111",
  "currencyCode": "USD",
  "email": "michael.primary@example.com",
  "role": "PRIMARY",
  "phone": "+12025550123",
  "ownership": 100,
  "setupStep": "NEW",
  "liquidNetWorth": 1000000,
  "currentAnnualIncome": 1000000,
  "sourceOfIncome": "EMPLOYED",
  "employerName": "Contoso Finance",
  "investedInCrowdfunding": 500000,
  "retirementAccountType": "SELF_DIRECTED",
  "custodianName": "Fidelity",
  "custodianAccountNumber": "ABC123456",
  "custodianRepresentativeName": "Sarah Johnson",
  "custodianEmail": "sarah.johnson@example.com",
  "tid": "782451",
  "address": "123 Broad Street",
  "address2": "Suite 200",
  "city": "Chicago",
  "country": "US",
  "state": "IL",
  "zip": "60601"
}
```

**Response:**

```json
{
  "id": "individual_01kfep71q0dfg9cr7db30m0swg",
  "investorAccountId": "investor_account_01kfeqj9qve8f1fn4tj03n87kd",
  "firstName": "Michael",
  "lastName": "Jackson",
  "role": "PRIMARY",
  "ownership": "100.00",
  "kycStatus": "PENDING",
  "amlStatus": "PENDING",
  "aicStatus": "PENDING",
  "setupStatus": "IN_PROGRESS",
  "accredited": false
}
```

**For Joint Accounts:**

Create a second individual with `role: "JOINT"` and appropriate `ownership` percentage (typically 50/50).

#### Step 4: Create Legal Entity (For Legal Entity Accounts Only)

Creates a legal entity profile with business information.

**Endpoint:** `POST /legal-entities`

**Request Body:**

```json
{
  "investorAccountId": "investor_account_01kfeyw45a9qb8f3s6cp4jz92b",
  "name": "Harrington Capital LLC",
  "ein": "987654321",
  "email": "legal.entity.harrington@example.com",
  "companyType": "LLC",
  "phone": "+12025559876",
  "dateOfIncorporation": "03/15/2023",
  "stateOfIncorporation": "DE",
  "address": "250 Market Street",
  "address2": "Floor 5",
  "city": "Denver",
  "country": "US",
  "state": "CO",
  "zip": "80202-1743"
}
```

**Response:**

```json
{
  "id": "legal_entity_01kfezzj29q8bcd0ne692v13km",
  "investorAccountId": "investor_account_01kfeyw45a9qb8f3s6cp4jz92b",
  "name": "Harrington Capital LLC",
  "ein": "987654321",
  "companyType": "LLC",
  "kybStatus": "PENDING",
  "sanctionsStatus": "PENDING",
  "setupStatus": "IN_PROGRESS"
}
```

**Key Fields:**

* `ein`: Employer Identification Number (tax ID)
* `companyType`: Legal structure (LLC, CORPORATION, PARTNERSHIP, TRUST, etc.)

***

### Regulation D (Reg D) Compliance Steps

For Regulation D offerings, additional steps are required to verify accredited investor status.

#### Step 5: Add AIC Questionnaire

Updates an individual's profile with an Accredited Investor Certification questionnaire.

**Endpoint:** `PATCH /individuals/{individualId}`

**Request Body:**

```json
{
  "aicQuestionnaire": "{\"AIC_Questionnaire\":{\"investment_objective\":\"Income- you seek investments with periodic distributions in exchange for capital appreciation\",\"investment_experience\":\"Less than 2 years\",\"risk_willingness\":\"Conservative\",\"equities_allocation\":\"Greater than $250,000 USD\",\"bonds_allocation\":\"Less than $250,000 USD\",\"real_estate_allocation\":\"Less than $250,000 USD\",\"other_investments_allocation\":\"Prefer not to answer\",\"overall_portfolio_percentage\":\"26% and over\",\"annual_living_expenses\":\"Prefer not to answer\",\"marginal_tax_rate\":\"Between 20%-30%\",\"significant_liquid_net_worth\":\"No\",\"risky_investment_understanding\":\"Yes\",\"investment_time_horizon\":\"Over 10 years\"}}"
}
```

**Questionnaire Fields:**

* `investment_objective`: Primary investment goal
* `investment_experience`: Years of investment experience
* `risk_willingness`: Risk tolerance level
* `equities_allocation`, `bonds_allocation`, etc.: Portfolio composition
* `overall_portfolio_percentage`: Percentage of portfolio in alternative investments
* `investment_time_horizon`: Expected investment duration

#### Step 6: Upload AIC Supporting Documents

Uploads documents to verify accredited investor status.

**Endpoint:** `POST /files?targetId={individual_id}&category=Investor+Accreditation&label={LABEL}&name={filename}&metadata={metadata_json}`

**Query Parameters:**

* `targetId`: Individual ID (e.g., `individual_xxxxxx`)
* `category`: Always `Investor Accreditation`
* `label`: Document type (e.g., `PROOF_OF_NET_WORTH`)
* `name`: Original filename
* `metadata`: JSON string with file-specific metadata

**Request Body:**

| Field  | Type          | Required | Description                  |
| ------ | ------------- | -------- | ---------------------------- |
| `file` | file (binary) | Yes      | PDF, image, or document file |

**Response:**

```json
{
  "id": "file_01kev4grfaenas38dsqdtpbqb7",
  "name": "Bank Statement _ $1M.pdf",
  "category": "Investor Accreditation",
  "label": "PROOF_OF_NET_WORTH",
  "targetId": "individual_01kerhsy0kfnss1p8x1h73actx",
  "complianceReview": "APPROVED",
  "status": "PENDING"
}
```

#### Step 7: Initialize/Get Individual AIC

Retrieves or initializes the AIC record for an individual.

**Endpoint:** `GET /individual/{individualId}/aic`

**Response:**

```json
{
  "id": "aic_01kev3f0x7f14vzk7ph9xxk5sd",
  "individualId": "individual_01kes966s7eecbbxakecpc18kx",
  "systemReview": "PENDING",
  "firstName": "Brooke",
  "lastName": "Cormier",
  "method": "PENDING",
  "complianceReview": "PENDING"
}
```

#### Step 8: Attach AIC Documentation

Attaches accreditation files and metadata to verify investor status.

**Endpoint:** `PUT /individual/{individualId}/aic`

**Request Body:**

```json
{
  "type": "NET_WORTH",
  "metadata": [
    {
      "fileId": "file_xxxxxx",
      "balance": 1075445,
      "accountType": "CHECKING",
      "institution": "Bank of America"
    },
    {
      "fileId": "file_xxxxxx",
      "balance": 1387580,
      "accountType": "SAVINGS",
      "institution": "Bank of America"
    }
  ]
}
```

**Accreditation Methods:**

* `NET_WORTH`: Bank statements, brokerage statements
* `INCOME`: Tax returns
* `PROFESSIONAL`: Professional certifications/licenses
* `EMPLOYEE`: Knowledgeable employee status

**Response:**

```json
{
  "id": "aic_xxxxxx",
  "individualId": "individual_xxxxxx",
  "method": "NET_WORTH",
  "complianceReview": "PENDING",
  "systemReview": "NEEDS_INFO",
  "netWorthData": [
    {
      "institution": "Bank of America",
      "accountType": "CHECKING",
      "balance": 1075445,
      "fileId": "file_xxxxxx"
    },
    {
      "institution": "Bank of America",
      "accountType": "SAVINGS",
      "balance": 1387580,
      "fileId": "file_xxxxxx"
    }
  ]
}
```

***

### API Calling Flows for Investor Accounts

#### Individual Investor Account Flow

```
1. Register Investor User
   POST /auth/register/investor
   └─> Returns: userId

2. Create Investor Account (type: INDIVIDUAL)
   POST /investor-accounts
   └─> Returns: investorAccountId

3. Create Individual
   POST /individuals
   └─> Returns: individualId

--- For Reg D Offerings Only ---

4. Add AIC Questionnaire
   PATCH /individuals/{individualId}

5. Upload AIC Supporting Documents
   POST /files
   └─> Returns: fileId(s)

6. Initialize/Get Individual AIC
   GET /individual/{individualId}/aic
   └─> Returns: aicId

7. Attach AIC Documentation
   PUT /individual/{individualId}/aic
```

#### Joint Investor Account Flow

```
1. Register Investor User
   POST /auth/register/investor
   └─> Returns: userId

2. Create Investor Account (type: JOINT)
   POST /investor-accounts
   └─> Returns: investorAccountId

3a. Create Primary Individual
    POST /individuals (role: PRIMARY, ownership: 50)
    └─> Returns: primaryIndividualId

3b. Create Joint Individual
    POST /individuals (role: JOINT, ownership: 50)
    └─> Returns: jointIndividualId

--- For Reg D Offerings Only ---

4. Add AIC Questionnaires
   PATCH /individuals/{primaryIndividualId}
   PATCH /individuals/{jointIndividualId}

5. Upload AIC Supporting Documents
   POST /files (for each individual)
   └─> Returns: fileId(s)

6. Initialize/Get AIC Records
   GET /individual/{primaryIndividualId}/aic
   GET /individual/{jointIndividualId}/aic
   └─> Returns: aicId(s)

7. Attach AIC Documentation
   PUT /individual/{primaryIndividualId}/aic
   PUT /individual/{jointIndividualId}/aic
```

#### Legal Entity Investor Account Flow

```
1. Register Investor User
   POST /auth/register/investor
   └─> Returns: userId

2. Create Investor Account (type: LEGAL_ENTITY)
   POST /investor-accounts
   └─> Returns: investorAccountId

3. Create Legal Entity
   POST /legal-entities
   └─> Returns: legalEntityId

4. Create Authorized Signers
   POST /individuals (role: AUTHORIZED_SIGNER)
   └─> Returns: individualId(s)

--- For Reg D Offerings Only (if applicable) ---

5. Add AIC Questionnaires for Authorized Signers
   PATCH /individuals/{individualId}

6. Upload AIC Supporting Documents
   POST /files
   └─> Returns: fileId(s)

7. Initialize/Get Individual AIC
   GET /individual/{individualId}/aic

8. Attach AIC Documentation
   PUT /individual/{individualId}/aic
```

***

### 3. Attaching KYC Documentation

After creating an investor account, you need to complete the Know Your Customer (KYC) verification process by uploading identity documents. This section covers the complete KYC document submission workflow.

#### KYC Document Types

The platform supports three types of identity documents:

* **PASSPORT**: International passport
* **DRIVER\_LICENSE**: State-issued driver's license
* **STATE\_ID**: State-issued identification card

#### Step 1: Get Investor Accounts

Retrieve the list of investor accounts to select the individual for KYC verification.

**Endpoint:** `GET /investor-accounts`

**Response:**

json

```json
{
  "data": [
    {
      "id": "investor_account_01kfn7ntvge7mav9vrk356zmgh",
      "investorAccountType": "LEGAL_ENTITY",
      "name": "Dorian Nicolas",
      "individuals": [
        {
          "id": "individual_01kfn7nv95e76sbv8v1ndepswx",
          "firstName": "Dorian",
          "lastName": "Nicolas",
          "role": "PRIMARY",
          "kycStatus": "PENDING"
        }
      ]
    }
  ],
  "meta": {
    "itemCount": 10,
    "totalItems": 1140,
    "currentPage": 1,
    "totalPages": 114
  }
}
```

#### Step 2: Upload KYC Document Files

Upload the required identity documents. The document front image is mandatory, while the selfie is optional.

**Endpoint:** `POST /files?name={filename}&category=kyc-document&label={LABEL}&targetId={individual_id}`

**Query Parameters:**

* `name`: Original filename (e.g., `Passport_01.png`)
* `category`: Always `kyc-document`
* `label`: Document type label
  * For document front: `KYC_DOCUMENT_FRONT`
  * For document back (driver's license/state ID): `KYC_DOCUMENT_BACK`
  * For selfie: `KYC_SELFIE`
* `targetId`: Individual ID (e.g., `individual_xxxxxx`)

**Request Body:**

| Field  | Type          | Required | Description                      |
| ------ | ------------- | -------- | -------------------------------- |
| `file` | file (binary) | Yes      | Image file (PNG, JPG, JPEG, PDF) |

**Example: Upload Document Front (Mandatory)**

**Request:**

```
POST /files?name=Passport_01.png&category=kyc-document&label=KYC_DOCUMENT_FRONT&targetId=individual_01kfn7nv95e76sbv8v1ndepswx
Content-Type: multipart/form-data

[Binary file data]
```

**Response:**

json

```json
{
  "id": "file_01kfnbs35nfqbrf4hp0g4qxrka",
  "name": "Passport_01.png",
  "category": "kyc-document",
  "label": "KYC_DOCUMENT_FRONT",
  "targetId": "individual_01kfn7nv95e76sbv8v1ndepswx",
  "targetTable": "INDIVIDUALS",
  "fileType": "image/png",
  "url": "https://dalmoredatafactory.blob.core.windows.net/...",
  "status": "PENDING",
  "createdAt": "2026-01-23T12:03:05.000Z"
}
```

**Example: Upload Selfie (Optional)**

**Request:**

```
POST /files?name=Selfie_01.jpeg&category=kyc-document&label=KYC_SELFIE&targetId=individual_01kfn7nv95e76sbv8v1ndepswx
Content-Type: multipart/form-data

[Binary file data]
```

**Response:**

json

```json
{
  "id": "file_01kfnbs5n5fqbrf4kaedm6mfsf",
  "name": "Selfie_01.jpeg",
  "category": "kyc-document",
  "label": "KYC_SELFIE",
  "targetId": "individual_01kfn7nv95e76sbv8v1ndepswx",
  "targetTable": "INDIVIDUALS",
  "fileType": "image/jpeg",
  "url": "https://dalmoredatafactory.blob.core.windows.net/...",
  "status": "PENDING",
  "createdAt": "2026-01-23T12:03:07.000Z"
}
```

#### Step 3: Submit KYC Record

After uploading the required documents, submit the KYC verification record with document details and file references.

**Endpoint:** `POST /kyc`

**Request Body:**

**For Passport:**

json

```json
{
  "individualId": "individual_01kfn7nv95e76sbv8v1ndepswx",
  "kycFirstName": "Maria",
  "kycLastName": "Cole",
  "kycDocumentType": "PASSPORT",
  "kycDocumentId": "PNXPTSCN",
  "kycDocumentIssuer": "BR",
  "kycDocumentIssuedDate": "01/07/2018",
  "kycDocumentExpirationDate": "04/26/2034",
  "kycDocumentDob": "07/11/1997",
  "kycProvider": "WITH_PERSONA",
  "kycDocumentFrontFileId": "file_01kfnbs35nfqbrf4hp0g4qxrka",
  "kycSelfieFileId": "file_01kfnbs5n5fqbrf4kaedm6mfsf",
  "kycLog": "{\"data\":{\"type\":\"event\",\"id\":\"evt_YXLEAqCyJnnTXWvjUXCuCtHh\",\"attributes\":{\"name\":\"inquiry.approved\",\"payload\":{\"data\":{\"type\":\"inquiry\",\"id\":\"inq_qe17v49Ltn1tUs7zkv1F0bub\",\"attributes\":{\"status\":\"approved\",\"reference-id\":\"individual_01kfn7nv95e76sbv8v1ndepswx\",\"created-at\":\"2026-01-22T12:02:57.576Z\",\"completed-at\":\"2026-01-23T12:02:57.576Z\"}}}}}}"
}
```

**For Driver's License:**

json

```json
{
  "individualId": "individual_01kfn7nv95e76sbv8v1ndepswx",
  "kycFirstName": "John",
  "kycLastName": "Smith",
  "kycDocumentType": "DRIVER_LICENSE",
  "kycDocumentId": "D1234567",
  "kycDocumentIssuer": "CA",
  "kycDocumentIssuedDate": "03/15/2020",
  "kycDocumentExpirationDate": "03/15/2028",
  "kycDocumentDob": "05/20/1985",
  "kycProvider": "WITH_PERSONA",
  "kycDocumentFrontFileId": "file_xxxxxx",
  "kycDocumentBackFileId": "file_xxxxxx",
  "kycSelfieFileId": "file_xxxxxx"
}
```

**For State ID:**

json

```json
{
  "individualId": "individual_01kfn7nv95e76sbv8v1ndepswx",
  "kycFirstName": "Jane",
  "kycLastName": "Doe",
  "kycDocumentType": "STATE_ID",
  "kycDocumentId": "S9876543",
  "kycDocumentIssuer": "NY",
  "kycDocumentIssuedDate": "06/10/2021",
  "kycDocumentExpirationDate": "06/10/2029",
  "kycDocumentDob": "08/15/1990",
  "kycProvider": "WITH_PERSONA",
  "kycDocumentFrontFileId": "file_xxxxxx",
  "kycDocumentBackFileId": "file_xxxxxx",
  "kycSelfieFileId": "file_xxxxxx"
}
```

**Key Fields:**

* `individualId`: The individual ID for KYC verification
* `kycDocumentType`: Type of document (PASSPORT, DRIVER\_LICENSE, STATE\_ID)
* `kycDocumentId`: Document number/ID
* `kycDocumentIssuer`: Issuing country (for passport) or state (for driver's license/state ID)
* `kycProvider`: KYC verification provider (default: `WITH_PERSONA`)
* `kycDocumentFrontFileId`: Mandatory - File ID of document front image
* `kycDocumentBackFileId`: Required for DRIVER\_LICENSE and STATE\_ID - File ID of document back image
* `kycSelfieFileId`: Optional - File ID of selfie image

**Response:**

json

```json
{
  "id": "kyc_01kfnbs62qfkmtdttyn6tfp6ea",
  "individualId": "individual_01kfn7nv95e76sbv8v1ndepswx",
  "kycStatus": "PENDING",
  "platform": "WITH_PERSONA",
  "documentType": "PASSPORT",
  "documentImage": "file_01kfnbs35nfqbrf4hp0g4qxrka",
  "tid": null,
  "response": "{\"data\":{\"type\":\"event\",\"id\":\"evt_YXLEAqCyJnnTXWvjUXCuCtHh\",\"attributes\":{\"name\":\"inquiry.approved\",\"payload\":{\"data\":{\"type\":\"inquiry\",\"id\":\"inq_qe17v49Ltn1tUs7zkv1F0bub\",\"attributes\":{\"status\":\"approved\",\"reference-id\":\"individual_01kfn7nv95e76sbv8v1ndepswx\",\"created-at\":\"2026-01-22T12:02:57.576Z\",\"completed-at\":\"2026-01-23T12:02:57.576Z\"}}}}}}",
  "reason": null,
  "lastEventAt": null,
  "createdAt": "2026-01-23T12:03:06.962Z",
  "updatedAt": "2026-01-23T12:03:06.962Z"
}
```

***

### KYC Attachment Flow

#### Complete KYC Workflow

```
1. Get Investor Accounts
   GET /investor-accounts
   └─> Returns: List of investor accounts with individuals

2. Upload Document Front Image (Mandatory)
   POST /files?name={filename}&category=kyc-document&label=KYC_DOCUMENT_FRONT&targetId={individualId}
   └─> Returns: kycDocumentFrontFileId

3. Upload Document Back Image (Required for DRIVER_LICENSE & STATE_ID)
   POST /files?name={filename}&category=kyc-document&label=KYC_DOCUMENT_BACK&targetId={individualId}
   └─> Returns: kycDocumentBackFileId

4. Upload Selfie Image (Optional)
   POST /files?name={filename}&category=kyc-document&label=KYC_SELFIE&targetId={individualId}
   └─> Returns: kycSelfieFileId

5. Submit KYC Record
   POST /kyc
   └─> Returns: KYC record with verification status
```

#### Document Requirements by Type

| Document Type   | Front Image | Back Image   | Selfie   | Issuer Format               |
| --------------- | ----------- | ------------ | -------- | --------------------------- |
| PASSPORT        | Mandatory   | Not Required | Optional | Country Code (e.g., BR, US) |
| DRIVER\_LICENSE | Mandatory   | Required     | Optional | State Code (e.g., CA, NY)   |
| STATE\_ID       | Mandatory   | Required     | Optional | State Code (e.g., TX, FL)   |

#### Important Notes

* **File Upload Order**: Always upload files before submitting the KYC record
* **File Categories**: Use `kyc-document` category for all KYC-related files
* **Document Front**: Mandatory for all document types
* **Document Back**: Required only for DRIVER\_LICENSE and STATE\_ID
* **Selfie**: Optional for all document types
* **Supported Formats**: PNG, JPG, JPEG, PDF
* **Provider**: Default KYC provider is `WITH_PERSONA`
* **Status Flow**: KYC records start with `PENDING` status and are processed by the verification provider

***

## 4. How to Place a Trade

### Overview

The place trade workflow consists of multiple sequential steps to create and finalize an investment trade. This process involves selecting accounts, choosing offerings and assets, managing cart items, configuring payment methods, and checking out.

***

### Step 1: Get User's Investor Accounts

**Description:**

Retrieves all investor accounts associated with a user to select which account will be used for the trade.

**Example Request:**

```http
GET /clients/api/v1/investor-accounts
```

**Response:**

```json
{
    "items": [
        {
            "createdAt": "2026-01-22T12:39:37.883Z",
            "updatedAt": "2026-01-22T13:00:00.128Z",
            "deletedAt": null,
            "id": "investor_account_01kfjvfamwe2yrkhypyzb2n0v0",
            "tid": "1769085577876",
            "investorAccountType": "LEGAL_ENTITY",
            "userId": "user_01kfjvfakzep3r0dpav23xfwg1",
            "email": "Tad.McKenzie50@hotmail.com",
            "name": "Buford Marks",
            "regAQualified": true,
            "regCfQualified": true,
            "regDQualified": true,
            "accountId": "account_01k8n2b26bfzwv7nnyayk8e5t3",
            "setupStatus": "IN_PROGRESS",
            "systemReviewLog": null,
            "userDataType": "LIVE",
            "__entity": "InvestorAccount"
        }
    ],
    "meta": {
        "itemCount": 1,
        "totalItems": 1,
        "itemsPerPage": 10,
        "totalPages": 1,
        "currentPage": 1
    }
}
```

***

### Step 2: Browse Available Offerings

**Description:**

Retrieves a paginated list of available offerings for investment.

**Example Request:**

```http
GET /clients/api/v1/offerings
```

**Response:**

```json
{
    "items": [
        {
            "createdAt": "2026-01-22T12:42:30.989Z",
            "updatedAt": "2026-01-22T12:42:30.989Z",
            "deletedAt": null,
            "id": "offering_01kfjvmkpperebzey73vsc5pnr",
            "name": "Upgradable encompassing open system",
            "description": "Tristis creptio omnis. Spectaculum damnatio averto canonicus strenuus recusandae consectetur administratio. Alii doloremque calculus ultio valde.",
            "tid": null,
            "type": "REG_D",
            "raiseAmount": 171262,
            "minInvestment": 3871,
            "maxInvestment": 17530,
            "contingencyAmount": 6707,
            "targetAmount": 131073,
            "serviceChargesType": null,
            "startAt": "2026-02-13T19:00:00.000Z",
            "endAt": "2026-04-01T19:00:00.000Z",
            "platform": "dalmore",
            "platformSettings": null,
            "enabled": true,
            "accountId": "account_01k8n2b26bfzwv7nnyayk8e5t3",
            "issuerId": "issuer_01kdsw8zwwenfv86g65y9qv8rh",
            "cancellationPeriod": 3,
            "complianceReview": "PENDING",
            "coverArtId": null,
            "memorandumId": null,
            "subscriptionAgreementId": null,
            "managedBy": "DALMORE",
            "subscriptionAgreementTemplateId": null,
            "jointSubscriptionAgreementTemplateId": null,
            "entitySubscriptionAgreementTemplateId": null,
            "signerSenderIdentityId": null,
            "signerBrandId": null,
            "valuationCap": null,
            "publishedVersionId": null,
            "draftVersionId": "offering_revision_01kfjvmkq1ec4tymg942e599vw",
            "onboardingStatus": "IN_REVIEW",
            "onboardingReviewedById": null,
            "onboardingReviewedAt": null,
            "showTotalRaised": true,
            "__entity": "Offering"
        }
    ],
    "meta": {
        "totalItems": 1,
        "itemCount": 1,
        "itemsPerPage": 10,
        "totalPages": 1,
        "currentPage": 1
    }
}
```

***

### Step 3: Get Offering Details with Assets

**Description:**

Retrieves detailed information about a specific offering, including all available assets for purchase.

**Query Parameters:**

* `include` - Related entities to include (use `assets` to get asset details)

**Example Request:**

```http
GET /clients/api/v1/offerings/offering_01kfjvmkpperebzey73vsc5pnr?include=assets
```

**Response:**

```json
{
    "createdAt": "2026-01-22T12:42:30.989Z",
    "updatedAt": "2026-01-22T12:42:30.989Z",
    "deletedAt": null,
    "id": "offering_01kfjvmkpperebzey73vsc5pnr",
    "name": "Upgradable encompassing open system",
    "description": "Tristis creptio omnis. Spectaculum damnatio averto canonicus strenuus recusandae consectetur administratio. Alii doloremque calculus ultio valde.",
    "tid": null,
    "type": "REG_D",
    "raiseAmount": 171262,
    "minInvestment": 3871,
    "maxInvestment": 17530,
    "contingencyAmount": 6707,
    "targetAmount": 131073,
    "serviceChargesType": null,
    "startAt": "2026-02-13T19:00:00.000Z",
    "endAt": "2026-04-01T19:00:00.000Z",
    "platform": "dalmore",
    "platformSettings": null,
    "enabled": true,
    "accountId": "account_01k8n2b26bfzwv7nnyayk8e5t3",
    "issuerId": "issuer_01kdsw8zwwenfv86g65y9qv8rh",
    "cancellationPeriod": 3,
    "complianceReview": "PENDING",
    "coverArtId": null,
    "memorandumId": null,
    "subscriptionAgreementId": null,
    "managedBy": "DALMORE",
    "subscriptionAgreementTemplateId": null,
    "jointSubscriptionAgreementTemplateId": null,
    "entitySubscriptionAgreementTemplateId": null,
    "signerSenderIdentityId": null,
    "signerBrandId": null,
    "valuationCap": null,
    "publishedVersionId": null,
    "draftVersionId": "offering_revision_01kfjvmkq1ec4tymg942e599vw",
    "onboardingStatus": "IN_REVIEW",
    "onboardingReviewedById": null,
    "onboardingReviewedAt": null,
    "showTotalRaised": true,
    "assets": [
        {
            "createdAt": "2026-01-22T12:42:30.989Z",
            "updatedAt": "2026-01-22T12:42:30.989Z",
            "deletedAt": null,
            "id": "asset_01kfjvmkq6f4ca2y4bdvd8016c",
            "name": "Luxurious Rubber Tuna",
            "type": "STOCK",
            "pricePerUnit": 54.87,
            "totalUnits": 1335,
            "totalAmount": 73251.45,
            "yield": null,
            "duration": null,
            "durationType": null,
            "accountId": "account_01k8n2b26bfzwv7nnyayk8e5t3",
            "offeringId": "offering_01kfjvmkpperebzey73vsc5pnr",
            "template": "STANDARD",
            "tiers": null,
            "enableBonus": false,
            "__entity": "Asset"
        },
        {
            "createdAt": "2026-01-22T12:42:31.033Z",
            "updatedAt": "2026-01-22T12:42:31.033Z",
            "deletedAt": null,
            "id": "asset_01kfjvmkqse8gtc5tstx6r6kdk",
            "name": "Practical Concrete Sausages",
            "type": "STOCK",
            "pricePerUnit": 77.9,
            "totalUnits": 3068,
            "totalAmount": 238997.2,
            "yield": null,
            "duration": null,
            "durationType": null,
            "accountId": "account_01k8n2b26bfzwv7nnyayk8e5t3",
            "offeringId": "offering_01kfjvmkpperebzey73vsc5pnr",
            "template": "STANDARD",
            "tiers": null,
            "enableBonus": false,
            "__entity": "Asset"
        }
    ],
    "__entity": "Offering"
}
```

***

### Step 4: Retrieve or Create Cart

**Description:**

Retrieves the current cart for a user. If no cart exists, a new one is automatically created.

**Query Parameters:**

* `userId` - `user_xxxxxx`

**Example Request:**

```http
GET /clients/api/v1/carts?userId=user_01kfjvfakzep3r0dpav23xfwg1
```

**Response:**

```json
{
  "isUncleared24h": false,
  "createdAt": "2026-01-08T12:04:36.764Z",
  "updatedAt": "2026-01-08T12:04:36.764Z",
  "id": "trade_01kg1mbm8we5vvkmb5rrrfearv",
  "userId": "user_01kfjvfakzep3r0dpav23xfwg1",
  "tradeStatus": "CART",
  "totalAmount": null,
  "numberOfShares": 0,
  "issuer": [{
      "id": "issuer_01kdsw8zwwenfv86g65y9qv8rh"
  }],
  "offering": [{
      "id": "offering_01kfjvmkpperebzey73vsc5pnr"
  }],
  "lineItems": [{
      "id": "trade_line_item_01kg1mbm9mentbev7ech4dqd14"
  }],
  "paymentMethod": {
      "id": "payment_method_01kfjvfam1e8gtc4dbfymbq30m"
  },
  "__entity": "Trade"
}
```

***

### Step 5a: Add Asset to Cart (Create Trade Line Item)

**Description:**

Adds an asset to the cart by creating a new trade line item. If no cart exists for the user, one will be created automatically.

**Query Parameters:**

* `userId` - `user_xxxxxx`

**Request Body:**

```json
{
    "assetId": "asset_01kfjvmkq6f4ca2y4bdvd8016c",
    "quantity": 200
}
```

**Example Request:**

```http
POST /clients/api/v1/trade-line-items?userId=user_01kfjvfakzep3r0dpav23xfwg1
```

**Response:**

```json
{
    "createdAt": "2026-01-28T06:23:53.129Z",
    "updatedAt": "2026-01-28T06:25:20.504Z",
    "deletedAt": null,
    "id": "trade_line_item_01kg1mbm9mentbev7ech4dqd14",
    "quantity": 200,
    "bonusShares": 0,
    "totalNumberOfShares": 200,
    "pricePerShare": 54.87,
    "total": 10974,
    "assetId": "asset_01kfjvmkq6f4ca2y4bdvd8016c",
    "assetName": "Luxurious Rubber Tuna",
    "assetType": "STOCK",
    "tradeId": "trade_01kg1mbm8we5vvkmb5rrrfearv",
    "tid": null,
    "signaturePlatform": null,
    "signatureDocumentId": null,
    "signatureUrl": null,
    "signatureStatus": "SIGNED",
    "jointSignatureStatus": "PENDING",
    "subdocFileId": "file_01kg1mbsvxf20a2xda68fvmanc",
    "lineItemRegulation": "REG_D",
    "lineItemCoverArtId": null,
    "__entity": "TradeLineItem"
}
```

***

### Step 5b: Update Existing Trade Line Item

**Description:**

Updates the quantity of an existing trade line item in the cart.

**Request Body:**

```json
{
    "quantity": 100
}
```

**Example Request:**

```http
PATCH /clients/api/v1/trade-line-items/trade_line_item_01kg1mbm9mentbev7ech4dqd14
```

**Response:**

```json
{
    "createdAt": "2026-01-28T06:23:53.129Z",
    "updatedAt": "2026-01-28T09:05:35.613Z",
    "deletedAt": null,
    "id": "trade_line_item_01kg1mbm9mentbev7ech4dqd14",
    "quantity": 200,
    "bonusShares": 0,
    "totalNumberOfShares": 200,
    "pricePerShare": 54.87,
    "total": 10974,
    "assetId": "asset_01kfjvmkq6f4ca2y4bdvd8016c",
    "assetName": "Luxurious Rubber Tuna",
    "assetType": "STOCK",
    "tradeId": "trade_01kg1mbm8we5vvkmb5rrrfearv",
    "tid": null,
    "signaturePlatform": null,
    "signatureDocumentId": null,
    "signatureUrl": null,
    "signatureStatus": "PENDING",
    "jointSignatureStatus": "PENDING",
    "subdocFileId": null,
    "lineItemRegulation": "REG_D",
    "lineItemCoverArtId": null,
    "asset": {
        "createdAt": "2026-01-22T12:42:30.989Z",
        "updatedAt": "2026-01-22T12:42:30.989Z",
        "deletedAt": null,
        "id": "asset_01kfjvmkq6f4ca2y4bdvd8016c",
        "name": "Luxurious Rubber Tuna",
        "type": "STOCK",
        "pricePerUnit": 54.87,
        "totalUnits": 1335,
        "totalAmount": 73251.45,
        "yield": null,
        "duration": null,
        "durationType": null,
        "accountId": "account_01k8n2b26bfzwv7nnyayk8e5t3",
        "offeringId": "offering_01kfjvmkpperebzey73vsc5pnr",
        "template": "STANDARD",
        "tiers": null,
        "enableBonus": false,
        "bonusTiers": [],
        "__entity": "Asset"
    },
    "__entity": "TradeLineItem",
    "generatedMaps": [],
    "raw": [],
    "affected": 1
}
```

***

### Step 6a: Get Payment Methods

**Description:**

Retrieves all payment methods associated with a user.

**Query Parameters:**

* `userId` - `user_xxxxxx`

**Example Request:**

```http
GET /clients/api/v1/payment-methods?userId=user_01kfjvfakzep3r0dpav23xfwg1
```

**Response:**

```json
[{
    "createdAt": "2026-01-22T12:39:37.764Z",
    "updatedAt": "2026-01-22T12:39:37.764Z",
    "deletedAt": null,
    "id": "payment_method_01kfjvfam1e8gtc4dbfymbq30m",
    "paymentMethodType": "CHECK",
    "paymentMethodProvider": "OTHER",
    "tid": null,
    "name": "Checking Account",
    "last4": null,
    "brand": null,
    "country": "US",
    "userId": "user_01kfjvfakzep3r0dpav23xfwg1",
    "status": "PENDING",
    "clientSecret": null,
    "__entity": "PaymentMethod"
}]
```

***

### Step 6b: Create Payment Method (if needed)

**Description:**

Creates a new payment method for the user.

**Query Parameters:**

* `userId` - `user_xxxxxx`

**Request Body:**

```json
{
    "paymentMethodType": "CREDIT_CARD",
    "paymentMethodProvider": "STRIPE",
    "status": "PENDING",
    "tid": "pm_1AbCdEfGhIjKlMnO",
    "name": "John Visa",
    "last4": "4242",
    "brand": "Visa",
    "country": "US"
}
```

**Example Request:**

```http
POST /clients/api/v1/payment-methods?userId=user_01kfjvfakzep3r0dpav23xfwg1
```

**Response:**

```json
{
    "paymentMethodType": "CREDIT_CARD",
    "paymentMethodProvider": "STRIPE",
    "tid": "pm_1AbCdEfGhIjKlMnO",
    "name": "John Visa",
    "last4": "4242",
    "brand": "Visa",
    "country": "US",
    "userId": "user_01kfjvfakzep3r0dpav23xfwg1",
    "status": "PENDING",
    "id": "payment_method_01kg1yb4nme00vdpbk0kzya67p",
    "clientSecret": null,
    "createdAt": "2026-01-28T09:18:22.900Z",
    "updatedAt": "2026-01-28T09:18:22.900Z",
    "deletedAt": null,
    "__entity": "PaymentMethod"
}
```

***

### Step 7: Update Cart with Investor Account and Payment Method

**Description:**

Associates an investor account and payment method with the cart to prepare for checkout.

**Request Body:**

```json
{
  "investorAccountId": "investor_account_01kfjvfamwe2yrkhypyzb2n0v0",
  "paymentMethodId": "payment_method_01kfjvfam1e8gtc4dbfymbq30m"
}
```

**Example Request:**

```http
PATCH /clients/api/v1/carts/trade_01kg1mbm8we5vvkmb5rrrfearv
```

**Response:**

```json
{
    "isUncleared24h": false,
    "createdAt": "2026-01-28T06:23:53.108Z",
    "updatedAt": "2026-01-28T09:20:50.088Z",
    "deletedAt": null,
    "id": "trade_01kg1mbm8we5vvkmb5rrrfearv",
    "investorAccountId": "investor_account_01kfjvfamwe2yrkhypyzb2n0v0",
    "accountId": "account_01k8n2b26bfzwv7nnyayk8e5t3",
    "offeringId": "offering_01kfjvmkpperebzey73vsc5pnr",
    "paymentMethodId": "payment_method_01kfjvfam1e8gtc4dbfymbq30m",
    "userId": "user_01kfjvfakzep3r0dpav23xfwg1",
    "tradeNumber": "D-8915-NWTX",
    "ip": "::1",
    "tid": null,
    "platform": "DALMORE",
    "investmentType": "INDIVIDUAL",
    "purchasedShares": 100,
    "bonusShares": 0,
    "totalNumberOfShares": 100,
    "pricePerShare": 0,
    "totalAmount": 5487,
    "tradeStatus": "CART",
    "tradeStatusUnmapped": null,
    "tradeDate": null,
    "saStatus": "PENDING",
    "saStatusUnmapped": null,
    "saUrl": null,
    "saSignedAt": null,
    "saExtractedNumberOfShares": null,
    "saExtractedTotalAmount": null,
    "saExtractedPricePerShare": null,
    "saExtractedInvestorType": null,
    "saExtractedSigner": null,
    "saExtractedSignatureDate": null,
    "saExtractedSigner2": null,
    "saExtractedSignatureDate2": null,
    "saCheck": "PENDING",
    "saCheckedAt": null,
    "saLog": null,
    "txnTid": null,
    "txnResponse": null,
    "txnPaymentMethod": "CHECK",
    "txnCurrencyCode": null,
    "txnChargedAmount": null,
    "txnDate": null,
    "txnSettledDate": null,
    "fundingStatus": "PENDING",
    "fundingStatusUnmapped": null,
    "txnCheck": "PENDING",
    "txnCheckedAt": null,
    "txnLog": null,
    "systemReviewCheck": "PENDING",
    "systemReviewCheckedAt": null,
    "systemReviewLog": null,
    "complianceReview": "PENDING",
    "complianceReviewNotes": null,
    "complianceReviewerId": null,
    "managedBy": "DALMORE",
    "reviewStartAt": null,
    "reviewCount": null,
    "issuerId": "issuer_01kdsw8zwwenfv86g65y9qv8rh",
    "complianceReviewName": null,
    "complianceReviewAt": null,
    "tradeType": "PURCHASE",
    "placedAt": null,
    "closedAt": null,
    "cancellationPeriod": null,
    "cancelledAt": null,
    "cancelledById": null,
    "cancelledReason": null,
    "rejectionReason": null,
    "disbursed": false,
    "registeredRepId": null,
    "userDataType": "LIVE",
    "__entity": "Trade"
}
```

***

### Step 8: Upload Subscription Agreement

**Description:**

Uploads a subscription agreement document for the trade.

**Query Parameters:**

* `name` - File name (e.g., `subscription-agreement.pdf`)
* `category` - `offering-document`
* `label` - `SUBSCRIPTION_AGREEMENT`
* `targetId` - Trade ID (cart ID)

**Content-Type:**

`multipart/form-data`

**Example Request:**

```http
POST /clients/api/v1/files?name=subscription-agreement.pdf&category=offering-document&label=SUBSCRIPTION_AGREEMENT&targetId=trade_01kg1mbm8we5vvkmb5rrrfearv
```

**Response:**

```json
{
    "name": "subscription-agreement.pdf",
    "category": "offering-document",
    "userId": "user_01kcrnjwg4ejkrcape9xcg258f",
    "accountId": "account_01k8n2b26bfzwv7nnyayk8e5t3",
    "url": "https://dalmoredatafactory.blob.core.windows.net/api-files-dev/1769592171672.trade_01kctzk688efaaavecvkcdkftx.2023%20-%20Single%20(Tax%20Doc).pdf",
    "fileType": "application/pdf",
    "fileName": "subscription-agreement.pdf",
    "targetTable": "TRADES",
    "targetId": "trade_01kctzk688efaaavecvkcdkftx",
    "linkedFrom": null,
    "label": "SUBSCRIPTION_AGREEMENT",
    "private": true,
    "metadata": null,
    "complianceReview": "APPROVED",
    "pipeline": "NONE",
    "status": "PENDING",
    "id": "file_01kg1ykdh6e00vdpjnrrq4kqw8",
    "tid": null,
    "reviewLog": null,
    "errorMessage": null,
    "createdAt": "2026-01-28T09:22:51.670Z",
    "updatedAt": "2026-01-28T09:22:51.670Z",
    "deletedAt": null,
    "__entity": "File"
}
```

***

### Step 9: Attach Subscription Agreement to Trade Line Item

**Description:**

Attaches an uploaded subscription agreement to a specific trade line item and records signature statuses.

**Request Body:**

```json
{
  "lineItemId": "trade_line_item_01kg1mbm9mentbev7ech4dqd14",
  "fileId": "file_01kg1mbsvxf20a2xda68fvmanc",
  "primarySignatureStatus": "SIGNED"
}
```

**Example Request:**

```http
POST /clients/api/v1/trades/trade_01kg1mbm8we5vvkmb5rrrfearv/attach-subdoc
```

**Response:**

```json
{
    "success": true,
    "message": "Subdoc attached successfully"
}
```

***

### Step 10: Checkout Cart (Place Trade)

**Description:**

Finalizes the cart and places the trade. This transitions the cart from `CART` status to a placed trade status.

**Request Body:**

```json
{
  "userId": "user_01kfjvfakzep3r0dpav23xfwg1"
}
```

**Example Request:**

```http
POST /clients/api/v1/carts/checkout
```

**Response:**

```json
{
    "tradeStatus": "PLACED"
}
```

***

### Complete Workflow Summary

**Sequential API Calls:**

1. **GET** `/investor-accounts` - Select investor account
2. **GET** `/offerings` - Browse available offerings
3. **GET** `/offerings/{id}?include=assets` - Get offering details with assets
4. **GET** `/carts?userId={userId}` - Retrieve or create cart
5. **POST** `/trade-line-items?userId={userId}` - Add asset to cart (or **PATCH** `/trade-line-items/{id}` to update existing)
6. **GET** `/payment-methods?userId={userId}` - Get payment methods (or **POST** `/payment-methods?userId={userId}` to create new)
7. **PATCH** `/carts/{id}` - Attach investor account and payment method
8. **POST** `/files` - Upload subscription agreement
9. **POST** `/trades/{id}/attach-subdoc` - Attach document to line item *(optional)*
10. **POST** `/carts/checkout` - Place the trade

***

### Quick Reference

| Step | Method | Endpoint                            | Purpose                            |
| ---- | ------ | ----------------------------------- | ---------------------------------- |
| 1    | GET    | `/investor-accounts`                | Get user's investor accounts       |
| 2    | GET    | `/offerings`                        | Browse available offerings         |
| 3    | GET    | `/offerings/{id}?include=assets`    | Get offering with assets           |
| 4    | GET    | `/carts?userId={userId}`            | Get or create cart                 |
| 5a   | POST   | `/trade-line-items?userId={userId}` | Add asset to cart                  |
| 5b   | PATCH  | `/trade-line-items/{id}`            | Update line item quantity          |
| 6a   | GET    | `/payment-methods?userId={userId}`  | Get payment methods                |
| 6b   | POST   | `/payment-methods?userId={userId}`  | Create payment method              |
| 7    | PATCH  | `/carts/{id}`                       | Update cart with account & payment |
| 8    | POST   | `/files`                            | Upload subscription agreement      |
| 9    | POST   | `/trades/{id}/attach-subdoc`        | Attach subdoc to line item         |
| 10   | POST   | `/carts/checkout`                   | Place the trade                    |

### Support

For additional support or questions, please refer to:

{% tabs %}
{% tab title="DEV" %}
<https://compliance.dalmoredev.com/>
{% endtab %}

{% tab title="PROD" %}
[https://compliance.dalmoregroup.com/](https://compliance.dalmoredev.com/)
{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="DEV" %}
[Swagger API Documentation](https://platform.dalmoredev.com/clients)
{% endtab %}

{% tab title="PROD" %}
[Swagger API Documentation](https://platform.dalmoregroup.com/clients)
{% endtab %}
{% endtabs %}

Postman Collection for Testing

{% file src="/files/Uzxeb2OUINgQr9tLtO9R" %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.dalmoredirect.com/dalmore-api-documentation.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
