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

# Vault — Confirm Upload

> Step 3 of the Vault upload flow. Registers the uploaded file in RMS and triggers async ingestion (parse → chunk → embed → index), returning immediately with the rms_document_id. Poll GET /v2/vault/status for processing status / readiness.

Step 3 of the Vault upload flow. Registers the uploaded file in RMS and triggers async ingestion (parse → chunk → embed → index).

The file **must already be uploaded** (via the presigned URL) before calling this.

`confirm` is **enqueue-and-return**: it responds immediately with the `rms_document_id`. Processing runs in the background — poll **`GET /v2/vault/status`** with the returned `rms_document_id` until `status` is `Synced`. (Document status lives on `/vault/status`, not on this response.)

```bash theme={null}
curl --request POST \
  --url 'https://api.linqalpha.com/v2/vault/confirm' \
  --header 'X-API-KEY: <api-key>' \
  --header 'Content-Type: application/json' \
  --data '{"document_id":"3a5b47d5-...","file_key":"development/data-original/<hash>.pdf","file_name":"Q4_report.pdf","content_type":"application/pdf"}'
```

<Note>
  `rms_document_id` is populated for normal file uploads. It is `null` only when the upload deduplicates into an existing document (`status: "already_exists"`) — in that case the document already exists and no new processing is enqueued.
</Note>

## `content_type` by file type

Pass the canonical MIME type for the file's type. **If the `content_type` does not match the file, the document is not processed** — always use the exact value from the table below.

The **same `content_type` must be used at all three steps** — `presigned_url`, the upload `PUT` (`Content-Type` header), and `confirm`. The upload URL is signed with it, so a mismatch is rejected with HTTP `403`.

| File type           | Extension | `content_type`                                                              |
| ------------------- | --------- | --------------------------------------------------------------------------- |
| PDF                 | `.pdf`    | `application/pdf`                                                           |
| Word                | `.docx`   | `application/vnd.openxmlformats-officedocument.wordprocessingml.document`   |
| Word (legacy)       | `.doc`    | `application/msword`                                                        |
| Excel               | `.xlsx`   | `application/vnd.openxmlformats-officedocument.spreadsheetml.sheet`         |
| Excel (macro)       | `.xlsm`   | `application/vnd.ms-excel.sheet.macroenabled.12`                            |
| Excel (binary)      | `.xlsb`   | `application/vnd.ms-excel.sheet.binary.macroenabled.12`                     |
| Excel (legacy)      | `.xls`    | `application/vnd.ms-excel`                                                  |
| PowerPoint          | `.pptx`   | `application/vnd.openxmlformats-officedocument.presentationml.presentation` |
| PowerPoint (legacy) | `.ppt`    | `application/vnd.ms-powerpoint`                                             |
| Text                | `.txt`    | `text/plain`                                                                |
| CSV                 | `.csv`    | `text/csv`                                                                  |
| Audio               | `.mp3`    | `audio/mpeg`                                                                |
| Audio               | `.m4a`    | `audio/x-m4a`                                                               |
| Audio               | `.wav`    | `audio/wav`                                                                 |
| Video               | `.mp4`    | `video/mp4`                                                                 |
| HWP                 | `.hwp`    | `application/vnd.hancom.hwp`                                                |
| HWPX                | `.hwpx`   | `application/vnd.hancom.hwpx`                                               |

<Note>
  The server resolves the file type from the **`file_name` extension first**, falling back to `content_type` only when the name has no extension — so always send a `file_name` with the correct extension. Legacy Office (`.xls/.xlsm/.xlsb/.doc/.ppt`), audio, and HWP/HWPX are auto-converted to a renderable parse target during ingestion.
</Note>

## `document_id` vs `rms_document_id`

These are **two different identifiers** created at different steps. Mixing them up is the most common integration error.

| ID                | Created by                            | What it's for                                                                                                                                                             |
| ----------------- | ------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `document_id`     | `presigned_url` (an upload handle)    | Carry it from `presigned_url` → `confirm`. Used only to tie the two calls together. Downstream endpoints do **not** use it.                                               |
| `rms_document_id` | `confirm` (the RMS document row's id) | The real document identifier. Pass it to **`GET /v2/vault/status`** (`rms_document_ids`) and to the **analytics SSE** search payload (`search_types.rms[].document_ids`). |

```
presigned_url  → document_id        (handle: presign → confirm only)
confirm         → rms_document_id    (real id)
status          → rms_document_ids = [rms_document_id]
analytics SSE   → search_types.rms[].document_ids = [rms_document_id]
```

<Note>For status polling and the analytics SSE, always use **`rms_document_id`** — never the presign `document_id`. When `rms_document_id` is `null` (dedup), there is no new id to poll; the existing document is already processed.</Note>


## OpenAPI

````yaml POST /v2/vault/confirm
openapi: 3.0.1
info:
  title: LinqAlpha API
  description: >-
    Linq helps finance professionals make informed decisions using
    Retrieval-Augmented Generation (RAG)-enhanced answers. By leveraging
    cutting-edge Large Language Models (LLM) and supplementary technology, Linq
    provides the most optimized responses based on your queries.
  version: 1.0.0
  license:
    name: MIT
servers:
  - url: https://api.linqalpha.com
security:
  - ApiKeyAuth: []
tags:
  - name: Search
    description: Search and generate responses
  - name: Data
    description: Data retrieval and mapping
  - name: Feedback
    description: Conversation feedback
  - name: RMS
    description: Research Management System
  - name: Source Management
    description: Source batch and file management
  - name: MCP
    description: >-
      LinqAlpha MCP — Financial data tools for AI assistants via Model Context
      Protocol
  - name: Connectors
    description: Customer Connectors — customer-owned MCP connector management
  - name: Briefing
    description: Briefing Agent — automated market briefings with scheduling and delivery
  - name: Status
    description: Sync status — check organization, document, and container sync progress
paths:
  /v2/vault/confirm:
    post:
      tags:
        - Vault
      summary: Vault — Confirm Upload
      description: >-
        Step 3 of the Vault upload flow. Registers the uploaded file in RMS and
        triggers async ingestion (parse → chunk → embed → index), returning
        immediately with the rms_document_id. Poll GET /v2/vault/status for
        processing status / readiness.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/VaultConfirmRequest'
            example:
              document_id: 3a5b47d5-124e-4052-9fa6-0647ddcb1d97
              file_key: development/data-original/<hash>.pdf
              file_name: Q4_report.pdf
              content_type: application/pdf
              workspace: personal
      responses:
        '200':
          description: Upload confirmed / registered
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VaultConfirmResponse'
              example:
                rms_document_id: eeb72343-d883-41a3-a58c-533184bbb9fd
        '400':
          description: Bad request — missing/invalid fields
        '401':
          description: Unauthorized — invalid or missing API key
        '500':
          description: Upstream error — e.g. the uploaded file does not exist yet
components:
  schemas:
    VaultConfirmRequest:
      type: object
      required:
        - document_id
        - file_key
        - file_name
        - content_type
      properties:
        document_id:
          type: string
          description: From the presigned_url response.
        file_key:
          type: string
          description: From the presigned_url response.
        file_name:
          type: string
          description: >-
            Original filename including the extension. The server resolves the
            file type from this extension first, so it must be correct.
          example: Q4_report.pdf
        content_type:
          type: string
          description: >-
            Canonical MIME type for the file. Must match the value sent to
            presigned_url and the upload PUT Content-Type header. If the
            content_type does not match the file, the document is not processed.
            See the content_type table on this page for the value per file type.
          example: application/pdf
        workspace:
          type: string
          enum:
            - personal
            - organization
          default: personal
        organization_id:
          type: string
          format: uuid
          description: Organization ID (optional).
        user_id:
          type: string
          format: uuid
          description: User id (optional).
        user_email:
          type: string
          format: email
          description: User email (optional).
        user_name:
          type: string
          description: User name (optional).
    VaultConfirmResponse:
      type: object
      properties:
        rms_document_id:
          type: string
          nullable: true
          description: >-
            RMS document id; null when the upload deduplicated into an existing
            document. Use it to poll GET /v2/vault/status.
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-KEY

````