generated: '2026-08-27' method: derived source: openapi/sift-stack-openapi.json (787 component schemas, 343 operations); entity vocabulary cross-checked against https://docs.siftstack.com/.well-known/agent-skills/sift/skill.md and https://docs.siftstack.com/documentation/reference/ name: Sift data model note: 'Sift''s core model is small and stable: an ASSET is the system under test, a CHANNEL is one signal from it, a RUN is a captured session, and everything else hangs off those three. RULE (a CEL expression) evaluated against a RUN yields a REPORT; a firing rule opens an ANNOTATION; a CAMPAIGN groups reports across runs; a FAMILY is a named set of known-good runs used as a comparison baseline; a CALCULATED CHANNEL is a derived signal. Relationships below are read from id-reference fields and $ref arrays in the spec, so they are structural rather than declared — the spec has no foreign-key vocabulary.' organization_scoping: Most top-level entities carry organizationId; the API key resolves to one organization, and organizationId is required on requests only when the user belongs to more than one. identity: server_ids: Opaque string ids, no type prefix (unlike Stripe-style prefixed ids) — an id alone does not tell a client what it points at. client_keys: Rules, Calculated Channels, Families, Campaigns and Runs additionally accept a client-supplied `client_key`, immutable after creation, and several operations resolve by it instead of by server id. entities: - entity: Asset schema: assetsv1Asset field_count: 11 required_count: 10 id_fields: - assetId - createdByUserId - modifiedByUserId - organizationId archivable: true client_key: false versioned: false - entity: Run schema: runsv2Run field_count: 20 required_count: 14 id_fields: - createdByUserId - defaultReportId - modifiedByUserId - organizationId - runId archivable: true client_key: true versioned: false - entity: Channel schema: channelsv3Channel field_count: 16 required_count: 11 id_fields: - assetId - channelId - createdByUserId - displayUnitId - modifiedByUserId - unitId archivable: false client_key: false versioned: false - entity: Rule schema: v1Rule field_count: 23 required_count: 18 id_fields: - assetId - createdByUserId - currentVersionId - modifiedByUserId - organizationId - ruleId archivable: true client_key: true versioned: true - entity: Report schema: v1Report field_count: 22 required_count: 12 id_fields: - canvasExecutionId - canvasId - canvasVersionId - createdByUserId - jobId - modifiedByUserId - organizationId - reportId - reportTemplateId - rerunFromReportId - runId archivable: true client_key: false versioned: true - entity: Annotation schema: annotationsv1Annotation field_count: 29 required_count: 14 id_fields: - annotationId - assignedToUserId - createdByConditionId - createdByRuleConditionVersionId - createdByUserId - modifiedByUserId - organizationId - reportRuleVersionId - runId archivable: true client_key: false versioned: true - entity: Campaign schema: v1Campaign field_count: 16 required_count: 3 id_fields: - campaignId - createdByUserId - createdFromCampaignId - modifiedByUserId - organizationId archivable: true client_key: true versioned: false - entity: Family schema: v1Family field_count: 10 required_count: 8 id_fields: - createdByUserId - currentVersionId - familyId - modifiedByUserId - organizationId archivable: true client_key: true versioned: true - entity: CalculatedChannel schema: v2CalculatedChannel field_count: 21 required_count: 17 id_fields: - calculatedChannelId - createdByUserId - modifiedByUserId - organizationId - versionId archivable: true client_key: true versioned: true - entity: IngestionConfig schema: ingestion_configsv2IngestionConfig field_count: 3 required_count: 2 id_fields: - assetId - ingestionConfigId archivable: false client_key: true versioned: false - entity: Webhook schema: v1Webhook field_count: 13 required_count: 11 id_fields: - createdByUserId - modifiedByUserId - organizationId - webhookId archivable: true client_key: false versioned: false - entity: Job schema: v1Job field_count: 12 required_count: 7 id_fields: - createdByUserId - jobId - modifiedByUserId - organizationId archivable: false client_key: false versioned: false - entity: DataImport schema: v2DataImport field_count: 19 required_count: 5 id_fields: - assetId - dataImportId - reportId - runId archivable: false client_key: false versioned: false - entity: User schema: v1User field_count: 3 required_count: 2 id_fields: - userId archivable: false client_key: false versioned: false - entity: Role schema: v2Role field_count: 4 required_count: 0 id_fields: - roleId archivable: false client_key: false versioned: false - entity: Policy schema: v1Policy field_count: 15 required_count: 10 id_fields: - createdByUserId - modifiedByUserId - organizationId - policyId - policyVersionId archivable: true client_key: false versioned: true - entity: Tag schema: tagsv2Tag field_count: 4 required_count: 0 id_fields: - createdByUserId - tagId archivable: false client_key: false versioned: false - entity: View schema: viewsv2View field_count: 9 required_count: 0 id_fields: - createdByUserId - modifiedByUserId - viewId archivable: false client_key: false versioned: false - entity: TestReport schema: v1TestReport field_count: 14 required_count: 7 id_fields: - runId - testReportId archivable: true client_key: false versioned: false - entity: Comment schema: v1Comment field_count: 8 required_count: 8 id_fields: - commentId - createdByUserId - resourceId archivable: false client_key: false versioned: false relationships: - from: Asset to: User type: belongs_to via: createdByUserId required: true - from: Asset to: User type: belongs_to via: modifiedByUserId required: true - from: Run to: User type: belongs_to via: createdByUserId required: true - from: Run to: User type: belongs_to via: modifiedByUserId required: true - from: Channel to: Asset type: belongs_to via: assetId required: true - from: Channel to: User type: belongs_to via: createdByUserId required: true - from: Channel to: User type: belongs_to via: modifiedByUserId required: true - from: Rule to: Asset type: belongs_to via: assetId required: true - from: Rule to: User type: belongs_to via: createdByUserId required: true - from: Rule to: User type: belongs_to via: modifiedByUserId required: true - from: Report to: Run type: belongs_to via: runId required: true - from: Report to: User type: belongs_to via: createdByUserId required: true - from: Report to: User type: belongs_to via: modifiedByUserId required: true - from: Report to: Job type: belongs_to via: jobId required: false - from: Annotation to: User type: belongs_to via: createdByUserId required: true - from: Annotation to: User type: belongs_to via: modifiedByUserId required: true - from: Annotation to: Run type: belongs_to via: runId required: false - from: Campaign to: User type: belongs_to via: createdByUserId required: false - from: Campaign to: User type: belongs_to via: modifiedByUserId required: false - from: Family to: User type: belongs_to via: createdByUserId required: true - from: Family to: User type: belongs_to via: modifiedByUserId required: true - from: CalculatedChannel to: User type: belongs_to via: createdByUserId required: true - from: CalculatedChannel to: User type: belongs_to via: modifiedByUserId required: true - from: IngestionConfig to: Asset type: belongs_to via: assetId required: true - from: Webhook to: User type: belongs_to via: createdByUserId required: true - from: Webhook to: User type: belongs_to via: modifiedByUserId required: true - from: Job to: User type: belongs_to via: createdByUserId required: true - from: Job to: User type: belongs_to via: modifiedByUserId required: true - from: DataImport to: Run type: belongs_to via: runId required: false - from: DataImport to: Report type: belongs_to via: reportId required: false - from: DataImport to: Asset type: belongs_to via: assetId required: false - from: Policy to: User type: belongs_to via: createdByUserId required: true - from: Policy to: User type: belongs_to via: modifiedByUserId required: true - from: Tag to: User type: belongs_to via: createdByUserId required: false - from: View to: User type: belongs_to via: createdByUserId required: false - from: View to: User type: belongs_to via: modifiedByUserId required: false - from: TestReport to: Run type: belongs_to via: runId required: false - from: Comment to: User type: belongs_to via: createdByUserId required: true archive_model: Entities carrying isArchived/archivedDate are soft-deleted rather than removed; see conventions/sift-stack-conventions.yml reversibility. render: null