---
title: "Attach a criterion to a moments collection"
method: POST
path: "/collections/{collection_id}/moment-criteria"
tags: ["Collections"]
---

# Attach a criterion to a moments collection

`POST /collections/{collection_id}/moment-criteria`

## Request

- Base URL: `https://api.cloudglue.dev/v1`
- URL: `https://api.cloudglue.dev/v1/collections/{collection_id}/moment-criteria`
- Auth: HTTP bearer

Adds a criterion attachment and backfills existing members. The attach response charges nothing (cost header 0); per-file runs charge as they execute, and a matching prior run satisfies a pair at no extra execution.

## Path parameters

- `collection_id` string, uuid, required

## Request body

- NewMomentCriterionAttachment
  - `criterion` MomentCriterion, required: An inline criterion: rubric instructions plus typed output declarations. Snapshotted and hashed onto the run.
    - `name` string, required
    - `instructions` string, required: The complete rubric, including any seed lists and worked examples.
    - `moment_schema` MomentSchemaDefinition: A validated JSON Schema subset (the moment schema dialect): a root object of string/number/integer/boolean/array-of-those fields, optional enums, one nesting level, per-field descriptions. Rejected shapes get a field-addressable 400 with a stable code.
    - `finding_schema` MomentSchemaDefinition: A validated JSON Schema subset (the moment schema dialect): a root object of string/number/integer/boolean/array-of-those fields, optional enums, one nesting level, per-field descriptions. Rejected shapes get a field-addressable 400 with a stable code.
    - `anchors` object: Named intra-moment timestamps. A non-required anchor that does not exist is omitted from the moment - never null.
    - `scoring` object: The rubric's single canonical score: what rank-ordered reads sort by and what min_score filters on. Exactly one scoring key per criterion.
      - `key` string, required
      - `min` number, required
      - `max` number, required
      - `higher_is_better` boolean
      - `description` string
  - `signals_required` string[]
  - `boundary_policy` 'sentence' | 'tight' | 'loose'
  - `speaker_filter` object
    - `include` string[]
    - `exclude` string[]
    - `match` 'any' | 'all'
  - `min_duration_seconds` number
  - `max_duration_seconds` number

## Response `201`

The attachment, backfill pending.

- MomentCriterionAttachment
  - `attachment_id` string, uuid, required
  - `criterion_name` string, required
  - `criterion_hash` string, required
  - `criterion` MomentCriterion: An inline criterion: rubric instructions plus typed output declarations. Snapshotted and hashed onto the run.
    - `name` string, required
    - `instructions` string, required: The complete rubric, including any seed lists and worked examples.
    - `moment_schema` MomentSchemaDefinition: A validated JSON Schema subset (the moment schema dialect): a root object of string/number/integer/boolean/array-of-those fields, optional enums, one nesting level, per-field descriptions. Rejected shapes get a field-addressable 400 with a stable code.
    - `finding_schema` MomentSchemaDefinition: A validated JSON Schema subset (the moment schema dialect): a root object of string/number/integer/boolean/array-of-those fields, optional enums, one nesting level, per-field descriptions. Rejected shapes get a field-addressable 400 with a stable code.
    - `anchors` object: Named intra-moment timestamps. A non-required anchor that does not exist is omitted from the moment - never null.
    - `scoring` object: The rubric's single canonical score: what rank-ordered reads sort by and what min_score filters on. Exactly one scoring key per criterion.
      - `key` string, required
      - `min` number, required
      - `max` number, required
      - `higher_is_better` boolean
      - `description` string
  - `options` object: The per-attachment run knobs, as supplied on NewMomentCriterionAttachment.
    - `signals_required` string[]
    - `boundary_policy` 'sentence' | 'tight' | 'loose'
    - `speaker_filter` object
    - `min_duration_seconds` number
    - `max_duration_seconds` number
  - `backfill_status` 'pending' | 'processing' | 'completed' | 'completed_with_failures', required
  - `files_total` integer
  - `files_completed` integer
  - `files_failed` integer
  - `created_at` integer: Unix timestamp in milliseconds

## Other responses

- `400`: Invalid criterion, or not a moments collection
- `402`: Balance cannot cover the backfill precheck
- `404`: Collection not found
- `500`: Internal server error

## Changes

- **2026-10-30** `23d3f240819f`: 4 info
  - added the optional property `code` to the response with the `400` status
  - added the optional property `code` to the response with the `402` status
  - added the optional property `code` to the response with the `404` status
  - added the optional property `code` to the response with the `500` status
- **2026-08-22** `d2a5205fc779`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/cloudglue/apis/cloudglue-api/changes/collections/:collection_id/moment-criteria/post.md)

---

[API](https://skmtc.dev/cloudglue/apis/cloudglue-api.md) - [All operations](https://skmtc.dev/cloudglue/apis/cloudglue-api/llms.txt) - [OpenAPI document](https://skmtc.dev/cloudglue/apis/cloudglue-api/revisions/23d3f240819f?raw)
