---
title: "Apply Manifest"
method: POST
path: "/v1/manifest/apply"
tags: ["Manifest"]
---

# Apply Manifest

`POST /v1/manifest/apply`

Apply a YAML manifest to create resources.

Creates all resources defined in the manifest file in dependency order.
Fails if any resource already exists (create-only mode).
Performs automatic rollback if any resource creation fails.

**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
- Dry run mode validates the manifest 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 }
```

## Query parameters

- `dry_run` boolean — Validate only, don't create resources

## Response `201`

Successful Response

- ApplyResult — Result of applying a manifest.
  - `success` boolean, required — Whether all resources were created successfully
  - `resources` ResourceResult[] — Results for each resource
    - `resource_type` string, required — Type of resource (namespace, bucket, etc.)
    - `name` string, required — Resource name from manifest
    - `resource_id` string, nullable — Created resource ID
    - `status` 'created' | 'skipped' | 'failed', required — Status of a resource creation attempt.
    - `error` string, nullable — Error message if failed
  - `created_count` integer — Number of resources created
  - `failed_count` integer — Number of resources that failed
  - `skipped_count` integer — Number of resources skipped
  - `errors` string[] — Error messages
  - `warnings` string[] — Non-fatal issues found while PARSING the manifest, chiefly keys the parser had to drop. MG-1435: 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` boolean — Whether a rollback was ATTEMPTED after a failure. MG-1440: 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.
  - `rollback_orphans` string[] — 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. MG-1440: 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` boolean — Whether this was a dry run (no changes made)

## Other responses

- `400` — Bad Request
- `401` — Unauthorized
- `403` — Forbidden
- `404` — Not Found
- `422` — Validation Error
- `500` — Internal Server Error

---

[API](https://skmtc.net/mixpeek/apis/mixpeek-api.md) · [All operations](https://skmtc.net/mixpeek/apis/mixpeek-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/mixpeek/mixpeek-api/revisions/40af5e67ba94/schema)
