---
updatedAt: 2026-08-21T16:12:58.000Z
agentTools:
  projectIndex: https://docs.rackspace.com/llms.txt
---

# Upload a file to a Model

Uploads a single file to the Model's storage directory in SeaweedFS.
The front proxy routes this request based on the `x-upload-target` header.

To upload an entire model directory, call this endpoint once per file,
preserving the relative path in the `{filePath}` parameter.

After all files are uploaded, the Model controller verifies file presence,
computes total size, and (if configured) checks MD5 integrity, then sets
`status.ready = true`.


# OpenAPI definition

```json
{
  "openapi": "3.0.3",
  "info": {
    "title": "RackAI API",
    "description": "REST API for RackAI Custom Resources managed by the `rackai.rackspace.com` operator.\n\nMost requests are routed through the Kubernetes API server and authenticated\nwith a bearer token (service-account token or kubeconfig credential).\n\nOrganization management is the exception: tenants have no RBAC to edit the\n`Organization` custom resource directly, so those operations are served by the\norganizer service behind the Front Proxy and authenticated with an Auth0 OIDC\ntoken. See the **Organization** tag.\n\n**Base path:** `/apis/rackai.rackspace.com/v1alpha1`\n",
    "version": "v1alpha1",
    "contact": {
      "name": "Rackspace Spot Platform Engineering"
    }
  },
  "servers": [
    {
      "url": "https://{fqdn}/apis/rackai.rackspace.com/v1alpha1",
      "description": "API Server",
      "variables": {
        "fqdn": {
          "default": "localhost:6443",
          "description": "Fully-qualified domain name (and optional port) of the Front Proxy in front of the Kubernetes API server"
        }
      }
    }
  ],
  "security": [
    {
      "BearerToken": []
    }
  ],
  "tags": [
    {
      "name": "Model",
      "description": "Model represents a stored or remotely-sourced AI model artifact within a namespace.\nIt carries descriptive metadata about the model (family, type, precision,\nquantization, parameter count, etc.) and acts as the central identity that\nModelClass, LoRAAdapter, and FineTuningJob reference.\n\nrackai.rackspace.com/uri-hash label with the following rules:\n  - Controller service account (e.g. rackai-controller-manager) MAY add,\n    update, or remove the label. The controller stamps it when cache=true is\n    first reconciled and removes it during the cache=true→false cleanup path.\n  - All other principals (end-users, CI, kubectl) MUST NOT modify or delete\n    the label once it has been stamped. Reject the request with a clear\n    message explaining that the label is managed by the controller.\n\nA webhook is necessary here because CEL transition rules apply to ALL\nmutations regardless of who makes them, so CEL cannot distinguish the\ncontroller from a user and would block legitimate controller cleanup."
    }
  ],
  "paths": {
    "/namespaces/{namespace}/models/{name}/{filePath}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/namespace"
        },
        {
          "$ref": "#/components/parameters/name"
        },
        {
          "$ref": "#/components/parameters/filePath"
        }
      ],
      "post": {
        "tags": [
          "Model"
        ],
        "summary": "Upload a file to a Model",
        "operationId": "uploadNamespacedModelFile",
        "description": "Uploads a single file to the Model's storage directory in SeaweedFS.\nThe front proxy routes this request based on the `x-upload-target` header.\n\nTo upload an entire model directory, call this endpoint once per file,\npreserving the relative path in the `{filePath}` parameter.\n\nAfter all files are uploaded, the Model controller verifies file presence,\ncomputes total size, and (if configured) checks MD5 integrity, then sets\n`status.ready = true`.\n",
        "parameters": [
          {
            "name": "x-upload-target",
            "in": "header",
            "required": true,
            "description": "Must be set to `models` for model file uploads.",
            "schema": {
              "type": "string",
              "enum": [
                "models"
              ]
            }
          },
          {
            "$ref": "#/components/parameters/contentMD5"
          }
        ],
        "requestBody": {
          "$ref": "#/components/requestBodies/FileUpload"
        },
        "responses": {
          "200": {
            "description": "File uploaded successfully."
          },
          "201": {
            "description": "File created successfully."
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "BearerToken": {
        "type": "http",
        "scheme": "bearer",
        "description": "Bearer token for the Kubernetes-extension API surface\n(`/apis/rackai.rackspace.com/v1alpha1/...`). Pass as\n`Authorization: Bearer <token>`.\n\nNote: for paths reached through the Front Proxy, the credential\npresented is an Auth0-issued OIDC bearer that the proxy validates\nand forwards to the upstream apiserver (which validates the same\ntoken via OIDC). A Kubernetes service-account token or kubeconfig\ncredential is what's typically used when hitting the apiserver\ndirectly (e.g. from inside the cluster).\n"
      }
    },
    "parameters": {
      "namespace": {
        "name": "namespace",
        "in": "path",
        "required": true,
        "description": "Kubernetes namespace of the resource.",
        "schema": {
          "type": "string"
        }
      },
      "name": {
        "name": "name",
        "in": "path",
        "required": true,
        "description": "Name of the resource.",
        "schema": {
          "type": "string"
        }
      },
      "filePath": {
        "name": "filePath",
        "in": "path",
        "required": true,
        "description": "Remote file path within the artifact's storage directory. When uploading\na directory tree, this preserves the relative path structure (e.g.\n`subdir/data.parquet`). May contain forward slashes for nested paths;\nthe Envoy front proxy handles the full path via regex routing.\n",
        "schema": {
          "type": "string"
        }
      },
      "contentMD5": {
        "name": "Content-MD5",
        "in": "header",
        "required": false,
        "description": "Hex-encoded MD5 digest of the file being uploaded. When provided, the\nserver verifies the uploaded file's integrity against this value during\nupload. For Model and Dataset uploads, corresponds to the\n`spec.integrity.md5` field on the resource.\n",
        "schema": {
          "type": "string"
        },
        "example": "d0e972641a9148f265e5ec218f1fc3cc"
      }
    },
    "responses": {
      "Unauthorized": {
        "description": "Unauthorized — no or invalid bearer token provided."
      },
      "Forbidden": {
        "description": "Forbidden — the authenticated principal lacks permission."
      },
      "NotFound": {
        "description": "Not Found — the resource does not exist."
      }
    },
    "requestBodies": {
      "FileUpload": {
        "required": true,
        "description": "Single-file upload as multipart/form-data. The `file` part carries the\nraw file content.\n",
        "content": {
          "multipart/form-data": {
            "schema": {
              "type": "object",
              "required": [
                "file"
              ],
              "properties": {
                "file": {
                  "type": "string",
                  "format": "binary",
                  "description": "The file content to upload."
                }
              }
            }
          }
        }
      }
    }
  }
}
```