{
  "openapi": "3.0.1",
  "info": {
    "title": "MFT Content API",
    "description": "File content plane for the Boomi MFT (Automated File Transfer) platform. Handles the movement of file bytes: single-shot and chunked (resumable) uploads, streamed and presigned-URL downloads, and listing the files staged against a flow endpoint. Configuration of flows, endpoints, and credentials lives in the MFT Management API.\n\n## Prerequisites\n\nYou need an MFT account, a flow with at least one flow endpoint to upload to or download from, and credentials that carry the privilege the operation requires. Every request goes to your account's regional host — see **Servers** below.\n\n## Authentication\n\nThree credential types are accepted, and any one of them satisfies every non-anonymous operation:\n\n- **API key** (`ApiKey` header) — the usual choice for programmatic access. Create the key in the MFT portal, scoped to the Content API, and send its value in the `ApiKey` request header.\n- **OAuth 2.0 client credentials** — request a token from `/oauth/token` on the same regional host and send it as `Authorization: Bearer <token>`. This is how the MFT connector authenticates.\n- **Session bearer token** — a JWT issued by the MFT portal sign-in endpoint, sent as `Authorization: Bearer <token>`.\n\n## Required privileges\n\nAuthentication alone is not enough: the credential must also carry the privilege for the operation. Uploading requires **File Upload**; downloading, generating a presigned URL, and listing files require **File Download**. Each operation states its privilege. Requests are additionally scoped to the caller's tenant, so a valid credential can only reach flow endpoints its own account owns.\n\nRedeeming a presigned download URL is the one exception — the token carries its own authorization, so no credential is sent.",
    "contact": {
      "name": "Boomi Support",
      "url": "https://support.boomi.com/boomi_support"
    },
    "version": "V2"
  },
  "servers": [
    {
      "url": "https://{region}-api.mft.boomi.com",
      "description": "Regional MFT API host. Use the region your MFT account is provisioned in.",
      "variables": {
        "region": {
          "default": "us",
          "description": "us (United States), eu (Europe), uk (United Kingdom), au (Australia).",
          "enum": [
            "us",
            "eu",
            "uk",
            "au"
          ]
        }
      }
    }
  ],
  "paths": {
    "/api/Files/1.0/{fileReferenceId}/presigned": {
      "post": {
        "tags": [
          "Download"
        ],
        "summary": "Generate a short-lived presigned download URL for a file",
        "description": "Mints a time- and use-limited token that grants anonymous download of a single file, suitable for handing to an external recipient. The token is returned as `{ \"presignedUrl\": \"<token>\" }` and is redeemed at `GET /api/Files/1.0/presigned/{presignedUrl}/content`. Requires the FileDownload permission.\n\n**Required privilege:** File Download.",
        "operationId": "Download_GeneratePresignedUrl",
        "parameters": [
          {
            "name": "fileReferenceId",
            "in": "path",
            "description": "Identifier of the file to expose.",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ThruApplication",
            "in": "header",
            "description": "Optional. Name of the calling application, recorded for tracing. Sent as the `ThruApplication` header.",
            "schema": {
              "type": "string",
              "default": "ThruApplication"
            }
          },
          {
            "name": "X-Thru-Tracking-ThruNodeId",
            "in": "header",
            "description": "Optional. Identifier of the MFT node that originated the request, recorded for tracing. Sent as the `X-Thru-Tracking-ThruNodeId` header.",
            "schema": {
              "type": "string",
              "default": ""
            }
          }
        ],
        "requestBody": {
          "description": "Target endpoint path plus limits: MaxDownloads (1–10) and ActiveDuration (1–86400 seconds).",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PresignedUrlRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The presigned token was created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PresignedUrlResponse"
                }
              }
            }
          },
          "400": {
            "description": "The request limits are out of range, or the file/customer could not be resolved.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "The flow or file could not be found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "The target resource is disabled.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKey": []
          },
          {
            "OAuth2": [
              "publicAPI-read"
            ]
          },
          {
            "BearerAuth": []
          }
        ]
      }
    },
    "/api/Files/1.0/{fileReferenceId}/content": {
      "get": {
        "tags": [
          "Download"
        ],
        "summary": "Download a file's content by file reference",
        "description": "Streams the bytes of the referenced file back to an authenticated caller. Supports HTTP range requests for partial/resumable downloads. Requires the FileDownload permission.\n\n**Required privilege:** File Download.",
        "operationId": "Download_Download",
        "parameters": [
          {
            "name": "fileReferenceId",
            "in": "path",
            "description": "Identifier of the file to download.",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "endpointPath",
            "in": "query",
            "description": "Flow endpoint path that locates the file's storage.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ThruApplication",
            "in": "header",
            "description": "Optional. Name of the calling application, recorded for tracing. Sent as the `ThruApplication` header.",
            "schema": {
              "type": "string",
              "default": "ThruApplication"
            }
          },
          {
            "name": "X-Thru-Tracking-ThruNodeId",
            "in": "header",
            "description": "Optional. Identifier of the MFT node that originated the request, recorded for tracing. Sent as the `X-Thru-Tracking-ThruNodeId` header.",
            "schema": {
              "type": "string",
              "default": ""
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The file content stream.",
            "headers": {
              "X-Thru-Path": {
                "description": "Path of the stored file relative to the endpoint root.",
                "schema": {
                  "type": "string",
                  "example": "/2026/08/invoices-2026-08-21.csv"
                }
              }
            },
            "content": {
              "application/octet-stream": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "206": {
            "description": "A requested byte range of the file content.",
            "headers": {
              "X-Thru-Path": {
                "description": "Path of the stored file relative to the endpoint root.",
                "schema": {
                  "type": "string",
                  "example": "/2026/08/invoices-2026-08-21.csv"
                }
              }
            },
            "content": {
              "application/octet-stream": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "404": {
            "description": "The file or its repository could not be found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "The target resource is disabled.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKey": []
          },
          {
            "OAuth2": [
              "publicAPI-read"
            ]
          },
          {
            "BearerAuth": []
          }
        ]
      }
    },
    "/api/Files/1.0/presigned/{presignedUrl}/content": {
      "get": {
        "tags": [
          "Download"
        ],
        "summary": "Download a file's content using a presigned token",
        "description": "Redeems a presigned token issued by `POST /api/Files/1.0/{fileReferenceId}/presigned` and streams the file content. Anonymous: the token itself authorizes the download, so no bearer credentials are required. The token expires and is capped to a maximum number of downloads; once exhausted or expired it is rejected. Supports HTTP range requests.\n\n**Required privilege:** none — this operation is unauthenticated.",
        "operationId": "Download_DownloadByPresignedUrl",
        "parameters": [
          {
            "name": "presignedUrl",
            "in": "path",
            "description": "The presigned token to redeem.",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ThruApplication",
            "in": "header",
            "description": "Optional. Name of the calling application, recorded for tracing. Sent as the `ThruApplication` header.",
            "schema": {
              "type": "string",
              "default": "thru-web-ui"
            }
          },
          {
            "name": "X-Thru-Tracking-ThruNodeId",
            "in": "header",
            "description": "Optional. Identifier of the MFT node that originated the request, recorded for tracing. Sent as the `X-Thru-Tracking-ThruNodeId` header.",
            "schema": {
              "type": "string",
              "default": ""
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The file content stream.",
            "headers": {
              "X-Thru-Path": {
                "description": "Path of the stored file relative to the endpoint root.",
                "schema": {
                  "type": "string",
                  "example": "/2026/08/invoices-2026-08-21.csv"
                }
              }
            },
            "content": {
              "application/octet-stream": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "206": {
            "description": "A requested byte range of the file content.",
            "headers": {
              "X-Thru-Path": {
                "description": "Path of the stored file relative to the endpoint root.",
                "schema": {
                  "type": "string",
                  "example": "/2026/08/invoices-2026-08-21.csv"
                }
              }
            },
            "content": {
              "application/octet-stream": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "The token is unknown/expired, or the file could not be found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "The target resource is disabled.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {}
        ]
      }
    },
    "/api/Files/1.0/FlowEndpoints/{flowEndpointId}/List": {
      "get": {
        "tags": [
          "FileList"
        ],
        "summary": "List the files staged against a flow endpoint",
        "description": "Returns a filtered view of the files held for the given flow endpoint. Filters are supplied as query-string parameters: maxFiles (page cap), fileId, status and actionType (each a repeated key for multiple values), and createdAfter/createdBefore (inclusive ISO-8601 UTC bounds on creation time). Multiple values are expressed by repeating a key — comma-joined lists are not parsed — and any unknown query key is rejected with a 400. Results are scoped to the caller's tenant, which must own the flow endpoint; requires the FileDownload permission.\n\n**Required privilege:** File Download.",
        "operationId": "FileList_List",
        "parameters": [
          {
            "name": "flowEndpointId",
            "in": "path",
            "description": "Identifier of the flow endpoint whose files are listed. Must be a positive integer.",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "maxFiles",
            "in": "query",
            "description": "Maximum number of files to return (default 100, max 1000).",
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          },
          {
            "name": "fileId",
            "in": "query",
            "description": "File id filter; repeat the key for multiple values (max 100).",
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          },
          {
            "name": "status",
            "in": "query",
            "description": "File status filter; repeat the key for multiple values (max 10).",
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          },
          {
            "name": "actionType",
            "in": "query",
            "description": "Action type filter; repeat the key for multiple values (max 10).",
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          },
          {
            "name": "createdAfter",
            "in": "query",
            "description": "Inclusive lower bound on file creation time (ISO-8601, UTC).",
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          },
          {
            "name": "createdBefore",
            "in": "query",
            "description": "Inclusive upper bound on file creation time (ISO-8601, UTC).",
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of matching files.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FileListResponse"
                }
              }
            }
          },
          "400": {
            "description": "The filter or paging parameters are invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "The caller has no tenant context, or does not own this flow endpoint.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "No flow endpoint exists for the supplied id.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "504": {
            "description": "The query exceeded the server time limit; narrow the filters and retry."
          }
        },
        "security": [
          {
            "ApiKey": []
          },
          {
            "OAuth2": [
              "publicAPI-read"
            ]
          },
          {
            "BearerAuth": []
          }
        ]
      }
    },
    "/api/HealthCheck/Thru.MFT.ContentAPI": {
      "get": {
        "tags": [
          "HealthCheck"
        ],
        "summary": "Liveness probe for the MFT Content API",
        "description": "Returns 200 OK when the service is up. Used by load balancers and orchestration health checks; performs no downstream (database or storage) dependency checks.\n\n**Required privilege:** none — this operation is unauthenticated.",
        "operationId": "HealthCheck_ThruMftContentApiHealthCheck",
        "responses": {
          "200": {
            "description": "The service is running."
          }
        },
        "security": [
          {}
        ]
      }
    },
    "/api/Files/1.0/Content": {
      "options": {
        "tags": [
          "Upload"
        ],
        "summary": "Pre-flight an upload and discover upload limits and URLs",
        "description": "Validates the target endpoint path and file attributes before any bytes are sent, and returns the maximum chunk size along with the URLs for the single-file and chunked (resumable) upload flows. Clients call this first to decide which upload path to use.\n\n**Required privilege:** none beyond a valid credential.",
        "operationId": "Upload_UploadPreFlight",
        "parameters": [
          {
            "name": "X-Thru-Tracking-ThruNodeId",
            "in": "header",
            "description": "Optional. Identifier of the MFT node that originated the request, recorded for tracing. Sent as the `X-Thru-Tracking-ThruNodeId` header.",
            "schema": {
              "type": "string",
              "default": ""
            }
          }
        ],
        "requestBody": {
          "description": "Target endpoint path and file attributes to validate.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UploadInfo"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Upload limits and the single-file / chunked upload URLs.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UploadPreFlightResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKey": []
          },
          {
            "OAuth2": [
              "publicAPI-read"
            ]
          },
          {
            "BearerAuth": []
          }
        ]
      },
      "post": {
        "tags": [
          "Upload"
        ],
        "summary": "Upload a whole file in a single request",
        "description": "Streams one complete file to its target flow endpoint in a single multipart request. Use this for files at or below the maximum chunk size reported by the pre-flight (OPTIONS) call; larger files should use the chunked upload-session flow. On success the response headers carry the transfer/activity tracking identifiers.\n\n**Required privilege:** File Upload.",
        "operationId": "Upload_UploadSingleFile",
        "parameters": [
          {
            "name": "X-Thru-Tracking-RequestId",
            "in": "header",
            "description": "Optional. Caller-supplied identifier used to correlate this upload with the caller's own records. Sent as the `X-Thru-Tracking-RequestId` header.",
            "schema": {
              "type": "integer",
              "format": "int64",
              "default": 0
            }
          },
          {
            "name": "X-Thru-Tracking-ThruNodeId",
            "in": "header",
            "description": "Optional. Identifier of the MFT node that originated the request, recorded for tracing. Sent as the `X-Thru-Tracking-ThruNodeId` header.",
            "schema": {
              "type": "string",
              "default": ""
            }
          },
          {
            "name": "ThruApplication",
            "in": "header",
            "description": "Optional. Name of the calling application, recorded for tracing. Sent as the `ThruApplication` header.",
            "schema": {
              "type": "string",
              "default": ""
            }
          }
        ],
        "requestBody": {
          "description": "Two-part multipart/form-data body. Send the JSON metadata part first, then the file bytes.",
          "content": {
            "multipart/form-data": {
              "schema": {
                "required": [
                  "Model_0",
                  "Model_1"
                ],
                "type": "object",
                "properties": {
                  "Model_0": {
                    "allOf": [
                      {
                        "$ref": "#/components/schemas/SingleFileRequest"
                      }
                    ],
                    "description": "JSON metadata for the upload, sent as a text part."
                  },
                  "Model_1": {
                    "type": "string",
                    "description": "The complete file to upload.",
                    "format": "binary"
                  }
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "The file was uploaded and accepted.",
            "headers": {
              "X-Thru-Tracking-ActivityId": {
                "description": "MFT-generated identifier for the file this upload created. Use it to correlate with transfer tracking and audit records.",
                "schema": {
                  "type": "string",
                  "example": "66c5a1f0e3b94a7d2c4f8b13"
                }
              }
            }
          },
          "400": {
            "description": "The upload payload or model data is invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKey": []
          },
          {
            "OAuth2": [
              "publicAPI-read"
            ]
          },
          {
            "BearerAuth": []
          }
        ]
      }
    },
    "/api/Files/1.0/Upload_Sessions": {
      "post": {
        "tags": [
          "Upload"
        ],
        "summary": "Start a chunked (resumable) upload session",
        "description": "Opens an upload session for a large file, returning the session identifier in the response headers. Chunks are then sent with PUT to the session, finalised with Commit, or discarded with Abort. Use this flow when a file exceeds the single-request maximum chunk size.\n\n**Required privilege:** File Upload.",
        "operationId": "Upload_UploadSession",
        "parameters": [
          {
            "name": "X-Thru-Tracking-RequestId",
            "in": "header",
            "description": "Optional. Caller-supplied identifier used to correlate this upload with the caller's own records. Sent as the `X-Thru-Tracking-RequestId` header.",
            "schema": {
              "type": "integer",
              "format": "int64",
              "default": 0
            }
          },
          {
            "name": "X-Thru-Tracking-ThruNodeId",
            "in": "header",
            "description": "Optional. Identifier of the MFT node that originated the request, recorded for tracing. Sent as the `X-Thru-Tracking-ThruNodeId` header.",
            "schema": {
              "type": "string",
              "default": ""
            }
          },
          {
            "name": "ThruApplication",
            "in": "header",
            "description": "Optional. Name of the calling application, recorded for tracing. Sent as the `ThruApplication` header.",
            "schema": {
              "type": "string",
              "default": ""
            }
          }
        ],
        "requestBody": {
          "description": "Target endpoint path and file attributes for the session.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UploadInfo"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "The upload session was created; use the returned session id for subsequent chunks.",
            "headers": {
              "X-Thru-TransferId": {
                "description": "Identifier of the upload session just created. The response has no body, so this header is the only place it is returned — pass it as the uploadSession path segment on every subsequent chunk, commit, abort, and status call.",
                "schema": {
                  "type": "string",
                  "example": "7c1f2a44-08d5-4d1e-9a3b-51f0c2e9de77"
                }
              },
              "X-Thru-Tracking-ActivityId": {
                "description": "MFT-generated identifier for the file this upload created. Use it to correlate with transfer tracking and audit records.",
                "schema": {
                  "type": "string",
                  "example": "66c5a1f0e3b94a7d2c4f8b13"
                }
              }
            }
          },
          "400": {
            "description": "The session model data is invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "The token is not authorized for the target flow endpoint.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKey": []
          },
          {
            "OAuth2": [
              "publicAPI-read"
            ]
          },
          {
            "BearerAuth": []
          }
        ]
      }
    },
    "/api/Files/1.0/Upload_Sessions/{uploadSession}": {
      "patch": {
        "tags": [
          "Upload"
        ],
        "summary": "Set or update the file details on an open upload session",
        "description": "Updates the target endpoint path and file attributes for an in-progress chunked upload session before it is committed. The destination endpoint is re-validated against the caller's authorization on every call.\n\n**Required privilege:** none beyond a valid credential.",
        "operationId": "Upload_UploadSessionSetFileDetails",
        "parameters": [
          {
            "name": "uploadSession",
            "in": "path",
            "description": "Identifier of the open upload session.",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Thru-Tracking-ThruNodeId",
            "in": "header",
            "description": "Optional. Identifier of the MFT node that originated the request, recorded for tracing. Sent as the `X-Thru-Tracking-ThruNodeId` header.",
            "schema": {
              "type": "string",
              "default": ""
            }
          }
        ],
        "requestBody": {
          "description": "Updated target endpoint path and file attributes.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UploadInfo"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "The session file details were updated."
          },
          "400": {
            "description": "The model data is invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "The token is not authorized for the target flow endpoint.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKey": []
          },
          {
            "OAuth2": [
              "publicAPI-read"
            ]
          },
          {
            "BearerAuth": []
          }
        ]
      },
      "put": {
        "tags": [
          "Upload"
        ],
        "summary": "Upload the next chunk of an open upload session",
        "description": "Appends a chunk of bytes to an in-progress chunked upload session. The chunk's position and size are taken from the Content-Range of the request. Call repeatedly until every chunk has been sent, then finalise with Commit.\n\n**Required privilege:** none beyond a valid credential.",
        "operationId": "Upload_ContinueUpload",
        "parameters": [
          {
            "name": "uploadSession",
            "in": "path",
            "description": "Identifier of the open upload session.",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Thru-Tracking-ThruNodeId",
            "in": "header",
            "description": "Optional. Identifier of the MFT node that originated the request, recorded for tracing. Sent as the `X-Thru-Tracking-ThruNodeId` header.",
            "schema": {
              "type": "string",
              "default": ""
            }
          }
        ],
        "requestBody": {
          "description": "Two-part multipart/form-data body. Send the JSON metadata part first, then the file bytes.",
          "content": {
            "multipart/form-data": {
              "schema": {
                "required": [
                  "Model_0",
                  "Model_1"
                ],
                "type": "object",
                "properties": {
                  "Model_0": {
                    "allOf": [
                      {
                        "$ref": "#/components/schemas/ChunkRequest"
                      }
                    ],
                    "description": "JSON metadata for the upload, sent as a text part."
                  },
                  "Model_1": {
                    "type": "string",
                    "description": "The bytes of this chunk.",
                    "format": "binary"
                  }
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "The chunk was accepted."
          }
        },
        "security": [
          {
            "ApiKey": []
          },
          {
            "OAuth2": [
              "publicAPI-read"
            ]
          },
          {
            "BearerAuth": []
          }
        ]
      }
    },
    "/api/Files/1.0/Upload_Sessions/{uploadSession}/Commit": {
      "post": {
        "tags": [
          "Upload"
        ],
        "summary": "Commit an upload session and assemble the final file",
        "description": "Finalises a chunked upload: the uploaded chunks are assembled into the complete file at its destination. Assembly is asynchronous — the endpoint returns 202 (with a Retry-After header) while assembly is in progress and 201 once the file is fully assembled, so clients poll Commit until it reports completion.\n\n**Required privilege:** File Upload.",
        "operationId": "Upload_CommitUpload",
        "parameters": [
          {
            "name": "uploadSession",
            "in": "path",
            "description": "Identifier of the upload session to commit.",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Thru-Tracking-ThruNodeId",
            "in": "header",
            "description": "Optional. Identifier of the MFT node that originated the request, recorded for tracing. Sent as the `X-Thru-Tracking-ThruNodeId` header.",
            "schema": {
              "type": "string",
              "default": ""
            }
          }
        ],
        "responses": {
          "201": {
            "description": "Assembly completed; the file is available at its destination."
          },
          "202": {
            "description": "Assembly is in progress; retry after the interval in the Retry-After header.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before polling the commit again while assembly finishes.",
                "schema": {
                  "type": "integer",
                  "example": "10"
                }
              }
            }
          },
          "500": {
            "description": "Assembly completed with an error."
          }
        },
        "security": [
          {
            "ApiKey": []
          },
          {
            "OAuth2": [
              "publicAPI-read"
            ]
          },
          {
            "BearerAuth": []
          }
        ]
      }
    },
    "/api/Files/1.0/Upload_Sessions/{uploadSession}/Abort": {
      "post": {
        "tags": [
          "Upload"
        ],
        "summary": "Abort an open upload session and discard its chunks",
        "description": "Cancels an in-progress chunked upload, releasing the staged chunks and marking the transfer as cancelled. Use this when a client abandons an upload it will not commit.\n\n**Required privilege:** File Upload.",
        "operationId": "Upload_AbortUpload",
        "parameters": [
          {
            "name": "uploadSession",
            "in": "path",
            "description": "Identifier of the upload session to abort.",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Thru-Tracking-ThruNodeId",
            "in": "header",
            "description": "Optional. Identifier of the MFT node that originated the request, recorded for tracing. Sent as the `X-Thru-Tracking-ThruNodeId` header.",
            "schema": {
              "type": "string",
              "default": ""
            }
          }
        ],
        "requestBody": {
          "description": "Optional reason/context for the cancellation.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CancellationInfo"
              }
            }
          }
        },
        "responses": {
          "204": {
            "description": "The session was aborted and its chunks discarded."
          }
        },
        "security": [
          {
            "ApiKey": []
          },
          {
            "OAuth2": [
              "publicAPI-read"
            ]
          },
          {
            "BearerAuth": []
          }
        ]
      }
    },
    "/api/Files/1.0/Upload_Sessions/{upload_session}": {
      "get": {
        "tags": [
          "Upload"
        ],
        "summary": "Get the status of an upload session",
        "description": "Returns the current state of a chunked upload session — file name, uploaded size, the byte ranges received so far, and start/complete timestamps — so a client can resume an interrupted upload by sending only the missing chunks.\n\n**Required privilege:** none beyond a valid credential.",
        "operationId": "Upload_GetUploadStatusInfos",
        "parameters": [
          {
            "name": "upload_session",
            "in": "path",
            "description": "Identifier of the upload session to inspect.",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The current status of the upload session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StatusInfo"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKey": []
          },
          {
            "OAuth2": [
              "publicAPI-read"
            ]
          },
          {
            "BearerAuth": []
          }
        ]
      }
    }
  },
  "components": {
    "schemas": {
      "CancellationInfo": {
        "type": "object",
        "properties": {
          "status": {
            "$ref": "#/components/schemas/CancellationStatus"
          },
          "message": {
            "type": "string",
            "description": "Free-text explanation recorded against the aborted session.",
            "nullable": true,
            "example": "Cancelled by the user before the final chunk was sent."
          }
        },
        "additionalProperties": false,
        "description": "Reason an upload session is being aborted."
      },
      "CancellationStatus": {
        "enum": [
          0,
          1
        ],
        "type": "integer",
        "description": "Outcome recorded when an upload session is aborted.",
        "format": "int32"
      },
      "ChunkRequest": {
        "type": "object",
        "properties": {
          "seqNumber": {
            "type": "integer",
            "description": "Zero-based position of this chunk in the file.",
            "format": "int32",
            "example": 4
          },
          "size": {
            "type": "integer",
            "description": "Size of the chunk in bytes. Set by the server from the received part.",
            "format": "int64",
            "example": 5242880
          },
          "hash": {
            "$ref": "#/components/schemas/HashInfo"
          }
        },
        "additionalProperties": false,
        "description": "Metadata part of a chunk upload within an open session."
      },
      "FileListContext": {
        "type": "object",
        "properties": {
          "flowEndpointId": {
            "type": "integer",
            "description": "Identifier of the flow endpoint these files belong to.",
            "format": "int32",
            "example": 7781
          },
          "flowId": {
            "type": "integer",
            "description": "Identifier of the flow the endpoint belongs to.",
            "format": "int32",
            "example": 912
          },
          "endpointId": {
            "type": "integer",
            "description": "Identifier of the endpoint definition behind the flow endpoint.",
            "format": "int32",
            "example": 2043
          },
          "organizationId": {
            "type": "integer",
            "description": "Identifier of the owning organization.",
            "format": "int32",
            "example": 118
          },
          "tenantId": {
            "type": "integer",
            "description": "Identifier of the owning tenant.",
            "format": "int32",
            "example": 57
          },
          "customerId": {
            "type": "integer",
            "description": "Identifier of the owning customer.",
            "format": "int32",
            "example": 31
          }
        },
        "additionalProperties": false,
        "description": "Cross-system context shared by every file at a flow endpoint, emitted once per LIST response (D29, option C). All files under one `flowEndpointId` share the same flow/endpoint/org/tenant/customer ids, so the server sends the block once and the connector copies it onto each emitted document — traceability without repeating six fields per file."
      },
      "FileListItem": {
        "type": "object",
        "properties": {
          "fileId": {
            "type": "string",
            "description": "Identifier of the file. Use this with the download operations.",
            "nullable": true,
            "example": "66c5a1f0e3b94a7d2c4f8b13"
          },
          "fileName": {
            "type": "string",
            "description": "Current name of the file at the flow endpoint.",
            "nullable": true,
            "example": "invoices-2026-08-21.csv"
          },
          "originalName": {
            "type": "string",
            "description": "Name the file arrived with, before any rename step in the flow.",
            "nullable": true,
            "example": "INV_20260821.CSV"
          },
          "fileSize": {
            "type": "integer",
            "description": "Size of the file in bytes.",
            "format": "int64",
            "example": 10485760
          },
          "status": {
            "type": "string",
            "description": "Current processing status of the file.",
            "nullable": true,
            "example": "Completed"
          },
          "actionType": {
            "type": "string",
            "description": "Flow action that produced or last touched the file.",
            "nullable": true,
            "example": "Upload"
          },
          "flowEndpointType": {
            "type": "string",
            "description": "Kind of flow endpoint the file is held at.",
            "nullable": true,
            "example": "Target"
          },
          "createdDate": {
            "type": "string",
            "description": "UTC time the file record was created in MFT (ISO-8601).",
            "format": "date-time",
            "example": "2026-08-21T09:14:41Z"
          },
          "uploader": {
            "$ref": "#/components/schemas/FileListUploader"
          },
          "protocol": {
            "type": "string",
            "description": "Transport the file arrived over.",
            "nullable": true,
            "example": "SFTP"
          },
          "transferType": {
            "type": "string",
            "description": "Direction of the transfer that delivered the file.",
            "nullable": true,
            "example": "Inbound"
          },
          "subfolderPath": {
            "type": "string",
            "description": "Path of the file below the endpoint root.",
            "nullable": true,
            "example": "/2026/08"
          },
          "remoteDirectory": {
            "type": "string",
            "description": "Directory the file was read from on the remote system.",
            "nullable": true,
            "example": "/outbox/invoices"
          },
          "timestamp": {
            "type": "string",
            "description": "The file's own source time (remote last-modified: SFTP LastWriteTime, S3/Azure/GCS LastModified, LAN GetLastWriteTime), not a record-keeping timestamp. Sits alongside ContentAPI.Application.Model.FileListItem.CreatedDate and is serialized the same way (ISO-8601 UTC). Sourced from the free-form `FileModel.FileTime` string; unparseable/empty/MinValue sentinels emit null.",
            "format": "date-time",
            "nullable": true,
            "example": "2026-08-21T09:14:37Z"
          },
          "flowEndpointTags": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FileListTag"
            },
            "description": "Point-in-time snapshot of this file's own Flow Endpoint metadata tags, captured onto the file record at transfer time. Absent for files whose endpoint carried no tags and for records written before that snapshotting shipped.",
            "nullable": true
          },
          "sourceFlowEndpointTags": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FileListTag"
            },
            "description": "Snapshot of the SOURCE endpoint's tags, copied onto each target file at creation so a source→target pair's tags are readable from the target record alone. Absent on source-side files and on target files whose source endpoint had no tags.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "One file in a LIST response. Identity is exposed as `fileId` (AFT-532 D63)."
      },
      "FileListResponse": {
        "type": "object",
        "properties": {
          "flowEndpointId": {
            "type": "integer",
            "description": "Identifier of the flow endpoint that was listed.",
            "format": "int32",
            "example": 7781
          },
          "files": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FileListItem"
            },
            "description": "The matching files, newest first, capped at `maxFiles`.",
            "nullable": true
          },
          "returnedCount": {
            "type": "integer",
            "description": "Number of files in `files`.",
            "format": "int32",
            "readOnly": true,
            "example": 2
          },
          "truncated": {
            "type": "boolean",
            "description": "True when the result hit `maxFiles`; the caller should narrow filters or page.",
            "example": false
          },
          "context": {
            "$ref": "#/components/schemas/FileListContext"
          }
        },
        "additionalProperties": false,
        "description": "LIST response envelope."
      },
      "FileListTag": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "Tag name.",
            "nullable": true,
            "example": "region"
          },
          "value": {
            "type": "string",
            "description": "Tag value.",
            "nullable": true,
            "example": "emea"
          }
        },
        "additionalProperties": false,
        "description": "One Flow Endpoint metadata tag as carried on a LIST item. A flat name/value pair — the stored snapshot keeps no tag id, so there is nothing else to surface."
      },
      "FileListUploader": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Identifier of the uploading user or service account.",
            "nullable": true,
            "example": "4821"
          },
          "name": {
            "type": "string",
            "description": "Display name of the uploader.",
            "nullable": true,
            "example": "Dana Okafor"
          },
          "type": {
            "type": "string",
            "description": "Whether the uploader was a portal user, an API client, or a service.",
            "nullable": true,
            "example": "User"
          }
        },
        "additionalProperties": false,
        "description": "AFT-984: the uploading user's identity carried on a LIST item. Only id/name/type are captured today (AFT-449); `id` is the internal user id rendered as a string (parity with the UI API mapping and the connector's all-string tracked properties). Email/first/last name are not yet captured at upload time."
      },
      "HashInfo": {
        "type": "object",
        "properties": {
          "hash": {
            "type": "string",
            "description": "The checksum value, hex-encoded.",
            "nullable": true,
            "example": "d41d8cd98f00b204e9800998ecf8427e"
          },
          "hashType": {
            "type": "string",
            "description": "Algorithm used to compute the checksum.",
            "nullable": true,
            "example": "MD5"
          }
        },
        "additionalProperties": false,
        "description": "A checksum and the algorithm that produced it."
      },
      "MetaInfo": {
        "type": "object",
        "properties": {
          "fileTime": {
            "type": "string",
            "description": "Last-modified time of the source file (ISO-8601, UTC).",
            "nullable": true,
            "example": "2026-08-21T09:14:37Z"
          },
          "fileName": {
            "type": "string",
            "description": "File name, without any directory component.",
            "nullable": true,
            "example": "invoices-2026-08-21.csv"
          },
          "path": {
            "type": "string",
            "description": "Directory path of the file relative to the endpoint root.",
            "nullable": true,
            "example": "/2026/08"
          },
          "sourceFullPath": {
            "type": "string",
            "description": "Full path of the file on the source system, recorded for tracking.",
            "nullable": true,
            "example": "/var/exports/2026/08/invoices-2026-08-21.csv"
          },
          "size": {
            "type": "integer",
            "description": "Size of the file in bytes.",
            "format": "int64",
            "nullable": true,
            "example": 10485760
          },
          "fileId": {
            "type": "string",
            "description": "Identifier of an existing file this upload replaces or continues.",
            "nullable": true,
            "example": "66c5a1f0e3b94a7d2c4f8b13"
          },
          "actionId": {
            "type": "string",
            "description": "Identifier of the flow action that produced this file.",
            "nullable": true,
            "example": "48219"
          },
          "processingId": {
            "type": "string",
            "description": "Identifier correlating this file with a processing run.",
            "nullable": true,
            "example": "7c1f2a44-08d5-4d1e-9a3b-51f0c2e9de77"
          },
          "customerCode": {
            "type": "string",
            "description": "Code of the customer that owns the target flow endpoint.",
            "nullable": true,
            "example": "acme"
          }
        },
        "additionalProperties": false,
        "description": "Attributes describing a single file in an upload."
      },
      "PresignedUrlRequest": {
        "type": "object",
        "properties": {
          "endpointPath": {
            "type": "string",
            "description": "Flow endpoint path that locates the file's storage, in `/{customerCode}/{flow}/{flowEndpoint}` form.",
            "nullable": true,
            "example": "/acme/invoices-inbound/partner-drop"
          },
          "maxDownloads": {
            "type": "integer",
            "description": "Maximum number of times the token may be redeemed. Between 1 and 10.",
            "format": "int32",
            "example": 3
          },
          "activeDuration": {
            "type": "integer",
            "description": "Lifetime of the token in seconds, from the moment it is issued. Between 1 and 86400 (24 hours).",
            "format": "int32",
            "example": 3600
          }
        },
        "additionalProperties": false,
        "description": "Body of a presigned-download request: which flow endpoint holds the file, and how long and how often the minted token may be redeemed."
      },
      "PresignedUrlResponse": {
        "type": "object",
        "properties": {
          "presignedUrl": {
            "type": "string",
            "description": "The opaque presigned token. Redeem it at `GET /api/Files/1.0/presigned/{presignedUrl}/content`.",
            "nullable": true,
            "example": "9f3c1d7e-4b2a-4c8f-9a10-2d6e5b7c8a91"
          }
        },
        "additionalProperties": false,
        "description": "Token minted by a presigned-download request."
      },
      "ProblemDetails": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "nullable": true
          },
          "title": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "detail": {
            "type": "string",
            "nullable": true
          },
          "instance": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": {}
      },
      "RangeInfo": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Identifier of this chunk within the upload session.",
            "nullable": true,
            "example": "a1b2c3d4e5f60718293a4b5c"
          },
          "startWriteDateTime": {
            "type": "string",
            "description": "UTC time the chunk began being written to storage.",
            "format": "date-time",
            "nullable": true,
            "example": "2026-08-21T09:14:37Z"
          },
          "completeWriteDateTime": {
            "type": "string",
            "description": "UTC time the chunk finished being written. Null while the write is still in flight.",
            "format": "date-time",
            "nullable": true,
            "example": "2026-08-21T09:14:39Z"
          },
          "seqNumber": {
            "type": "integer",
            "description": "Zero-based position of this chunk in the file.",
            "format": "int32",
            "example": 4
          },
          "attempt": {
            "type": "integer",
            "description": "How many times this chunk has been uploaded, counting retries.",
            "format": "int32",
            "example": 1
          },
          "size": {
            "type": "integer",
            "description": "Size of the chunk in bytes.",
            "format": "int64",
            "example": 5242880
          },
          "hash": {
            "type": "string",
            "description": "Checksum of the chunk bytes, used to verify the write.",
            "nullable": true,
            "example": "d41d8cd98f00b204e9800998ecf8427e"
          },
          "hashType": {
            "type": "string",
            "description": "Algorithm used to compute `Hash`.",
            "nullable": true,
            "example": "MD5"
          },
          "ver": {
            "type": "string",
            "description": "Schema version of this chunk record.",
            "default": "1.0",
            "nullable": true,
            "example": "1.1"
          }
        },
        "additionalProperties": false,
        "description": "Record of one chunk written as part of a chunked upload session."
      },
      "SingleFileRequest": {
        "type": "object",
        "properties": {
          "uploadInfo": {
            "$ref": "#/components/schemas/UploadInfo"
          },
          "hash": {
            "$ref": "#/components/schemas/HashInfo"
          },
          "contentBytes": {
            "type": "string",
            "description": "Populated from the binary part; not sent in the JSON metadata.",
            "format": "byte",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Metadata part of a single-file upload."
      },
      "StatusInfo": {
        "type": "object",
        "properties": {
          "transferId": {
            "type": "string",
            "description": "Identifier of the upload session this status describes.",
            "nullable": true,
            "example": "7c1f2a44-08d5-4d1e-9a3b-51f0c2e9de77"
          },
          "fileName": {
            "type": "string",
            "description": "Name of the file being uploaded.",
            "nullable": true,
            "example": "invoices-2026-08-21.csv"
          },
          "fileSizeBytes": {
            "type": "integer",
            "description": "Total declared size of the file in bytes.",
            "format": "int64",
            "example": 10485760
          },
          "committedRangeInfos": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RangeInfo"
            },
            "description": "The chunks committed so far, in sequence order. Resume an interrupted upload by sending the first chunk not listed here.",
            "nullable": true
          },
          "lastChunkSizeBytes": {
            "type": "integer",
            "description": "Size in bytes of the most recently committed chunk.",
            "format": "int64",
            "example": 5242880
          },
          "dateStartedUTC": {
            "type": "string",
            "description": "UTC time the upload session was created.",
            "format": "date-time",
            "example": "2026-08-21T09:14:30Z"
          },
          "dateCompletedUTC": {
            "type": "string",
            "description": "UTC time the session was committed. Null while the upload is still open.",
            "format": "date-time",
            "nullable": true,
            "example": "2026-08-21T09:16:02Z"
          }
        },
        "additionalProperties": false,
        "description": "Progress of a chunked upload session: which chunks have been committed so far, and when the session started and (if it has) completed."
      },
      "UploadInfo": {
        "type": "object",
        "properties": {
          "endpointPath": {
            "type": "string",
            "description": "Flow endpoint path the file is being uploaded to, in `/{customerCode}/{flow}/{flowEndpoint}` form.",
            "nullable": true,
            "example": "/acme/invoices-inbound/partner-drop"
          },
          "attributes": {
            "$ref": "#/components/schemas/MetaInfo"
          }
        },
        "additionalProperties": false,
        "description": "Target flow endpoint and file attributes for an upload."
      },
      "UploadPreFlightResponse": {
        "type": "object",
        "properties": {
          "uploadMaxChunkSize": {
            "type": "integer",
            "description": "Largest number of bytes that may be sent in one request. Files at or below this size can go through the single-file upload; larger files must use a chunked upload session.",
            "format": "int64",
            "example": 52428800
          },
          "uploadSingleFileUrl": {
            "type": "string",
            "description": "Relative URL of the single-file upload endpoint.",
            "nullable": true,
            "example": "api/Files/1.0/Content/"
          },
          "uploadChunkedFileUrl": {
            "type": "string",
            "description": "Relative URL used to start a chunked upload session.",
            "nullable": true,
            "example": "api/Files/1.0/Upload_Sessions/"
          }
        },
        "additionalProperties": false,
        "description": "Upload limits and entry-point URLs returned by the upload pre-flight call."
      }
    },
    "securitySchemes": {
      "ApiKey": {
        "type": "apiKey",
        "description": "An MFT API key, sent in the ApiKey header. Create the key in the MFT portal and grant it access to the Content API.",
        "name": "ApiKey",
        "in": "header"
      },
      "OAuth2": {
        "type": "oauth2",
        "description": "OAuth 2.0 client credentials. Exchange your client id and secret at /oauth/token on the same regional host for an access token.",
        "flows": {
          "clientCredentials": {
            "tokenUrl": "https://us-api.mft.boomi.com/oauth/token",
            "scopes": {
              "publicAPI-read": "Access the MFT public APIs."
            }
          }
        }
      },
      "BearerAuth": {
        "type": "http",
        "description": "A JWT access token issued by the MFT portal sign-in endpoint.",
        "scheme": "bearer",
        "bearerFormat": "JWT"
      }
    }
  },
  "tags": [
    {
      "name": "Download",
      "description": "Retrieval of file content. Files can be streamed directly by an authenticated caller, or\r\nexposed to an external recipient through a short-lived presigned token that carries its own\r\nauthorization. Both paths support HTTP range requests for partial and resumable downloads."
    },
    {
      "name": "FileList",
      "description": "Discovery of the files staged against a flow endpoint. Returns a filtered, paged view of the\r\nfile metadata a caller's tenant owns, so a client can decide what to download before\r\nfetching any content."
    },
    {
      "name": "HealthCheck",
      "description": "Liveness probing. A single unauthenticated endpoint that reports whether the Content API\r\nprocess is up and serving requests."
    },
    {
      "name": "Upload",
      "description": "Delivery of file content into a flow endpoint. Small files go in a single request; larger\r\nfiles use a chunked upload session that can be resumed after an interruption. Call the\r\npre-flight (OPTIONS) operation first to learn the maximum chunk size and pick the right path."
    }
  ]
}