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

# Apply Manifest

> Apply a YAML manifest to create resources.

Creates all resources defined in the manifest file in dependency order.

**Modes:**
- `create_only` (default) — fails if any resource already exists.
- `create_missing` — creates what is missing, leaves what exists alone, and resolves
  manifest references against the resources ALREADY in the namespace. This is what makes
  "here is a namespace with buckets, add these collections over them" work. Under
  `create_only` a reference to an undeclared-but-existing bucket is a validation error,
  because the manifest is treated as a closed world.

**Plan first:** before creating anything, apply runs the same checks as
`POST /v1/manifest/validate`. Any error refuses the whole manifest with
`success: false`, every resource `skipped`, and each error naming the
resource, the field and the fix. Nothing is created. A namespace budget above
the organization's bound is set to the bound and reported as a warning.

**Features:**
- Topological sorting ensures resources are created in correct dependency order
- Secret references (`${{ secrets.NAME }}`) are resolved from organization secrets
- Atomic operation: rolls back all created resources if any creation fails, and
  an apply whose process is stopped part way is rolled back when the API starts again
- Dry run returns the plan without making changes

**Example:**
```bash
curl -X POST /v1/manifest/apply \
  -H "Authorization: Bearer $API_KEY" \
  -H "X-Namespace: ns_xxx" \
  -F "manifest_file=@mixpeek.yaml"
```

**Example manifest:**
```yaml
version: "1.0"
metadata:
  name: "my-environment"

namespaces:
  - name: video_search
    feature_extractors:
      - name: multimodal_extractor
        version: v1

buckets:
  - name: raw_videos
    namespace: video_search
    schema:
      properties:
        video: { type: video }
```



## OpenAPI

````yaml post /v1/manifest/apply
openapi: 3.1.0
info:
  title: Mixpeek API
  description: >-
    This is the Mixpeek API, providing access to various endpoints for data
    processing and retrieval.
  termsOfService: https://mixpeek.com/terms
  contact:
    name: Mixpeek Support
    url: https://mixpeek.com/contact
    email: info@mixpeek.com
  version: '0.82'
servers:
  - url: https://api.mixpeek.com
    description: Production
security:
  - BearerAuth: []
paths:
  /v1/manifest/apply:
    post:
      tags:
        - Manifest
      summary: Apply Manifest
      description: >-
        Apply a YAML manifest to create resources.


        Creates all resources defined in the manifest file in dependency order.


        **Modes:**

        - `create_only` (default) — fails if any resource already exists.

        - `create_missing` — creates what is missing, leaves what exists alone,
        and resolves
          manifest references against the resources ALREADY in the namespace. This is what makes
          "here is a namespace with buckets, add these collections over them" work. Under
          `create_only` a reference to an undeclared-but-existing bucket is a validation error,
          because the manifest is treated as a closed world.

        **Plan first:** before creating anything, apply runs the same checks as

        `POST /v1/manifest/validate`. Any error refuses the whole manifest with

        `success: false`, every resource `skipped`, and each error naming the

        resource, the field and the fix. Nothing is created. A namespace budget
        above

        the organization's bound is set to the bound and reported as a warning.


        **Features:**

        - Topological sorting ensures resources are created in correct
        dependency order

        - Secret references (`${{ secrets.NAME }}`) are resolved from
        organization secrets

        - Atomic operation: rolls back all created resources if any creation
        fails, and
          an apply whose process is stopped part way is rolled back when the API starts again
        - Dry run returns the plan without making changes


        **Example:**

        ```bash

        curl -X POST /v1/manifest/apply \
          -H "Authorization: Bearer $API_KEY" \
          -H "X-Namespace: ns_xxx" \
          -F "manifest_file=@mixpeek.yaml"
        ```


        **Example manifest:**

        ```yaml

        version: "1.0"

        metadata:
          name: "my-environment"

        namespaces:
          - name: video_search
            feature_extractors:
              - name: multimodal_extractor
                version: v1

        buckets:
          - name: raw_videos
            namespace: video_search
            schema:
              properties:
                video: { type: video }
        ```
      operationId: apply_manifest_v1_manifest_apply_post
      parameters:
        - name: dry_run
          in: query
          required: false
          schema:
            type: boolean
            description: >-
              Run the plan only: the same checks as POST /v1/manifest/validate,
              returned as errors and warnings, with nothing created
            default: false
            title: Dry Run
          description: >-
            Run the plan only: the same checks as POST /v1/manifest/validate,
            returned as errors and warnings, with nothing created
        - name: deadline_seconds
          in: query
          required: false
          schema:
            anyOf:
              - type: number
                maximum: 1800
                minimum: 1
              - type: 'null'
            description: >-
              Wait up to this many seconds after the resources are created for
              every Ray Serve app a declared collection needs to be RUNNING (the
              apps listed in `readiness`). Past the deadline the result has
              success false and an error naming the deadline and each app not
              RUNNING; the resources stay in place. Omit to return as soon as
              the resources exist.
            title: Deadline Seconds
          description: >-
            Wait up to this many seconds after the resources are created for
            every Ray Serve app a declared collection needs to be RUNNING (the
            apps listed in `readiness`). Past the deadline the result has
            success false and an error naming the deadline and each app not
            RUNNING; the resources stay in place. Omit to return as soon as the
            resources exist.
        - name: mode
          in: query
          required: false
          schema:
            $ref: '#/components/schemas/ApplyMode'
            description: >-
              create_only (default): fail if any resource already exists.
              create_missing: create what is missing and leave what exists
              alone, which is what lets a manifest be applied to an EXISTING
              namespace. create_missing does not UPDATE anything — a resource
              that exists but differs from the manifest is reported as `exists`
              and left untouched. upsert: create what is missing AND patch what
              exists but differs, so re-applying a manifest brings the running
              resources back to what it declares. Each resource is patched only
              through its own update surface, so a field that surface does not
              accept, or refuses the value of, is reported in `refused` with the
              resource and the field named, and the rest of the manifest still
              applies. Explicit on purpose: this is the only mode that CHANGES
              resources that already exist.
            default: create_only
          description: >-
            create_only (default): fail if any resource already exists.
            create_missing: create what is missing and leave what exists alone,
            which is what lets a manifest be applied to an EXISTING namespace.
            create_missing does not UPDATE anything — a resource that exists but
            differs from the manifest is reported as `exists` and left
            untouched. upsert: create what is missing AND patch what exists but
            differs, so re-applying a manifest brings the running resources back
            to what it declares. Each resource is patched only through its own
            update surface, so a field that surface does not accept, or refuses
            the value of, is reported in `refused` with the resource and the
            field named, and the rest of the manifest still applies. Explicit on
            purpose: this is the only mode that CHANGES resources that already
            exist.
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/Body_apply_manifest_v1_manifest_apply_post'
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApplyResult'
        '400':
          description: Bad Request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not Found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      security:
        - BearerAuth: []
components:
  schemas:
    ApplyMode:
      type: string
      enum:
        - create_only
        - create_missing
        - upsert
      title: ApplyMode
      description: Mode for applying manifests.
    Body_apply_manifest_v1_manifest_apply_post:
      properties:
        manifest_file:
          type: string
          contentMediaType: application/octet-stream
          title: Manifest File
          description: YAML manifest file
        parameters:
          anyOf:
            - type: string
            - type: 'null'
          title: Parameters
          description: >-
            JSON object of values for the manifest's declared parameters, e.g.
            {"camera_url": "rtsp://host/stream", "polling_seconds": 300}. Each
            value must match its declared type. Omit when the manifest declares
            none.
      type: object
      required:
        - manifest_file
      title: Body_apply_manifest_v1_manifest_apply_post
    ApplyResult:
      properties:
        success:
          type: boolean
          title: Success
          description: Whether all resources were created successfully
        resources:
          items:
            $ref: '#/components/schemas/ResourceResult'
          type: array
          title: Resources
          description: Results for each resource
        created_count:
          type: integer
          title: Created Count
          description: Number of resources created
          default: 0
        failed_count:
          type: integer
          title: Failed Count
          description: Number of resources that failed
          default: 0
        skipped_count:
          type: integer
          title: Skipped Count
          description: Number of resources skipped
          default: 0
        updated_count:
          type: integer
          title: Updated Count
          description: >-
            Resources that existed, differed, and were PATCHED to match. Only
            ever non-zero under `upsert`. Counted separately because without it
            an upsert that changed five running resources reports created 0,
            failed 0, skipped 0, a summary that reads as nothing having
            happened.
          default: 0
        errors:
          items:
            type: string
          type: array
          title: Errors
          description: Error messages
        warnings:
          items:
            type: string
          type: array
          title: Warnings
          description: >-
            Non-fatal issues found while PARSING the manifest, chiefly keys the
            parser had to drop. the parser already detects these and /validate
            and /lint already surface them, but /apply computed them and threw
            them away — so anyone applying without validating first got a 201
            and no hint that part of their manifest was ignored. A
            collection-level `field_passthrough:` is the case that cost a
            customer POC: detected, described, discarded.
        rollback_performed:
          type: boolean
          title: Rollback Performed
          description: >-
            Whether a rollback was ATTEMPTED after a failure. this used to read
            as 'the namespace was returned to its prior state', which it does
            not mean — rollback deletes only namespaces and buckets today, so
            any other resource created before the failure SURVIVES. Read
            `rollback_orphans` to find out what is still there.
          default: false
        rollback_orphans:
          items:
            type: string
          type: array
          title: Rollback Orphans
          description: >-
            Resources created before the failure that rollback did NOT delete,
            as '<type>/<id>'. Non-empty means the namespace is in a PARTIAL
            state and a straight retry will hit AlreadyExists on these.
            previously these were silently skipped while rollback_performed=true
            claimed otherwise, which is the state that had to be unpicked by
            hand on the Radio-Canada POC.
        dry_run:
          type: boolean
          title: Dry Run
          description: Whether this was a dry run (no changes made)
          default: false
        task_id:
          anyOf:
            - type: string
            - type: 'null'
          title: Task Id
          description: >-
            The apply's task: GET /v1/tasks/{task_id} returns every resource of
            the plan with its states in order (planned, creating, created,
            exists, updated or failed with the finding; for a collection,
            warming or ready), each with the time it was reached. Absent on a
            dry run
        readiness:
          items:
            $ref: '#/components/schemas/CollectionReadiness'
          type: array
          title: Readiness
          description: >-
            For each collection the manifest declares whose extractor needs Ray
            Serve applications for real-time inference: whether each one is
            served, read once from the live Serve list after apply.
            `realtime_available` true means every app is RUNNING. An app scaled
            to zero replicas is still RUNNING; its first call answers 503 with
            Retry-After (code model_warming) while it warms, so retry after that
            many seconds. Empty for collections whose extractor needs no Serve
            app.
      type: object
      required:
        - success
      title: ApplyResult
      description: Result of applying a manifest.
      examples:
        - created_count: 2
          dry_run: false
          errors: []
          failed_count: 0
          resources:
            - name: video_search
              resource_id: ns_abc123
              resource_type: namespace
              status: created
            - name: raw_videos
              resource_id: bkt_xyz789
              resource_type: bucket
              status: created
          rollback_performed: false
          skipped_count: 0
          success: true
    ErrorResponse:
      properties:
        success:
          type: boolean
          title: Success
          description: Always false for error responses
          default: false
        status:
          type: integer
          title: Status
          description: HTTP status code for this error
        error:
          $ref: '#/components/schemas/ErrorDetail'
          description: Error details payload
      type: object
      required:
        - status
        - error
      title: ErrorResponse
      description: Error response model.
      examples:
        - error:
            details:
              id: ns_123
              resource: namespace
            message: Namespace not found
            type: NotFoundError
          status: 404
          success: false
    HTTPValidationError:
      properties:
        detail:
          items:
            $ref: '#/components/schemas/ValidationError'
          type: array
          title: Detail
      type: object
      title: HTTPValidationError
    ResourceResult:
      properties:
        resource_type:
          type: string
          title: Resource Type
          description: Type of resource (namespace, bucket, etc.)
        name:
          type: string
          title: Name
          description: Resource name from manifest
        resource_id:
          anyOf:
            - type: string
            - type: 'null'
          title: Resource Id
          description: Created resource ID
        status:
          $ref: '#/components/schemas/ResourceResultStatus'
          description: >-
            What apply did to this resource. `created` and `skipped` are what
            they sound like. `exists` means it was already what the manifest
            declares. `drifted` means it differs and still does. `updated` means
            apply patched it. READ `updated` WITH `refused`: a resource can be
            `updated` AND carry refused fields, because apply patches what the
            update surface accepts and reports the rest. `updated` on its own
            does not mean every declared field was applied, and a caller that
            treats it as reconciled will report a partly-applied manifest as
            complete.
        error:
          anyOf:
            - type: string
            - type: 'null'
          title: Error
          description: Error message if failed
        drift:
          anyOf:
            - items:
                type: string
              type: array
            - type: 'null'
          title: Drift
          description: >-
            Fields the manifest DECLARES that differ from the live resource.
            Present when status is `drifted`, and ALSO on an `updated` resource,
            where it is HISTORICAL: the record of what apply changed, not a
            difference that is still there. A caller that renders any non-empty
            value as 'differs' will announce the opposite of what happened on
            every patched row. Named rather than counted: 'collection c1
            differs: schedule' is actionable, 'exists' is not. Only fields the
            manifest explicitly set are compared — an omitted field asserts
            nothing, and treating an omission as drift would make every apply
            drift on server-set defaults.
          examples:
            - - schedule
              - feature_extractor
        refused:
          anyOf:
            - items:
                type: string
              type: array
            - type: 'null'
          title: Refused
          description: >-
            Fields the manifest declares, and that DIFFER, which apply would not
            change. Present under `upsert` when the resource's own update
            surface does not accept a field or refuses the value. A refusal is
            reported per field rather than as a failed apply: the rest of the
            manifest still applies, and the caller learns exactly which resource
            and which field to take up by hand. A bucket's schema is the
            standing example — it is patchable through the API and a destructive
            change is refused, so upsert does not route around that guard.
          examples:
            - - budget_limits
        drift_not_compared:
          anyOf:
            - items:
                type: string
              type: array
            - type: 'null'
          title: Drift Not Compared
          description: >-
            Fields the manifest declares that could NOT be compared, because the
            live resource has no corresponding key. Reported rather than
            dropped: a field silently excluded from the comparison is
            indistinguishable from one that matched, and that is the exact
            ambiguity `drifted` exists to remove.
      type: object
      required:
        - resource_type
        - name
        - status
      title: ResourceResult
      description: Result of applying a single resource.
      examples:
        - name: video_search
          resource_id: ns_abc123
          resource_type: namespace
          status: created
    CollectionReadiness:
      properties:
        collection:
          type: string
          title: Collection
          description: Collection name from the manifest
        feature_extractor:
          type: string
          title: Feature Extractor
          description: Registry extractor id the collection runs, e.g. text_extractor_v1
        realtime_available:
          anyOf:
            - type: boolean
            - type: 'null'
          title: Realtime Available
          description: >-
            true when every Serve app below is RUNNING, false when one is absent
            or not RUNNING, null when the live Serve list could not be read
        serve_apps:
          items:
            $ref: '#/components/schemas/ServeAppStatus'
          type: array
          title: Serve Apps
          description: Each Ray Serve application the extractor needs, with its status
      type: object
      required:
        - collection
        - feature_extractor
      title: CollectionReadiness
      description: Whether one collection's real-time inference is served after apply.
    ErrorDetail:
      properties:
        message:
          type: string
          title: Message
          description: Human-readable error message
        type:
          type: string
          title: Type
          description: Stable error type identifier (machine-readable)
        code:
          anyOf:
            - type: string
            - type: 'null'
          title: Code
          description: >-
            Fine-grained error code for programmatic handling (e.g.,
            namespace_name_taken, feature_extractor_not_found). Present only
            when consumers may need to branch on a specific error condition.
        details:
          anyOf:
            - additionalProperties: true
              type: object
            - type: 'null'
          title: Details
          description: >-
            Optional structured details to help debugging (validation errors,
            IDs, etc.)
      type: object
      required:
        - message
        - type
      title: ErrorDetail
      description: Error detail model.
    ValidationError:
      properties:
        loc:
          items:
            anyOf:
              - type: string
              - type: integer
          type: array
          title: Location
        msg:
          type: string
          title: Message
        type:
          type: string
          title: Error Type
        input:
          title: Input
        ctx:
          type: object
          title: Context
      type: object
      required:
        - loc
        - msg
        - type
      title: ValidationError
    ResourceResultStatus:
      type: string
      enum:
        - created
        - skipped
        - failed
        - exists
        - drifted
        - updated
      title: ResourceResultStatus
      description: Status of a resource creation attempt.
    ServeAppStatus:
      properties:
        name:
          type: string
          title: Name
          description: Ray Serve application name, as the engine deploys it.
        status:
          type: string
          title: Status
          description: >-
            Live status of that application on the deployment serving this
            request. A Ray Serve status such as 'RUNNING', 'DEPLOYING' or
            'UNHEALTHY'; 'absent' when the deployment does not serve it;
            'unconfigured' when it runs but the deployment lacks the model
            provider's key or credentials; 'unknown' when the live list could
            not be read.
      type: object
      required:
        - name
        - status
      title: ServeAppStatus
      description: One Ray Serve application an extractor needs, with its live status.
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      description: >-
        Mixpeek API key, sent as `Authorization: Bearer mxp_sk_...`. Create one
        in Studio under Settings → API Keys, or with an admin key via `POST
        /v1/organizations/users/{user_email}/api-keys`. A missing, malformed,
        unknown, revoked, inactive or expired key returns 401; a key without the
        permission, scope or plan an operation needs returns 403.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.